diff --git a/.gitattributes b/.gitattributes index c1965c2162a..1f7549b5c66 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -.github/workflows/*.lock.yml linguist-generated=true merge=ours \ No newline at end of file +.github/workflows/*.lock.yml linguist-generated=true \ No newline at end of file diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index 5733f7af4c3..c143df3de5c 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -35,15 +35,15 @@ "version": "v7.0.1", "sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a" }, - "github/gh-aw-actions/setup-cli@v0.86.2": { + "github/gh-aw-actions/setup-cli@v0.87.9": { "repo": "github/gh-aw-actions/setup-cli", - "version": "v0.86.2", - "sha": "6aab9e5b5c91c615506061f09bedd81a23babe3c" + "version": "v0.87.9", + "sha": "49dc896ccb7d6d975514cfe232bcbd68cc12e2c1" }, - "github/gh-aw-actions/setup@v0.86.2": { + "github/gh-aw-actions/setup@v0.87.9": { "repo": "github/gh-aw-actions/setup", - "version": "v0.86.2", - "sha": "6aab9e5b5c91c615506061f09bedd81a23babe3c" + "version": "v0.87.9", + "sha": "49dc896ccb7d6d975514cfe232bcbd68cc12e2c1" }, "ruby/setup-ruby@v1.321.0": { "repo": "ruby/setup-ruby", @@ -72,21 +72,11 @@ "digest": "sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627", "pinned_image": "ghcr.io/github/gh-aw-firewall/squid:0.27.44@sha256:83e48bbe12c634be8c228a576832fe45f66c529ac3659db92bddbcf2eeb6d627" }, - "ghcr.io/github/gh-aw-mcpg:v0.4.9": { - "image": "ghcr.io/github/gh-aw-mcpg:v0.4.9", - "digest": "sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f", - "pinned_image": "ghcr.io/github/gh-aw-mcpg:v0.4.9@sha256:e5a1569aeaf41820fa7bdee3e94468cae448133cdbf00119ad24f5b74db1ab9f" - }, "ghcr.io/github/gh-aw-node": { "image": "ghcr.io/github/gh-aw-node", "digest": "sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748", "pinned_image": "ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748" }, - "ghcr.io/github/github-mcp-server:v1.9.0": { - "image": "ghcr.io/github/github-mcp-server:v1.9.0", - "digest": "sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e", - "pinned_image": "ghcr.io/github/github-mcp-server:v1.9.0@sha256:881b53d6f75f69bdbc1b5b10fc2f1361717c19054143b3a8529fb5c32061a50e" - }, "node:26-alpine": { "image": "node:26-alpine", "digest": "sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9", diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 10af423deb6..a3f6068c08a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -149,7 +149,7 @@ The 13 analysis/article-generating news workflows declare the Opus-class reasoni ```yaml engine: id: copilot - model: claude-opus-4.8 # Content/analysis workflows — strongest reasoning for the 23-artifact pipeline + model: claude-opus-5 # Content/analysis workflows — strongest reasoning for the 23-artifact pipeline # news-translate.md keeps: model: claude-sonnet-4.6 — faster throughput for high-volume translation fan-out # Note: engine.mcp.session-timeout was removed in the v0.71.3 era due to MCP Gateway v0.3.1 rejecting it; the v0.74.3 lock files now run MCP Gateway v0.3.9 — re-test before re-enabling. ``` diff --git a/.github/skills/agentic-workflows/SKILL.md b/.github/skills/agentic-workflows/SKILL.md index 3af44da06f2..17789fc5179 100644 --- a/.github/skills/agentic-workflows/SKILL.md +++ b/.github/skills/agentic-workflows/SKILL.md @@ -34,13 +34,16 @@ Load these files from `github/gh-aw` (they are not available locally). - `.github/aw/deployment-status.md` - `.github/aw/designer-mappings.md` - `.github/aw/designer.md` +- `.github/aw/drive-memory.md` - `.github/aw/enclaves.md` - `.github/aw/evals.md` - `.github/aw/experiments.md` - `.github/aw/github-agentic-workflows.md` - `.github/aw/github-mcp-server-pagination.md` +- `.github/aw/github-mcp-server-tools.md` - `.github/aw/github-mcp-server.md` - `.github/aw/instructions.md` +- `.github/aw/intent.md` - `.github/aw/jobs.md` - `.github/aw/linter-workflows.md` - `.github/aw/llms.md` @@ -102,5 +105,6 @@ After loading the matching workflow prompt or skill, follow it directly: - Choose workflow architecture and patterns: `.github/aw/patterns.md` - Optimize token usage and cost: `.github/aw/token-optimization.md` - Design long-running multi-agent research workflows: `.github/aw/multi-agent-research.md` +- Add skills or agent plugins requested by the user (`skills:` / `plugins:` frontmatter, never on-the-fly installs): `.github/aw/skills.md` When the task involves OTEL, OTLP, traces, observability backends, or telemetry-driven analysis, also read and follow `skills/otel-queries/SKILL.md` after loading the matching workflow prompt or skill. diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 0a125d9c4c2..5ff8b1c0972 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -109,7 +109,7 @@ Every news workflow declares the **same** tool & runtime surface for parity, res | Field | Value | Purpose | |-------|-------|---------| | `runtimes.node.version` | `"26"` | Pinned Node 26 for IMF CLI + render scripts | -| `engine.id` / `engine.model` | `copilot` / `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.id` / `engine.model` | `copilot` / `claude-opus-5` (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-timeout` | ~~`1h`~~ **removed** | Was 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`](https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/github-tools.md) | | `tools.bash` / `tools.edit` / `tools.web-fetch` / `tools.agentic-workflows` | enabled | Full local tool surface; `web-fetch` reaches non-MCP public sources (`statskontoret.se`, `riksdagsmonitor.com`) through the AWF firewall | diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml index ddccd5e146f..312a338159c 100644 --- a/.github/workflows/agentics-maintenance.yml +++ b/.github/workflows/agentics-maintenance.yml @@ -1,4 +1,4 @@ -# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.82.7). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -44,9 +44,9 @@ on: description: 'Optional maintenance operation to run' required: false type: choice - default: '' + default: 'none' options: - - '' + - 'none' - 'disable' - 'enable' - 'update' @@ -88,13 +88,13 @@ permissions: {} jobs: close-expired-discussions: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }} runs-on: ubuntu-slim permissions: discussions: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -102,18 +102,20 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_discussions.cjs'); + const { main } = require(path.join(actionsDir, 'close_expired_discussions.cjs')); await main(); close-expired-issues: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }} runs-on: ubuntu-slim permissions: issues: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -121,18 +123,20 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_issues.cjs'); + const { main } = require(path.join(actionsDir, 'close_expired_issues.cjs')); await main(); close-expired-pull-requests: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }} + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none') }} runs-on: ubuntu-slim permissions: pull-requests: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -140,19 +144,21 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_pull_requests.cjs'); + const { main } = require(path.join(actionsDir, 'close_expired_pull_requests.cjs')); await main(); cleanup-cache-memory: - if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }} + if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'none' || inputs.operation == 'clean_cache_memories') }} runs-on: ubuntu-slim permissions: actions: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -160,13 +166,15 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/cleanup_cache_memory.cjs'); + const { main } = require(path.join(actionsDir, 'cleanup_cache_memory.cjs')); await main(); run_operation: - if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }} + if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'none' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }} runs-on: ubuntu-slim permissions: actions: write @@ -181,7 +189,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -190,15 +198,17 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Install gh-aw - uses: github/gh-aw-actions/setup-cli@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: v0.82.7 + version: v0.87.9 - name: Run operation uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -209,9 +219,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs'); + const { main } = require(path.join(actionsDir, 'run_operation_update_upgrade.cjs')); await main(); - name: Record outputs @@ -228,7 +240,7 @@ jobs: pull-requests: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -237,9 +249,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Update pull request branches @@ -249,9 +263,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/update_pull_request_branches.cjs'); + const { main } = require(path.join(actionsDir, 'update_pull_request_branches.cjs')); await main(); apply_safe_outputs: @@ -275,7 +291,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -284,9 +300,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Apply Safe Outputs @@ -297,9 +315,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs'); + const { main } = require(path.join(actionsDir, 'apply_safe_outputs_replay.cjs')); await main(); - name: Record outputs @@ -321,7 +341,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -330,15 +350,17 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Install gh-aw - uses: github/gh-aw-actions/setup-cli@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: v0.82.7 + version: v0.87.9 - name: Create missing labels uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -347,9 +369,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/create_labels.cjs'); + const { main } = require(path.join(actionsDir, 'create_labels.cjs')); await main(); activity_report: @@ -367,7 +391,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -376,15 +400,17 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Install gh-aw - uses: github/gh-aw-actions/setup-cli@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: v0.82.7 + version: v0.87.9 - name: Restore activity report logs cache id: activity_report_logs_cache @@ -472,7 +498,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -481,15 +507,17 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Install gh-aw - uses: github/gh-aw-actions/setup-cli@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: v0.82.7 + version: v0.87.9 - name: Restore forecast report logs cache id: forecast_report_logs_cache @@ -552,9 +580,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/create_forecast_issue.cjs'); + const { main } = require(path.join(actionsDir, 'create_forecast_issue.cjs')); await main(); close_agentic_workflows_issues: @@ -564,7 +594,7 @@ jobs: issues: write steps: - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -573,9 +603,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Close no-repro agentic-workflows issues @@ -583,9 +615,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/close_agentic_workflows_issues.cjs'); + const { main } = require(path.join(actionsDir, 'close_agentic_workflows_issues.cjs')); await main(); validate_workflows: @@ -601,7 +635,7 @@ jobs: persist-credentials: false - name: Setup Scripts - uses: github/gh-aw-actions/setup@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions @@ -610,15 +644,17 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs'); + const { main } = require(path.join(actionsDir, 'check_team_member.cjs')); await main(); - name: Install gh-aw - uses: github/gh-aw-actions/setup-cli@bf7ba42ce6443bf79fa184c9c6a35de202690bfc # v0.82.7 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: v0.82.7 + version: v0.87.9 - name: Validate workflows and file issue on findings uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -627,7 +663,9 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/run_validate_workflows.cjs'); + const { main } = require(path.join(actionsDir, 'run_validate_workflows.cjs')); await main(); diff --git a/.github/workflows/compile-agentic-workflows.yml b/.github/workflows/compile-agentic-workflows.yml index 91dbff0eebb..7e1f6e5342c 100644 --- a/.github/workflows/compile-agentic-workflows.yml +++ b/.github/workflows/compile-agentic-workflows.yml @@ -42,7 +42,7 @@ jobs: - name: Install gh-aw CLI run: | - GH_AW_VERSION="v0.83.1" + GH_AW_VERSION="v0.87.9" gh extension install github/gh-aw --pin "$GH_AW_VERSION" env: GH_TOKEN: ${{ secrets.COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index f3e9af09e67..b6200d7266e 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -113,7 +113,7 @@ jobs: - name: Install gh-aw CLI run: | - GH_AW_VERSION="v0.82.13" + GH_AW_VERSION="v0.87.9" gh extension install github/gh-aw --pin "$GH_AW_VERSION" env: GH_TOKEN: ${{ secrets.COPILOT_MCP_GITHUB_PERSONAL_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/news-committee-reports.lock.yml b/.github/workflows/news-committee-reports.lock.yml index e4d55719608..67b853deef4 100644 --- a/.github/workflows/news-committee-reports.lock.yml +++ b/.github/workflows/news-committee-reports.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"7c82c2654b6034869813930e7a92c8a8a7471ff6d6e4bab3aba7027383accd17","body_hash":"aff46e944dd3416665cdaaaa203166c50d2df4eb33f5b5eadb0822f7d7abd810","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"b864437e8777ed77539ae501b0a7e382f700f757db82afecc463ee7ec72ed169","body_hash":"aff46e944dd3416665cdaaaa203166c50d2df4eb33f5b5eadb0822f7d7abd810","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -37,8 +37,8 @@ # - ../prompts/07-commit-and-pr.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -48,23 +48,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Committee Reports" @@ -99,6 +98,14 @@ concurrency: run-name: "News: Committee Reports" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-committee-reports + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Committee%20Reports,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -112,6 +119,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -125,7 +133,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -133,35 +141,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Committee Reports" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -188,9 +202,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -208,15 +224,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -226,20 +243,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -248,146 +263,108 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_a3b9e36f580dde26_EOF' - - GH_AW_PROMPT_a3b9e36f580dde26_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_a3b9e36f580dde26_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_a3b9e36f580dde26_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_a3b9e36f580dde26_EOF' - - GH_AW_PROMPT_a3b9e36f580dde26_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_a3b9e36f580dde26_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_a3b9e36f580dde26_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_a3b9e36f580dde26_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/workflows/news-committee-reports.md}} - GH_AW_PROMPT_a3b9e36f580dde26_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/workflows/news-committee-reports.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -398,27 +375,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -451,12 +435,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newscommitteereports outputs: @@ -472,7 +463,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -480,11 +474,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -493,17 +488,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -570,16 +572,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -588,13 +593,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -606,44 +613,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -666,9 +663,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -676,6 +682,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -699,6 +715,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -712,6 +734,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -797,9 +831,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -808,6 +844,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -815,6 +852,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -826,17 +868,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -857,13 +906,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -889,7 +938,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -911,6 +960,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -922,7 +979,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -944,7 +1001,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -964,7 +1021,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -974,10 +1031,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -988,9 +1050,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1002,21 +1066,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1034,14 +1122,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1050,7 +1143,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1071,7 +1164,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1096,9 +1200,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1122,14 +1228,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1139,9 +1247,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1149,9 +1259,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1165,9 +1277,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1175,10 +1289,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1204,6 +1331,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1220,6 +1359,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1240,9 +1381,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1260,7 +1402,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1269,15 +1411,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1285,42 +1428,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1334,6 +1464,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1356,9 +1488,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1388,7 +1522,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-committee-reports.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1396,9 +1530,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1413,9 +1549,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1428,9 +1566,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1443,9 +1583,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1472,6 +1614,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1492,9 +1638,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Committee Reports" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-committee-reports.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1506,6 +1673,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1516,7 +1684,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1525,15 +1693,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1541,7 +1716,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1553,7 +1730,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1577,21 +1754,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1599,82 +1762,52 @@ jobs: WORKFLOW_NAME: "News: Committee Reports" WORKFLOW_DESCRIPTION: "Generates committee reports analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1690,58 +1823,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Committee Reports" + WORKFLOW_DESCRIPTION: "Generates committee reports analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1764,8 +1941,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-committee-reports" @@ -1780,12 +1956,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1794,15 +1978,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1810,7 +1997,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1846,17 +2035,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1866,6 +2057,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1883,7 +2075,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1892,8 +2084,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Committee Reports" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-committee-reports.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-committee-reports.md b/.github/workflows/news-committee-reports.md index 2a177a6b7a7..b042b7f9bf8 100644 --- a/.github/workflows/news-committee-reports.md +++ b/.github/workflows/news-committee-reports.md @@ -287,7 +287,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-election-cycle.lock.yml b/.github/workflows/news-election-cycle.lock.yml index 0bc69cd4512..77866840e55 100644 --- a/.github/workflows/news-election-cycle.lock.yml +++ b/.github/workflows/news-election-cycle.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"c293f3035b5789624b08dd7677014f0e85952348f065c9c8f4b72bfb507bed66","body_hash":"74fa39fcf178c6b24acf3d34792cd571a1963c36d97f8f2fd662ce755b8fd03f","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8184930f7fa215e911e8801aa9f5ed9478fc98bd9d29350623c0e37ab6fe092a","body_hash":"27cdebf973e2742a638a392d00178c311b7e816524aae2c0b2086c1be611ea25","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -40,8 +40,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -51,23 +51,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Election Cycle" @@ -104,6 +103,14 @@ concurrency: run-name: "News: Election Cycle" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-election-cycle + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Election%20Cycle,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -117,6 +124,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -130,7 +138,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -138,35 +146,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Election Cycle" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -193,9 +207,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -213,15 +229,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -231,20 +248,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -253,149 +268,111 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0015\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0016\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_bb99d6ac5fa98e96_EOF' - - GH_AW_PROMPT_bb99d6ac5fa98e96_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_bb99d6ac5fa98e96_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_bb99d6ac5fa98e96_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_bb99d6ac5fa98e96_EOF' - - GH_AW_PROMPT_bb99d6ac5fa98e96_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_bb99d6ac5fa98e96_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_bb99d6ac5fa98e96_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_bb99d6ac5fa98e96_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}} - {{#runtime-import .github/prompts/ext/cycle-rollover.md}} - {{#runtime-import .github/workflows/news-election-cycle.md}} - GH_AW_PROMPT_bb99d6ac5fa98e96_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}}\n" + GH_AW_PROMPT_CONTENT_0015: "{{#runtime-import .github/prompts/ext/cycle-rollover.md}}\n" + GH_AW_PROMPT_CONTENT_0016: "{{#runtime-import .github/workflows/news-election-cycle.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -406,27 +383,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -456,12 +440,19 @@ jobs: issues: read pull-requests: read security-events: read + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newselectioncycle outputs: @@ -477,7 +468,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -485,11 +479,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -498,17 +493,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -576,16 +578,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -594,13 +599,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -612,44 +619,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_d7e29c575651a6fb_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":720,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data","long-horizon","forward-look","election-cycle"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_d7e29c575651a6fb_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":720,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"election-cycle\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -672,9 +669,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -682,6 +688,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -705,6 +721,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -718,6 +740,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -803,9 +837,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -814,6 +850,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -821,6 +858,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -832,17 +874,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -863,13 +912,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -895,7 +944,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -917,6 +966,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -928,7 +985,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -950,7 +1007,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -970,7 +1027,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -980,10 +1037,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -994,9 +1056,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1008,21 +1072,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1040,14 +1128,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1056,7 +1149,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1077,7 +1170,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1102,9 +1206,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1128,14 +1234,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1145,9 +1253,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1155,9 +1265,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1171,9 +1283,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1181,10 +1295,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1210,6 +1337,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 30 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1226,6 +1365,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1246,9 +1387,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1266,7 +1408,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1275,15 +1417,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1291,42 +1434,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1340,6 +1470,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1362,9 +1494,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1394,7 +1528,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-election-cycle.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1402,9 +1536,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1419,9 +1555,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1434,9 +1572,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1449,9 +1589,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1478,6 +1620,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1498,9 +1644,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Election Cycle" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-election-cycle.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1512,6 +1679,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1522,7 +1690,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1531,15 +1699,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1547,7 +1722,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1559,7 +1736,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1583,21 +1760,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1605,82 +1768,52 @@ jobs: WORKFLOW_NAME: "News: Election Cycle" WORKFLOW_DESCRIPTION: "Generates election-cycle deep intelligence articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. The longest forward-look horizon — covers the full 4-year mandate (current Tidö 2022-09-11 → 2026-09-13 and next 2026-09-13 → 2030-09-08). Tier-C aggregation × 2.5 depth multiplier. Mandates wildcards-blackswans + quantitative-swot + political-stride-assessment + cycle-trajectory (24th artifact) blocking. Initially workflow_dispatch only until runtime is measured over 4-6 manual runs; cron `0 9 13 3,9 *` is declared but commented out below." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1696,58 +1829,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Election Cycle" + WORKFLOW_DESCRIPTION: "Generates election-cycle deep intelligence articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. The longest forward-look horizon — covers the full 4-year mandate (current Tidö 2022-09-11 → 2026-09-13 and next 2026-09-13 → 2030-09-08). Tier-C aggregation × 2.5 depth multiplier. Mandates wildcards-blackswans + quantitative-swot + political-stride-assessment + cycle-trajectory (24th artifact) blocking. Initially workflow_dispatch only until runtime is measured over 4-6 manual runs; cron `0 9 13 3,9 *` is declared but commented out below." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1770,8 +1947,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-election-cycle" @@ -1786,12 +1962,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1800,15 +1984,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1816,7 +2003,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1852,17 +2041,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":720,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"election-cycle\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":720,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"election-cycle\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1872,6 +2063,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1889,7 +2081,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1898,8 +2090,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Election Cycle" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-election-cycle.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-election-cycle.md b/.github/workflows/news-election-cycle.md index a9ea979d5e7..28939b70b81 100644 --- a/.github/workflows/news-election-cycle.md +++ b/.github/workflows/news-election-cycle.md @@ -298,7 +298,7 @@ steps: analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: comprehensive cycle-anchor: ${{ inputs.cycle_anchor }} -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- @@ -351,7 +351,7 @@ Non-English HTML pages are produced via the **localized executive-brief cascade* > 🟡 **Plan to call `safeoutputs___create_pull_request` by agent minute 42 (hard deadline 45)** to reserve job-level headroom for setup variance and the safe-outputs runner. See `00-base-contract.md §Session timing` and `07-commit-and-pr.md §Deadline enforcement`. > -> 🔴 **Token budget awareness**: This workflow uses `claude-opus-4.8` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** +> 🔴 **Token budget awareness**: This workflow uses `claude-opus-5` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** This workflow runs at the **upper limit** of the 60-minute job envelope. Initially gated `workflow_dispatch`-only until runtime is measured over 4–6 manual runs. diff --git a/.github/workflows/news-evening-analysis.lock.yml b/.github/workflows/news-evening-analysis.lock.yml index a49dd4e0f37..46ceaca24be 100644 --- a/.github/workflows/news-evening-analysis.lock.yml +++ b/.github/workflows/news-evening-analysis.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"826aa036a425303fa6efcd4cbabd37290a3179a648a52c16bff1c749c7da3484","body_hash":"aaa18190882238f675635c89c197bb3a540fd52358d6c783a73331fa6e7a8947","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"cc4923034a7f9dd4d2ffd02dc90534bab65c50a8ffa9b5d791af34ffc238529a","body_hash":"aaa18190882238f675635c89c197bb3a540fd52358d6c783a73331fa6e7a8947","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -38,8 +38,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -49,23 +49,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News Evening Analysis" @@ -104,6 +103,14 @@ concurrency: run-name: "News Evening Analysis" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-evening-analysis + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%20Evening%20Analysis,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -117,6 +124,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -130,7 +138,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -138,35 +146,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News Evening Analysis" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -193,9 +207,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -213,15 +229,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -231,20 +248,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -253,147 +268,109 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF' - - GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF' - - GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/workflows/news-evening-analysis.md}} - GH_AW_PROMPT_5e63cfcb7efdbd5f_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/workflows/news-evening-analysis.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -404,27 +381,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -457,12 +441,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newseveninganalysis outputs: @@ -478,7 +469,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -486,11 +480,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -499,17 +494,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -577,16 +579,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -595,13 +600,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -613,44 +620,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -673,9 +670,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -683,6 +689,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -706,6 +722,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -719,6 +741,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -804,9 +838,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -815,6 +851,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -822,6 +859,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -833,17 +875,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -864,13 +913,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -896,7 +945,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -918,6 +967,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -929,7 +986,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -951,7 +1008,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -971,7 +1028,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -981,10 +1038,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -995,9 +1057,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1009,21 +1073,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1041,14 +1129,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1057,7 +1150,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1078,7 +1171,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1103,9 +1207,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1129,14 +1235,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1146,9 +1254,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1156,9 +1266,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1172,9 +1284,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1182,10 +1296,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1211,6 +1338,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1227,6 +1366,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1247,9 +1388,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1267,7 +1409,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1276,15 +1418,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1292,42 +1435,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1341,6 +1471,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1363,9 +1495,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1395,7 +1529,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-evening-analysis.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1403,9 +1537,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1420,9 +1556,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1435,9 +1573,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1450,9 +1590,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1479,6 +1621,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1499,9 +1645,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News Evening Analysis" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-evening-analysis.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1513,6 +1680,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1523,7 +1691,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1532,15 +1700,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1548,7 +1723,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1560,7 +1737,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1584,21 +1761,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1606,82 +1769,52 @@ jobs: WORKFLOW_NAME: "News Evening Analysis" WORKFLOW_DESCRIPTION: "Generates comprehensive evening analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade with Playwright validation. On Saturdays, produces a weekly wrap-up reviewing the full parliamentary week. news-translate runs on a separate track to translate executive-brief.md into 13 languages." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1697,58 +1830,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News Evening Analysis" + WORKFLOW_DESCRIPTION: "Generates comprehensive evening analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade with Playwright validation. On Saturdays, produces a weekly wrap-up reviewing the full parliamentary week. news-translate runs on a separate track to translate executive-brief.md into 13 languages." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1771,8 +1948,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-evening-analysis" @@ -1787,12 +1963,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1801,15 +1985,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1817,7 +2004,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1853,17 +2042,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1873,6 +2064,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1890,7 +2082,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1899,8 +2091,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Evening Analysis" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-evening-analysis.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-evening-analysis.md b/.github/workflows/news-evening-analysis.md index 3f67580490a..6368d8d7e7c 100644 --- a/.github/workflows/news-evening-analysis.md +++ b/.github/workflows/news-evening-analysis.md @@ -296,7 +296,7 @@ steps: default-analysis-depth: deep coverage-depth: ${{ inputs.coverage_depth }} lookback-hours: ${{ inputs.lookback_hours }} -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-interpellations.lock.yml b/.github/workflows/news-interpellations.lock.yml index 341bdcd3bb8..bf9e5a15efa 100644 --- a/.github/workflows/news-interpellations.lock.yml +++ b/.github/workflows/news-interpellations.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"16660f9c9491d52db755ee32f56774646f994dd0f68e7c7747aa9b00ac37d103","body_hash":"5428aaa643b150f6d7babb5174bf6843fcdf3d5ce4e1093172f1a7ecfbf7c500","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"b620a70e4abc2cbe73350e241d914ff9824b241aa0bae6c241ceb99acfcc8db7","body_hash":"5428aaa643b150f6d7babb5174bf6843fcdf3d5ce4e1093172f1a7ecfbf7c500","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -37,8 +37,8 @@ # - ../prompts/07-commit-and-pr.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -48,23 +48,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Interpellation Debates" @@ -99,6 +98,14 @@ concurrency: run-name: "News: Interpellation Debates" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-interpellations + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Interpellation%20Debates,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -112,6 +119,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -125,7 +133,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -133,35 +141,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -188,9 +202,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -208,15 +224,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -226,20 +243,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -248,146 +263,108 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_bf16db967f8bf042_EOF' - - GH_AW_PROMPT_bf16db967f8bf042_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_bf16db967f8bf042_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_bf16db967f8bf042_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_bf16db967f8bf042_EOF' - - GH_AW_PROMPT_bf16db967f8bf042_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_bf16db967f8bf042_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_bf16db967f8bf042_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_bf16db967f8bf042_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/workflows/news-interpellations.md}} - GH_AW_PROMPT_bf16db967f8bf042_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/workflows/news-interpellations.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -398,27 +375,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -451,12 +435,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsinterpellations outputs: @@ -472,7 +463,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -480,11 +474,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -493,17 +488,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -570,16 +572,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -588,13 +593,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -606,44 +613,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -666,9 +663,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -676,6 +682,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -699,6 +715,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -712,6 +734,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -797,9 +831,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -808,6 +844,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -815,6 +852,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -826,17 +868,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -857,13 +906,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -889,7 +938,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -911,6 +960,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -922,7 +979,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -944,7 +1001,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -964,7 +1021,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -974,10 +1031,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -988,9 +1050,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1002,21 +1066,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1034,14 +1122,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1050,7 +1143,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1071,7 +1164,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1096,9 +1200,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1122,14 +1228,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1139,9 +1247,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1149,9 +1259,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1165,9 +1277,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1175,10 +1289,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1204,6 +1331,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1220,6 +1359,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1240,9 +1381,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1260,7 +1402,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1269,15 +1411,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1285,42 +1428,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1334,6 +1464,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1356,9 +1488,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1388,7 +1522,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-interpellations.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1396,9 +1530,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1413,9 +1549,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1428,9 +1566,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1443,9 +1583,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1472,6 +1614,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1492,9 +1638,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Interpellation Debates" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-interpellations.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1506,6 +1673,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1516,7 +1684,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1525,15 +1693,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1541,7 +1716,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1553,7 +1730,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1577,21 +1754,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1599,82 +1762,52 @@ jobs: WORKFLOW_NAME: "News: Interpellation Debates" WORKFLOW_DESCRIPTION: "Generates interpellation debates analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. The news-translate workflow runs on a separate track and handles executive-brief markdown translations only; no inter-workflow dispatch." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1690,58 +1823,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Interpellation Debates" + WORKFLOW_DESCRIPTION: "Generates interpellation debates analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. The news-translate workflow runs on a separate track and handles executive-brief markdown translations only; no inter-workflow dispatch." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1764,8 +1941,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-interpellations" @@ -1780,12 +1956,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1794,15 +1978,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1810,7 +1997,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1846,17 +2035,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1866,6 +2057,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1883,7 +2075,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1892,8 +2084,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Interpellation Debates" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-interpellations.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-interpellations.md b/.github/workflows/news-interpellations.md index 7adfeef5688..1917cdaef06 100644 --- a/.github/workflows/news-interpellations.md +++ b/.github/workflows/news-interpellations.md @@ -287,7 +287,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-month-ahead.lock.yml b/.github/workflows/news-month-ahead.lock.yml index ae941f31b2a..2e5f1617cb5 100644 --- a/.github/workflows/news-month-ahead.lock.yml +++ b/.github/workflows/news-month-ahead.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9921252770495ce3514ae20e5a7001e3e57b2d8c215f2c398fc4cd735c7aca9a","body_hash":"f7003b3dcc0c37176708d7d2d7a214e5865827dbf617c969f63b504d81438e8a","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5f97d67262a9d7504ccfb28f330d5d27aeaa24f0c4f0dfaa342e6d2cb2f022d8","body_hash":"567d70d35cba465159a5768a71609b78274f14072704d924eb7fb1ee90d11b85","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -39,8 +39,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -50,23 +50,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Month Ahead" @@ -101,6 +100,14 @@ concurrency: run-name: "News: Month Ahead" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-month-ahead + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Month%20Ahead,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -114,6 +121,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -127,7 +135,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -135,35 +143,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Month Ahead" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -190,9 +204,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -210,15 +226,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -228,20 +245,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -250,148 +265,110 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0015\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_33269f8f5218698e_EOF' - - GH_AW_PROMPT_33269f8f5218698e_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_33269f8f5218698e_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_33269f8f5218698e_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_33269f8f5218698e_EOF' - - GH_AW_PROMPT_33269f8f5218698e_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_33269f8f5218698e_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_33269f8f5218698e_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_33269f8f5218698e_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}} - {{#runtime-import .github/workflows/news-month-ahead.md}} - GH_AW_PROMPT_33269f8f5218698e_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}}\n" + GH_AW_PROMPT_CONTENT_0015: "{{#runtime-import .github/workflows/news-month-ahead.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -402,27 +379,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -455,12 +439,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsmonthahead outputs: @@ -476,7 +467,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -484,11 +478,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -497,17 +492,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -574,16 +576,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -592,13 +597,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -610,44 +617,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -670,9 +667,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -680,6 +686,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -703,6 +719,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -716,6 +738,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -801,9 +835,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -812,6 +848,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -819,6 +856,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -830,17 +872,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -861,13 +910,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -893,7 +942,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -915,6 +964,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -926,7 +983,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -948,7 +1005,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -968,7 +1025,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -978,10 +1035,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -992,9 +1054,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1006,21 +1070,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1038,14 +1126,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1054,7 +1147,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1075,7 +1168,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1100,9 +1204,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1126,14 +1232,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1143,9 +1251,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1153,9 +1263,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1169,9 +1281,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1179,10 +1293,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1208,6 +1335,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1224,6 +1363,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1244,9 +1385,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1264,7 +1406,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1273,15 +1415,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1289,42 +1432,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1338,6 +1468,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1360,9 +1492,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1392,7 +1526,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-month-ahead.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1400,9 +1534,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1417,9 +1553,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1432,9 +1570,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1447,9 +1587,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1476,6 +1618,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1496,9 +1642,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Month Ahead" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-month-ahead.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1510,6 +1677,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1520,7 +1688,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1529,15 +1697,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1545,7 +1720,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1557,7 +1734,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1581,21 +1758,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1603,82 +1766,52 @@ jobs: WORKFLOW_NAME: "News: Month Ahead" WORKFLOW_DESCRIPTION: "Generates month-ahead strategic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs on 1st of each month." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1694,58 +1827,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Month Ahead" + WORKFLOW_DESCRIPTION: "Generates month-ahead strategic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs on 1st of each month." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1768,8 +1945,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-month-ahead" @@ -1784,12 +1960,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1798,15 +1982,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1814,7 +2001,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1850,17 +2039,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1870,6 +2061,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1887,7 +2079,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1896,8 +2088,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Month Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-month-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-month-ahead.md b/.github/workflows/news-month-ahead.md index 230525ac0db..dc61523dca7 100644 --- a/.github/workflows/news-month-ahead.md +++ b/.github/workflows/news-month-ahead.md @@ -290,7 +290,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- @@ -311,7 +311,7 @@ Generates deep political intelligence analysis **and** renders the HTML article > 🟡 **Plan to call `safeoutputs___create_pull_request` by agent minute 42 (hard deadline 45)** to reserve job-level headroom for setup variance and the safe-outputs runner. See `00-base-contract.md §Session timing` and `07-commit-and-pr.md §Deadline enforcement`. > -> 🔴 **Token budget awareness**: This workflow uses `claude-opus-4.8` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** +> 🔴 **Token budget awareness**: This workflow uses `claude-opus-5` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** > > **AI-FIRST within the 60-minute budget**: Pass 2 is still mandatory. Scheduled runs should honor the configured `analysis_depth=deep` default instead of pre-emptively downgrading scope. Prefer **scope compression over iteration skipping** only if runtime risk emerges — reduce the download/manifest scope if needed, but maintain 1:1 per-document coverage and always perform a full read-back-and-improve Pass 2 on whatever artifacts exist. Reserve `comprehensive` for manual `workflow_dispatch` backfills. diff --git a/.github/workflows/news-monthly-review.lock.yml b/.github/workflows/news-monthly-review.lock.yml index 6558d52bf89..f72cd77a1f0 100644 --- a/.github/workflows/news-monthly-review.lock.yml +++ b/.github/workflows/news-monthly-review.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f62e5bdc74cd1855e4f9e15acb6b7d49b8bde7e0a95fd1737096bbbea4b07de8","body_hash":"c2f2b284b8cb15885c811e4d16afd45e9aed6203b9bb47e26d97229c27d9858c","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e963f7cab749ec79914fe0b3f0f5432b37024eb2005a315d4aa24edd3c9f5ee2","body_hash":"c2f2b284b8cb15885c811e4d16afd45e9aed6203b9bb47e26d97229c27d9858c","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -38,8 +38,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -49,23 +49,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Monthly Review" @@ -100,6 +99,14 @@ concurrency: run-name: "News: Monthly Review" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-monthly-review + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Monthly%20Review,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -113,6 +120,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -126,7 +134,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -134,35 +142,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Monthly Review" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -189,9 +203,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -209,15 +225,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -227,20 +244,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -249,147 +264,109 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_743d19cb9edb3064_EOF' - - GH_AW_PROMPT_743d19cb9edb3064_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_743d19cb9edb3064_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_743d19cb9edb3064_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_743d19cb9edb3064_EOF' - - GH_AW_PROMPT_743d19cb9edb3064_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_743d19cb9edb3064_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_743d19cb9edb3064_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_743d19cb9edb3064_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/workflows/news-monthly-review.md}} - GH_AW_PROMPT_743d19cb9edb3064_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/workflows/news-monthly-review.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -400,27 +377,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -453,12 +437,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsmonthlyreview outputs: @@ -474,7 +465,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -482,11 +476,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -495,17 +490,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -572,16 +574,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -590,13 +595,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -608,44 +615,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -668,9 +665,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -678,6 +684,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -701,6 +717,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -714,6 +736,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -799,9 +833,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -810,6 +846,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -817,6 +854,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -828,17 +870,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -859,13 +908,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -891,7 +940,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -913,6 +962,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -924,7 +981,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -946,7 +1003,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -966,7 +1023,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -976,10 +1033,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -990,9 +1052,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1004,21 +1068,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1036,14 +1124,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1052,7 +1145,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1073,7 +1166,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1098,9 +1202,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1124,14 +1230,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1141,9 +1249,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1151,9 +1261,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1167,9 +1279,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1177,10 +1291,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1206,6 +1333,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1222,6 +1361,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1242,9 +1383,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1262,7 +1404,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1271,15 +1413,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1287,42 +1430,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1336,6 +1466,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1358,9 +1490,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1390,7 +1524,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-monthly-review.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1398,9 +1532,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1415,9 +1551,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1430,9 +1568,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1445,9 +1585,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1474,6 +1616,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1494,9 +1640,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Monthly Review" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-monthly-review.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1508,6 +1675,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1518,7 +1686,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1527,15 +1695,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1543,7 +1718,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1555,7 +1732,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1579,21 +1756,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1601,82 +1764,52 @@ jobs: WORKFLOW_NAME: "News: Monthly Review" WORKFLOW_DESCRIPTION: "Generates monthly review retrospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs on 28th of each month." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1692,58 +1825,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Monthly Review" + WORKFLOW_DESCRIPTION: "Generates monthly review retrospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs on 28th of each month." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1766,8 +1943,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-monthly-review" @@ -1782,12 +1958,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1796,15 +1980,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1812,7 +1999,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1848,17 +2037,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1868,6 +2059,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1885,7 +2077,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1894,8 +2086,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Monthly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-monthly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-monthly-review.md b/.github/workflows/news-monthly-review.md index 6beded79e63..4ad9cbd603f 100644 --- a/.github/workflows/news-monthly-review.md +++ b/.github/workflows/news-monthly-review.md @@ -289,7 +289,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-motions.lock.yml b/.github/workflows/news-motions.lock.yml index 553bf8383b5..03e95603a65 100644 --- a/.github/workflows/news-motions.lock.yml +++ b/.github/workflows/news-motions.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"996d6374cbee0d7484321cbcb237d41bf549af034d0d75bc294eb83b468cb6ea","body_hash":"360a7b0f008b167b1908f991e5177cb9bf0d0f45589ac87066ad3b7bc6bdc1b7","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f23f15120cfa06cef0baca5b1a343c43df109b0c0e94704aadcd6d15560aad2d","body_hash":"360a7b0f008b167b1908f991e5177cb9bf0d0f45589ac87066ad3b7bc6bdc1b7","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -37,8 +37,8 @@ # - ../prompts/07-commit-and-pr.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -48,23 +48,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Opposition Motions" @@ -99,6 +98,14 @@ concurrency: run-name: "News: Opposition Motions" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-motions + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Opposition%20Motions,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -112,6 +119,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -125,7 +133,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -133,35 +141,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -188,9 +202,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -208,15 +224,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -226,20 +243,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -248,146 +263,108 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_d347fea86036df46_EOF' - - GH_AW_PROMPT_d347fea86036df46_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_d347fea86036df46_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_d347fea86036df46_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_d347fea86036df46_EOF' - - GH_AW_PROMPT_d347fea86036df46_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_d347fea86036df46_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_d347fea86036df46_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_d347fea86036df46_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/workflows/news-motions.md}} - GH_AW_PROMPT_d347fea86036df46_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/workflows/news-motions.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -398,27 +375,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -451,12 +435,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsmotions outputs: @@ -472,7 +463,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -480,11 +474,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -493,17 +488,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -570,16 +572,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -588,13 +593,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -606,44 +613,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -666,9 +663,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -676,6 +682,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -699,6 +715,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -712,6 +734,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -797,9 +831,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -808,6 +844,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -815,6 +852,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -826,17 +868,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -857,13 +906,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -889,7 +938,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -911,6 +960,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -922,7 +979,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -944,7 +1001,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -964,7 +1021,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -974,10 +1031,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -988,9 +1050,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1002,21 +1066,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1034,14 +1122,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1050,7 +1143,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1071,7 +1164,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1096,9 +1200,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1122,14 +1228,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1139,9 +1247,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1149,9 +1259,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1165,9 +1277,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1175,10 +1289,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1204,6 +1331,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1220,6 +1359,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1240,9 +1381,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1260,7 +1402,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1269,15 +1411,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1285,42 +1428,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1334,6 +1464,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1356,9 +1488,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1388,7 +1522,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-motions.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1396,9 +1530,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1413,9 +1549,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1428,9 +1566,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1443,9 +1583,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1472,6 +1614,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1492,9 +1638,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Opposition Motions" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-motions.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1506,6 +1673,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1516,7 +1684,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1525,15 +1693,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1541,7 +1716,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1553,7 +1730,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1577,21 +1754,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1599,82 +1762,52 @@ jobs: WORKFLOW_NAME: "News: Opposition Motions" WORKFLOW_DESCRIPTION: "Generates opposition motions analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1690,58 +1823,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Opposition Motions" + WORKFLOW_DESCRIPTION: "Generates opposition motions analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1764,8 +1941,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-motions" @@ -1780,12 +1956,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1794,15 +1978,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1810,7 +1997,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1846,17 +2035,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1866,6 +2057,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1883,7 +2075,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1892,8 +2084,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Opposition Motions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-motions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-motions.md b/.github/workflows/news-motions.md index 0d24cdd50e7..6036b649591 100644 --- a/.github/workflows/news-motions.md +++ b/.github/workflows/news-motions.md @@ -287,7 +287,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-propositions.lock.yml b/.github/workflows/news-propositions.lock.yml index 935e6bc4ed2..cfa0d7c0313 100644 --- a/.github/workflows/news-propositions.lock.yml +++ b/.github/workflows/news-propositions.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d8d4d224b1fab94e324c1264e3c5c430e9c5499e26d6c92f44e61d6aa4575378","body_hash":"bee9cf9a29a4564e7dad1cb0b59b0eb1097a7dae9298a34fbae5989f32fc2ea7","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"759e304f81a4774c87315de1c8e3e916b606f665a83940eb2411f9577c34eb9e","body_hash":"bee9cf9a29a4564e7dad1cb0b59b0eb1097a7dae9298a34fbae5989f32fc2ea7","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -37,8 +37,8 @@ # - ../prompts/07-commit-and-pr.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -48,23 +48,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Government Propositions" @@ -99,6 +98,14 @@ concurrency: run-name: "News: Government Propositions" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-propositions + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Government%20Propositions,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -112,6 +119,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -125,7 +133,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -133,35 +141,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Government Propositions" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -188,9 +202,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -208,15 +224,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -226,20 +243,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -248,146 +263,108 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_d734ca7470c12a64_EOF' - - GH_AW_PROMPT_d734ca7470c12a64_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_d734ca7470c12a64_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_d734ca7470c12a64_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_d734ca7470c12a64_EOF' - - GH_AW_PROMPT_d734ca7470c12a64_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_d734ca7470c12a64_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_d734ca7470c12a64_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_d734ca7470c12a64_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/workflows/news-propositions.md}} - GH_AW_PROMPT_d734ca7470c12a64_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/workflows/news-propositions.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -398,27 +375,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -451,12 +435,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newspropositions outputs: @@ -472,7 +463,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -480,11 +474,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -493,17 +488,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -570,16 +572,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -588,13 +593,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -606,44 +613,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -666,9 +663,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -676,6 +682,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -699,6 +715,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -712,6 +734,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -797,9 +831,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -808,6 +844,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -815,6 +852,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -826,17 +868,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -857,13 +906,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -889,7 +938,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -911,6 +960,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -922,7 +979,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -944,7 +1001,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -964,7 +1021,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -974,10 +1031,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -988,9 +1050,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1002,21 +1066,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1034,14 +1122,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1050,7 +1143,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1071,7 +1164,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1096,9 +1200,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1122,14 +1228,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1139,9 +1247,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1149,9 +1259,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1165,9 +1277,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1175,10 +1289,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1204,6 +1331,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1220,6 +1359,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1240,9 +1381,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1260,7 +1402,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1269,15 +1411,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1285,42 +1428,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1334,6 +1464,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1356,9 +1488,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1388,7 +1522,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-propositions.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1396,9 +1530,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1413,9 +1549,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1428,9 +1566,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1443,9 +1583,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1472,6 +1614,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1492,9 +1638,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Government Propositions" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-propositions.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1506,6 +1673,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1516,7 +1684,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1525,15 +1693,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1541,7 +1716,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1553,7 +1730,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1577,21 +1754,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1599,82 +1762,52 @@ jobs: WORKFLOW_NAME: "News: Government Propositions" WORKFLOW_DESCRIPTION: "Generates government propositions analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1690,58 +1823,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Government Propositions" + WORKFLOW_DESCRIPTION: "Generates government propositions analysis articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Single article type per run; news-translate runs on a separate track to translate executive-brief.md into 13 languages." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1764,8 +1941,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-propositions" @@ -1780,12 +1956,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1794,15 +1978,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1810,7 +1997,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1846,17 +2035,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1866,6 +2057,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1883,7 +2075,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1892,8 +2084,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Government Propositions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-propositions.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-propositions.md b/.github/workflows/news-propositions.md index 4a3a8a85a56..1ce0316651f 100644 --- a/.github/workflows/news-propositions.md +++ b/.github/workflows/news-propositions.md @@ -287,7 +287,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-quarter-ahead.lock.yml b/.github/workflows/news-quarter-ahead.lock.yml index 354666391bf..b686e6bf7c6 100644 --- a/.github/workflows/news-quarter-ahead.lock.yml +++ b/.github/workflows/news-quarter-ahead.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"472c3fe41a56de839fbff9de4be9ddbc9f223ee09e8961743e9b6beefb44854e","body_hash":"e30367c0a300482c8698ae33ca0a79f5e0821bff80a69b5bb18a1475bd6526b7","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"214f6074e3fc6aeb2f329639777298658766a8f6445947c3e5c898d1c3995e9e","body_hash":"fc264175108ded7a1856a32854ed6dc3eccbd35c8666a42399d8df8ed134c414","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -39,8 +39,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -50,23 +50,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Quarter Ahead" @@ -101,6 +100,14 @@ concurrency: run-name: "News: Quarter Ahead" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-quarter-ahead + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Quarter%20Ahead,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -114,6 +121,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -127,7 +135,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -135,35 +143,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -190,9 +204,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -210,15 +226,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -228,20 +245,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -250,148 +265,110 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0015\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_845de924ed4a3740_EOF' - - GH_AW_PROMPT_845de924ed4a3740_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_845de924ed4a3740_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_845de924ed4a3740_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_845de924ed4a3740_EOF' - - GH_AW_PROMPT_845de924ed4a3740_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_845de924ed4a3740_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_845de924ed4a3740_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_845de924ed4a3740_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}} - {{#runtime-import .github/workflows/news-quarter-ahead.md}} - GH_AW_PROMPT_845de924ed4a3740_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}}\n" + GH_AW_PROMPT_CONTENT_0015: "{{#runtime-import .github/workflows/news-quarter-ahead.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -402,27 +379,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -455,12 +439,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsquarterahead outputs: @@ -476,7 +467,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -484,11 +478,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -497,17 +492,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -574,16 +576,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -592,13 +597,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -610,44 +617,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_cb319f32a0e6908a_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data","long-horizon","forward-look"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_cb319f32a0e6908a_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -670,9 +667,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -680,6 +686,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -703,6 +719,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -716,6 +738,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -801,9 +835,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -812,6 +848,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -819,6 +856,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -830,17 +872,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -861,13 +910,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -893,7 +942,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -915,6 +964,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -926,7 +983,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -948,7 +1005,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -968,7 +1025,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -978,10 +1035,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -992,9 +1054,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1006,21 +1070,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1038,14 +1126,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1054,7 +1147,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1075,7 +1168,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1100,9 +1204,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1126,14 +1232,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1143,9 +1251,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1153,9 +1263,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1169,9 +1281,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1179,10 +1293,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1208,6 +1335,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1224,6 +1363,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1244,9 +1385,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1264,7 +1406,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1273,15 +1415,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1289,42 +1432,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1338,6 +1468,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1360,9 +1492,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1392,7 +1526,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-quarter-ahead.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1400,9 +1534,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1417,9 +1553,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1432,9 +1570,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1447,9 +1587,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1476,6 +1618,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1496,9 +1642,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Quarter Ahead" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-quarter-ahead.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1510,6 +1677,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1520,7 +1688,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1529,15 +1697,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1545,7 +1720,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1557,7 +1734,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1581,21 +1758,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1603,82 +1766,52 @@ jobs: WORKFLOW_NAME: "News: Quarter Ahead" WORKFLOW_DESCRIPTION: "Generates quarter-ahead strategic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Long-horizon-forecast workflow with 90-day window — covers next-quarter parliamentary calendar, committee schedules, government propositions tabling deadlines, Riksbank rate decisions, and SCB quarterly NA release. Tier-C aggregation × 1.7 depth multiplier. Runs 1st and 15th of each month." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1694,58 +1827,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Quarter Ahead" + WORKFLOW_DESCRIPTION: "Generates quarter-ahead strategic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Long-horizon-forecast workflow with 90-day window — covers next-quarter parliamentary calendar, committee schedules, government propositions tabling deadlines, Riksbank rate decisions, and SCB quarterly NA release. Tier-C aggregation × 1.7 depth multiplier. Runs 1st and 15th of each month." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1768,8 +1945,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-quarter-ahead" @@ -1784,12 +1960,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1798,15 +1982,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1814,7 +2001,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1850,17 +2039,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1870,6 +2061,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1887,7 +2079,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1896,8 +2088,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Quarter Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-quarter-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-quarter-ahead.md b/.github/workflows/news-quarter-ahead.md index 9fbbed1243c..232eaf31f2c 100644 --- a/.github/workflows/news-quarter-ahead.md +++ b/.github/workflows/news-quarter-ahead.md @@ -290,7 +290,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- @@ -323,7 +323,7 @@ The dedicated `news-translate` workflow runs on a separate track and translates > 🟡 **Plan to call `safeoutputs___create_pull_request` by agent minute 42 (hard deadline 45)** to reserve job-level headroom for setup variance and the safe-outputs runner. See `00-base-contract.md §Session timing` and `07-commit-and-pr.md §Deadline enforcement`. > -> 🔴 **Token budget awareness**: This workflow uses `claude-opus-4.8` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** +> 🔴 **Token budget awareness**: This workflow uses `claude-opus-5` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** | Minutes | Phase | Module | |---------|-------|--------| diff --git a/.github/workflows/news-realtime-monitor.lock.yml b/.github/workflows/news-realtime-monitor.lock.yml index 45f172f117b..b2aeb680f89 100644 --- a/.github/workflows/news-realtime-monitor.lock.yml +++ b/.github/workflows/news-realtime-monitor.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"4203b0b781a18ca92932c2175bdc568dfe2ae3ca2d80e25bcd3c2239ab4c4f49","body_hash":"54bc6555dcc22769a62593958afbc825aface948ef47b761aca3d85561000c0a","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"gpt-5.3-codex","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"db052b5226c9699209e7bf3fea0ff65bc300ee7e16c68edfd2d823624adbccdc","body_hash":"54bc6555dcc22769a62593958afbc825aface948ef47b761aca3d85561000c0a","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"gpt-5.3-codex","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -38,8 +38,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -49,23 +49,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News Realtime Monitor" @@ -105,6 +104,14 @@ concurrency: run-name: "News Realtime Monitor" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-realtime-monitor + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%20Realtime%20Monitor,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -118,6 +125,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -131,7 +139,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -139,35 +147,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: "gpt-5.3-codex" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -194,9 +208,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -214,15 +230,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -232,20 +249,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -254,147 +269,109 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_a4096660488515b2_EOF' - - GH_AW_PROMPT_a4096660488515b2_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_a4096660488515b2_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_a4096660488515b2_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_a4096660488515b2_EOF' - - GH_AW_PROMPT_a4096660488515b2_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_a4096660488515b2_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_a4096660488515b2_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_a4096660488515b2_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/workflows/news-realtime-monitor.md}} - GH_AW_PROMPT_a4096660488515b2_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/workflows/news-realtime-monitor.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -405,27 +382,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -458,12 +442,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsrealtimemonitor outputs: @@ -479,7 +470,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -487,11 +481,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -500,17 +495,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -578,16 +580,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -596,13 +601,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -614,44 +621,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -674,9 +671,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -684,6 +690,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -707,6 +723,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -720,6 +742,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -805,9 +839,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -816,6 +852,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -823,6 +860,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -834,17 +876,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -865,13 +914,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -897,7 +946,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -919,6 +968,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -930,7 +987,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -952,7 +1009,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -972,7 +1029,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -982,10 +1039,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -996,9 +1058,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1010,21 +1074,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":1500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":1500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1042,8 +1130,13 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -1058,7 +1151,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1079,7 +1172,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1104,9 +1208,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1130,14 +1236,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1147,9 +1255,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1157,9 +1267,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1173,9 +1285,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1183,10 +1297,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1212,6 +1339,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1228,6 +1367,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1248,9 +1389,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1268,7 +1410,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1277,15 +1419,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1293,42 +1436,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1342,6 +1472,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1364,9 +1496,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1396,7 +1530,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-realtime-monitor.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1404,9 +1538,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1421,9 +1557,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1436,9 +1574,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1451,9 +1591,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1480,6 +1622,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1500,9 +1646,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News Realtime Monitor" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-realtime-monitor.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1514,6 +1681,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1524,7 +1692,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1533,15 +1701,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1549,7 +1724,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1561,7 +1738,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1585,21 +1762,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1607,82 +1770,52 @@ jobs: WORKFLOW_NAME: "News Realtime Monitor" WORKFLOW_DESCRIPTION: "Monitors Riksdag and Government for real-time updates and generates breaking news articles, rendering HTML in all 14 supported languages in a single agentic run via executive-brief cascade with Playwright validation. Runs twice daily on weekdays, once on weekends." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} COPILOT_MODEL: gpt-5.3-codex + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1698,58 +1831,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News Realtime Monitor" + WORKFLOW_DESCRIPTION: "Monitors Riksdag and Government for real-time updates and generates breaking news articles, rendering HTML in all 14 supported languages in a single agentic run via executive-brief cascade with Playwright validation. Runs twice daily on weekdays, once on weekends." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1773,7 +1950,6 @@ jobs: GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" GH_AW_ENGINE_MODEL: "gpt-5.3-codex" - GH_AW_ENGINE_VERSION: "1.0.73" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-realtime-monitor" @@ -1788,12 +1964,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1802,15 +1986,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1818,7 +2005,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1854,17 +2043,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1874,6 +2065,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1891,7 +2083,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1900,8 +2092,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News Realtime Monitor" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-realtime-monitor.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-translate.lock.yml b/.github/workflows/news-translate.lock.yml index 7c2153d20f9..5ff07f30918 100644 --- a/.github/workflows/news-translate.lock.yml +++ b/.github/workflows/news-translate.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f0aadf07ed80120e3ea3316aeb7913a732e012bf29cdd60edadf5a898cb806fb","body_hash":"f9447261830f1e4cc0c34a5b8923679f43876e6c599fa3a66ad638b630f9d0bf","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"ruby/setup-ruby","sha":"9eb537ca036ebaed86729dcb9309076e4c5c3b74","version":"v1.314.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"ab0a35659975d984286ff102f05f10a47b1ea37ee4278390b4a51bbb296cbb5d","body_hash":"f9447261830f1e4cc0c34a5b8923679f43876e6c599fa3a66ad638b630f9d0bf","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"ruby/setup-ruby","sha":"95ef2b042f9d7a56d8268cba8559e2842e2ad01b","version":"v1.321.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"riksdag-regering","tools":["get_sync_status"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -33,8 +33,8 @@ # - ../prompts/07-commit-and-pr.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -44,22 +44,21 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # - ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 name: "News: Translate Executive Briefs" on: @@ -109,6 +108,14 @@ concurrency: run-name: "News: Translate Executive Briefs" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-translate + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Translate%20Executive%20Briefs,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -122,6 +129,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -135,7 +143,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -143,35 +151,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: "claude-sonnet-4.6" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -198,9 +212,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -218,15 +234,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -236,20 +253,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -258,142 +273,104 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_5a366823994d6e48_EOF' - - GH_AW_PROMPT_5a366823994d6e48_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_5a366823994d6e48_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_5a366823994d6e48_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_5a366823994d6e48_EOF' - - GH_AW_PROMPT_5a366823994d6e48_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_5a366823994d6e48_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_5a366823994d6e48_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_5a366823994d6e48_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/workflows/news-translate.md}} - GH_AW_PROMPT_5a366823994d6e48_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/workflows/news-translate.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -404,27 +381,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -457,12 +441,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}-${{ inputs.article_date || 'batch' }}-${{ inputs.subfolder || 'all' }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newstranslate outputs: @@ -478,7 +469,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -486,11 +480,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -499,17 +494,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -593,16 +595,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -611,13 +616,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -629,15 +636,26 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 - - name: Generate Safe Outputs Config + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_65507d729af76774_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","translation","executive-brief"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_65507d729af76774_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"translation\",\"executive-brief\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -660,9 +678,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -670,6 +697,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -693,6 +730,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -706,6 +749,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -791,9 +846,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -802,6 +859,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -809,6 +867,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -820,22 +883,29 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_09349dd0b1342339_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_c0156fc22aee61ea_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -861,7 +931,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -883,6 +953,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -894,7 +972,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -904,10 +982,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_09349dd0b1342339_EOF + GH_AW_MCP_CONFIG_c0156fc22aee61ea_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -918,9 +1001,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -936,17 +1021,30 @@ jobs: run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":2500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":2500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -964,8 +1062,13 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE @@ -980,7 +1083,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1001,7 +1104,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1026,9 +1140,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1052,14 +1168,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1069,9 +1187,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1079,9 +1199,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1095,9 +1217,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1105,10 +1229,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1134,6 +1271,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1150,6 +1299,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1170,9 +1321,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1190,7 +1342,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1199,15 +1351,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1215,42 +1368,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1264,6 +1404,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1286,9 +1428,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1318,7 +1462,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-translate.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1326,9 +1470,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1343,9 +1489,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1358,9 +1506,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1373,9 +1523,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1402,6 +1554,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1422,9 +1578,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Translate Executive Briefs" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-translate.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1436,6 +1613,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1446,7 +1624,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1455,15 +1633,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1471,7 +1656,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1483,7 +1670,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1507,21 +1694,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1529,82 +1702,52 @@ jobs: WORKFLOW_NAME: "News: Translate Executive Briefs" WORKFLOW_DESCRIPTION: "Translates `analysis/daily/**/executive-brief.md` (English source produced by per-type news workflows) into the 13 non-English target languages as sibling `executive-brief_.md` files. Runs three times daily and picks up at most `max_briefs` (default 1) sources × `max_langs` (default 13) languages per run, **greenfield-first** — sources with one or more missing target files always win batch slots over drift-only sources, and within a source the still-needed languages are translated missing-first then drift up to `max_langs` (remaining languages drain in later runs). Pass 2 is **validator-first**: the bash validator does all structural parity at near-zero model-token cost and the agent only reads back the files it flags. This workflow only uses bash/edit/safe-outputs — its MCP/tool surface is deliberately minimal so the per-turn tool-schema context (the ~3.5× weighting driver that aborted run #26641603577 at 27.0M / 25M weighted) no longer dominates; wall-clock (Timer A/B) and the 200-file safe-outputs cap, not the token budget, are now the governing limits — see `07-commit-and-pr.md §Deadline enforcement`. See `TRANSLATION_GUIDE.md §Executive Brief Markdown Translations` for the authoritative content contract." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} COPILOT_MODEL: claude-sonnet-4.6 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1620,58 +1763,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Translate Executive Briefs" + WORKFLOW_DESCRIPTION: "Translates `analysis/daily/**/executive-brief.md` (English source produced by per-type news workflows) into the 13 non-English target languages as sibling `executive-brief_.md` files. Runs three times daily and picks up at most `max_briefs` (default 1) sources × `max_langs` (default 13) languages per run, **greenfield-first** — sources with one or more missing target files always win batch slots over drift-only sources, and within a source the still-needed languages are translated missing-first then drift up to `max_langs` (remaining languages drain in later runs). Pass 2 is **validator-first**: the bash validator does all structural parity at near-zero model-token cost and the agent only reads back the files it flags. This workflow only uses bash/edit/safe-outputs — its MCP/tool surface is deliberately minimal so the per-turn tool-schema context (the ~3.5× weighting driver that aborted run #26641603577 at 27.0M / 25M weighted) no longer dominates; wall-clock (Timer A/B) and the 200-file safe-outputs cap, not the token budget, are now the governing limits — see `07-commit-and-pr.md §Deadline enforcement`. See `TRANSLATION_GUIDE.md §Executive Brief Markdown Translations` for the authoritative content contract." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1695,7 +1882,6 @@ jobs: GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" GH_AW_ENGINE_MODEL: "claude-sonnet-4.6" - GH_AW_ENGINE_VERSION: "1.0.73" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-translate" @@ -1710,12 +1896,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1724,15 +1918,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1740,7 +1937,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1776,17 +1975,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"translation\",\"executive-brief\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"translation\",\"executive-brief\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1796,6 +1997,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1813,7 +2015,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1822,8 +2024,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Translate Executive Briefs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-translate.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-week-ahead.lock.yml b/.github/workflows/news-week-ahead.lock.yml index c25ae28345b..141c0b7b92a 100644 --- a/.github/workflows/news-week-ahead.lock.yml +++ b/.github/workflows/news-week-ahead.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"7399314a36909c5cb6451caefc83bc4df2269f7339ab2de30355ebf727b12639","body_hash":"ad011bfaecb4a6bd8911879ca820de2b1d0481d9299a9504703320531c96c619","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f48b7d52e0e7c48fdb20e02a5d9cba7749a3f98bbcab2b614ebca35a89c4492e","body_hash":"ad011bfaecb4a6bd8911879ca820de2b1d0481d9299a9504703320531c96c619","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -39,8 +39,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -50,23 +50,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Week Ahead" @@ -101,6 +100,14 @@ concurrency: run-name: "News: Week Ahead" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-week-ahead + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Week%20Ahead,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -114,6 +121,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -127,7 +135,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -135,35 +143,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Week Ahead" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -190,9 +204,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -210,15 +226,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -228,20 +245,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -250,148 +265,110 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0015\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF' - - GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF' - - GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}} - {{#runtime-import .github/workflows/news-week-ahead.md}} - GH_AW_PROMPT_bcbd1fd99fcd99a6_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}}\n" + GH_AW_PROMPT_CONTENT_0015: "{{#runtime-import .github/workflows/news-week-ahead.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -402,27 +379,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -455,12 +439,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsweekahead outputs: @@ -476,7 +467,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -484,11 +478,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -497,17 +492,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -574,16 +576,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -592,13 +597,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -610,44 +617,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -670,9 +667,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -680,6 +686,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -703,6 +719,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -716,6 +738,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -801,9 +835,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -812,6 +848,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -819,6 +856,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -830,17 +872,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -861,13 +910,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -893,7 +942,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -915,6 +964,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -926,7 +983,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -948,7 +1005,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -968,7 +1025,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -978,10 +1035,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -992,9 +1054,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1006,21 +1070,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1038,14 +1126,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1054,7 +1147,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1075,7 +1168,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1100,9 +1204,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1126,14 +1232,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1143,9 +1251,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1153,9 +1263,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1169,9 +1281,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1179,10 +1293,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1208,6 +1335,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1224,6 +1363,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1244,9 +1385,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1264,7 +1406,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1273,15 +1415,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1289,42 +1432,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1338,6 +1468,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1360,9 +1492,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1392,7 +1526,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-week-ahead.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1400,9 +1534,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1417,9 +1553,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1432,9 +1570,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1447,9 +1587,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1476,6 +1618,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1496,9 +1642,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Week Ahead" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-week-ahead.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1510,6 +1677,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1520,7 +1688,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1529,15 +1697,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1545,7 +1720,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1557,7 +1734,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1581,21 +1758,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1603,82 +1766,52 @@ jobs: WORKFLOW_NAME: "News: Week Ahead" WORKFLOW_DESCRIPTION: "Generates week-ahead prospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs Fridays to preview the upcoming parliamentary week." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1694,58 +1827,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Week Ahead" + WORKFLOW_DESCRIPTION: "Generates week-ahead prospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs Fridays to preview the upcoming parliamentary week." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1768,8 +1945,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-week-ahead" @@ -1784,12 +1960,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1798,15 +1982,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1814,7 +2001,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1850,17 +2039,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1870,6 +2061,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1887,7 +2079,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1896,8 +2088,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Week Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-week-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-week-ahead.md b/.github/workflows/news-week-ahead.md index e6577c0736d..f5019f6775a 100644 --- a/.github/workflows/news-week-ahead.md +++ b/.github/workflows/news-week-ahead.md @@ -289,7 +289,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-weekly-review.lock.yml b/.github/workflows/news-weekly-review.lock.yml index caa2ef8f1aa..8d7acd30525 100644 --- a/.github/workflows/news-weekly-review.lock.yml +++ b/.github/workflows/news-weekly-review.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9409292b772e4060e81018a57104006eca7508daf0bc78a2dbe93e9802866e83","body_hash":"fcea919aec54e64a5c6b0d1f3738fb426df99bf63e2cbb6b2fc33094ad82fc3a","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"1683592d249234a8fe645ece3b8c4a7c0fb48acd3a1262ea47f3ad26a76e025b","body_hash":"fcea919aec54e64a5c6b0d1f3738fb426df99bf63e2cbb6b2fc33094ad82fc3a","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -38,8 +38,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -49,23 +49,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Weekly Review" @@ -100,6 +99,14 @@ concurrency: run-name: "News: Weekly Review" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-weekly-review + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Weekly%20Review,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -113,6 +120,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -126,7 +134,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -134,35 +142,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Weekly Review" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -189,9 +203,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -209,15 +225,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -227,20 +244,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -249,147 +264,109 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_f187758a69818088_EOF' - - GH_AW_PROMPT_f187758a69818088_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_f187758a69818088_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_f187758a69818088_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_f187758a69818088_EOF' - - GH_AW_PROMPT_f187758a69818088_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_f187758a69818088_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_f187758a69818088_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_f187758a69818088_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/workflows/news-weekly-review.md}} - GH_AW_PROMPT_f187758a69818088_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/workflows/news-weekly-review.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -400,27 +377,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -453,12 +437,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsweeklyreview outputs: @@ -474,7 +465,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -482,11 +476,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -495,17 +490,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -572,16 +574,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -590,13 +595,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -608,44 +615,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_b8062c645dde2c0f_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -668,9 +665,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -678,6 +684,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -701,6 +717,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -714,6 +736,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -799,9 +833,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -810,6 +846,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -817,6 +854,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -828,17 +870,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -859,13 +908,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -891,7 +940,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -913,6 +962,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -924,7 +981,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -946,7 +1003,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -966,7 +1023,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -976,10 +1033,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -990,9 +1052,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1004,21 +1068,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1036,14 +1124,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1052,7 +1145,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1073,7 +1166,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1098,9 +1202,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1124,14 +1230,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1141,9 +1249,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1151,9 +1261,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1167,9 +1279,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1177,10 +1291,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1206,6 +1333,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1222,6 +1361,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1242,9 +1383,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1262,7 +1404,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1271,15 +1413,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1287,42 +1430,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1336,6 +1466,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1358,9 +1490,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1390,7 +1524,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-weekly-review.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1398,9 +1532,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1415,9 +1551,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1430,9 +1568,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1445,9 +1585,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1474,6 +1616,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1494,9 +1640,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Weekly Review" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-weekly-review.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1508,6 +1675,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1518,7 +1686,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1527,15 +1695,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1543,7 +1718,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1555,7 +1732,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1579,21 +1756,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1601,82 +1764,52 @@ jobs: WORKFLOW_NAME: "News: Weekly Review" WORKFLOW_DESCRIPTION: "Generates weekly review retrospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs Saturdays to review the past week." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1692,58 +1825,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Weekly Review" + WORKFLOW_DESCRIPTION: "Generates weekly review retrospective articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Runs Saturdays to review the past week." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1766,8 +1943,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-weekly-review" @@ -1782,12 +1958,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1796,15 +1980,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1812,7 +1999,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1848,17 +2037,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1868,6 +2059,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1885,7 +2077,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1894,8 +2086,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Weekly Review" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-weekly-review.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-weekly-review.md b/.github/workflows/news-weekly-review.md index 358237c6634..e76bf0499c6 100644 --- a/.github/workflows/news-weekly-review.md +++ b/.github/workflows/news-weekly-review.md @@ -288,7 +288,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: deep -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- diff --git a/.github/workflows/news-year-ahead.lock.yml b/.github/workflows/news-year-ahead.lock.yml index e7c28e3cffa..d8a3954a636 100644 --- a/.github/workflows/news-year-ahead.lock.yml +++ b/.github/workflows/news-year-ahead.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e99f7a326a74ae1a10ab6ad23bab70dbb0f390c43aa1d1a6759987b14b659d08","body_hash":"91177cc54b60a9cad4d483c9e3b290ad9dc817d1f1710de57b58c3da7e758b39","compiler_version":"v0.83.1","agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.73"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"},{"repo":"github/gh-aw-actions/setup-cli","sha":"8bdba8075360648fe6802302a5b4e016361dc6ac","version":"v0.83.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38","digest":"sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38","digest":"sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38","digest":"sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.3","digest":"sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.6.0","digest":"sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3","pinned_image":"ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}]} -# This file was automatically generated by gh-aw (v0.83.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e08490f746aef3b2409c7895d21355755c543d7d75a5203612373cbb7f6d16f2","body_hash":"45ed6104d881dd559944a0bc57b2f290e67fe3565727dd31aecee865aca485ad","compiler_version":"v0.87.9","agent_id":"copilot","agent_model":"claude-opus-5","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-manifest: {"version":1,"secrets":["GH_AW_CI_TRIGGER_TOKEN","GH_AW_DEFAULT_OTLP_HEADERS","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN","IMF_SDMX_SUBSCRIPTION_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"},{"repo":"github/gh-aw-actions/setup-cli","sha":"49dc896ccb7d6d975514cfe232bcbd68cc12e2c1","version":"v0.87.9"}],"containers":[{"image":"alpine:latest","digest":"sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b","pinned_image":"alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9","digest":"sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9","digest":"sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9","digest":"sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.13","digest":"sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.11.0","digest":"sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699","pinned_image":"ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699"},{"image":"node:26-alpine","digest":"sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9","pinned_image":"node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"github","tools":["actions_get","actions_list","get_code_scanning_alert","get_commit","get_discussion","get_discussion_comments","get_file_contents","get_job_logs","get_label","get_latest_release","get_me","get_notification_details","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_secret_scanning_alert","get_tag","issue_read","list_branches","list_code_scanning_alerts","list_commits","list_discussion_categories","list_discussions","list_issue_types","list_issues","list_label","list_notifications","list_pull_requests","list_releases","list_secret_scanning_alerts","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_orgs","search_pull_requests","search_repositories","search_users"]},{"name":"riksdag-regering","tools":["*"]},{"name":"safeoutputs","tools":["add_comment","create_pull_request","missing_data","missing_tool","noop"]},{"name":"scb","tools":["*"]},{"name":"world-bank","tools":["*"]}]} +# This file was automatically generated by gh-aw (v0.87.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -39,8 +39,8 @@ # - ../prompts/ext/tier-c-aggregation.md # # Secrets used: -# - COPILOT_GITHUB_TOKEN # - GH_AW_CI_TRIGGER_TOKEN +# - GH_AW_DEFAULT_OTLP_HEADERS # - GH_AW_GITHUB_MCP_SERVER_TOKEN # - GH_AW_GITHUB_TOKEN # - GITHUB_TOKEN @@ -50,23 +50,22 @@ # - actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 # - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -# - actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 -# - github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 +# - github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 +# - github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 # # Container images used: # - alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b -# - ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c -# - ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 -# - ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 -# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b -# - ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 +# - ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa +# - ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc +# - ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 +# - ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 # - node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 name: "News: Year Ahead" @@ -101,6 +100,14 @@ concurrency: run-name: "News: Year Ahead" +env: + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }} + OTEL_SERVICE_NAME: gh-aw.news-year-ahead + OTEL_RESOURCE_ATTRIBUTES: 'gh-aw.workflow.name=News%3A%20Year%20Ahead,gh-aw.repository=${{ github.repository }},gh-aw.run.id=${{ github.run_id }},github.run_id=${{ github.run_id }},gh-aw.engine.id=copilot' + OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }} + GH_AW_OTLP_ENDPOINTS: '[{"url":"${{ vars.GH_AW_DEFAULT_OTLP_ENDPOINT }}","headers":"${{ secrets.GH_AW_DEFAULT_OTLP_HEADERS }}"}]' + GH_AW_OTLP_IF_MISSING: ignore + jobs: activation: runs-on: ubuntu-slim @@ -114,6 +121,7 @@ jobs: comment_id: "" comment_repo: "" daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }} + daily_ai_credits_guardrail_status: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_guardrail_status || '' }} daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }} daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }} engine_id: ${{ steps.generate_aw_info.outputs.engine_id }} @@ -127,7 +135,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -135,35 +143,41 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Generate agentic run info id: generate_aw_info env: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: "claude-opus-4.8" - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AGENT_VERSION: "1.0.73" - GH_AW_INFO_CLI_VERSION: "v0.83.1" + GH_AW_INFO_MODEL: "claude-opus-5" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AGENT_VERSION: "1.0.80" + GH_AW_INFO_CLI_VERSION: "v0.87.9" GH_AW_INFO_WORKFLOW_NAME: "News: Year Ahead" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["node","playwright","github","defaults","containers","riksdag-regering-ai.onrender.com","data.riksdagen.se","www.riksdagen.se","riksdagen.se","www.regeringen.se","regeringen.se","www.government.se","g0v.se","api.scb.se","www.scb.se","scb-mcp.onrender.com","api.imf.org","data.imf.org","www.imf.org","dataservices.imf.org","datamarketplace.imf.org","api.worldbank.org","data.worldbank.org","datahelpdesk.worldbank.org","governance.worldbank.org","www.worldbank.org","www.europarl.europa.eu","europarl.europa.eu","ec.europa.eu","eur-lex.europa.eu","data.europa.eu","www.consilium.europa.eu","digital-strategy.ec.europa.eu","economy-finance.ec.europa.eu","www.enisa.europa.eu","www.statskontoret.se","statskontoret.se","www.lagradet.se","lagradet.se","www.riksbank.se","www.riksrevisionen.se","www.konj.se","www.finanspolitiskaradet.se","www.regelradet.se","www.esv.se","www.ei.se","www.energimyndigheten.se","www.naturvardsverket.se","www.boverket.se","www.do.se","www.domstol.se","www.imy.se","www.konkurrensverket.se","www.kriminalvarden.se","www.migrationsverket.se","www.msb.se","www.av.se","www.svt.se","www.val.se","bra.se","hack23.com","www.hack23.com","hack23.github.io","riksdagsmonitor.com","www.riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","euparliamentmonitor.com","www.euparliamentmonitor.com","ciacompliancemanager.com","www.ciacompliancemanager.com","blacktrigram.com","www.blacktrigram.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" + GH_AW_INFO_AGENT_RUNTIME: "" + GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_COMPILED_STRICT: "false" GH_AW_INFO_FEATURES: '{"mcp-gateway":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); + const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - name: Enforce strict mode policy if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} @@ -190,9 +204,11 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs'); + const { main } = require(path.join(actionsDir, 'restore_aic_usage_cache_fallback.cjs')); await main(); - name: Check daily workflow token guardrail id: daily-effective-workflow-guardrail @@ -210,15 +226,16 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs'); + const { main } = require(path.join(actionsDir, 'check_daily_aic_workflow_guardrail.cjs')); await main(); - name: Check for OAuth tokens id: check-oauth-tokens run: bash "${RUNNER_TEMP}/gh-aw/actions/check_oauth_tokens.sh" env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }} GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} - name: Checkout .github and .agents folders @@ -228,20 +245,18 @@ jobs: sparse-checkout: | .github .agents - .antigravity .claude .codex .gemini - .opencode .pi sparse-checkout-cone-mode: true fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file id: check-lock-file uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -250,148 +265,110 @@ jobs: GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); + const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.83.1" + GH_AW_COMPILED_VERSION: "v0.87.9" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs'); + const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" - name: Create prompt with built-in context + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_ACTIONS_DIR: ${{ runner.temp }}/gh-aw/actions + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl + GH_AW_PROMPT_CONFIG: "{\"items\":[{\"content_env\":\"GH_AW_PROMPT_CONTENT_0000\"},{\"file\":\"xpia.md\"},{\"file\":\"temp_folder_prompt.md\"},{\"file\":\"markdown.md\"},{\"file\":\"cache_memory_prompt.md\"},{\"file\":\"safe_outputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0001\"},{\"file\":\"safe_outputs_create_pull_request.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0002\"},{\"file\":\"mcp_cli_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0003\"},{\"file\":\"github_mcp_tools_with_safeoutputs_prompt.md\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0004\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0005\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0006\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0007\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0008\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0009\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0010\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0011\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0012\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0013\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0014\"},{\"content_env\":\"GH_AW_PROMPT_CONTENT_0015\"}]}" GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - # poutine:ignore untrusted_checkout_exec - run: | - bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" - { - cat << 'GH_AW_PROMPT_cfc29317dd4ba0d9_EOF' - - GH_AW_PROMPT_cfc29317dd4ba0d9_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_cfc29317dd4ba0d9_EOF' - - Tools: add_comment, create_pull_request, missing_tool, missing_data, noop - GH_AW_PROMPT_cfc29317dd4ba0d9_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_cfc29317dd4ba0d9_EOF' - - GH_AW_PROMPT_cfc29317dd4ba0d9_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_cfc29317dd4ba0d9_EOF' - - The following GitHub context information is available for this workflow: - {{#if github.actor}} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if github.repository}} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if github.workspace}} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}} - - **issue-number**: #__GH_AW_EXPR_802A9F6A__ - {{/if}} - {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}} - - **discussion-number**: #__GH_AW_EXPR_1A3A194A__ - {{/if}} - {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}} - - **pull-request-number**: #__GH_AW_EXPR_463A214A__ - {{/if}} - {{#if github.event.comment.id || github.aw.context.comment_id}} - - **comment-id**: __GH_AW_EXPR_FF1D34CE__ - {{/if}} - {{#if github.run_id}} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - **checkouts**: The following repositories have been checked out and are available in the workspace: - - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1] - - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches). - - **Warning: No git credentials are available to the agent.** Credentials are - intentionally removed after the checkout step for security. This means any git - operation that needs to authenticate to the remote will fail. In private repositories, that includes: - - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools) - - Checking out or switching to a remote branch that is not already fetched - - Deepening a shallow clone (`git fetch --unshallow`) - - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout) - Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` — - authentication will not succeed. If you encounter credential prompts or authentication errors, - stop immediately and report the limitation rather than spending turns trying to work around it. - - - GH_AW_PROMPT_cfc29317dd4ba0d9_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_cfc29317dd4ba0d9_EOF' - - {{#runtime-import .github/prompts/00-base-contract.md}} - {{#runtime-import .github/prompts/01-bash-and-shell-safety.md}} - {{#runtime-import .github/prompts/02-mcp-access.md}} - {{#runtime-import .github/prompts/03-data-download.md}} - {{#runtime-import .github/prompts/04-analysis-pipeline.md}} - {{#runtime-import .github/prompts/05-analysis-gate.md}} - {{#runtime-import .github/prompts/06-article-generation.md}} - {{#runtime-import .github/prompts/07-commit-and-pr.md}} - {{#runtime-import .github/prompts/ext/tier-c-aggregation.md}} - {{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}} - {{#runtime-import .github/workflows/news-year-ahead.md}} - GH_AW_PROMPT_cfc29317dd4ba0d9_EOF - } > "$GH_AW_PROMPT" + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} + GH_AW_PROMPT_CONTENT_0000: "\n" + GH_AW_PROMPT_CONTENT_0001: "\nTools: add_comment, create_pull_request, missing_tool, missing_data, noop\n" + GH_AW_PROMPT_CONTENT_0002: "\n" + GH_AW_PROMPT_CONTENT_0003: "\nThe following GitHub context information is available for this workflow:\n{{#if github.actor}}\n- **actor**: __GH_AW_GITHUB_ACTOR__\n{{/if}}\n{{#if github.repository}}\n- **repository**: __GH_AW_GITHUB_REPOSITORY__\n{{/if}}\n{{#if github.workspace}}\n- **workspace**: __GH_AW_GITHUB_WORKSPACE__\n{{/if}}\n{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}\n- **issue-number**: #__GH_AW_EXPR_802A9F6A__\n{{/if}}\n{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}\n- **discussion-number**: #__GH_AW_EXPR_1A3A194A__\n{{/if}}\n{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}\n- **pull-request-number**: #__GH_AW_EXPR_463A214A__\n{{/if}}\n{{#if github.event.comment.id || github.aw.context.comment_id}}\n- **comment-id**: __GH_AW_EXPR_FF1D34CE__\n{{/if}}\n{{#if github.run_id}}\n- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__\n{{/if}}\n- **checkouts**: The following repositories have been checked out and are available in the workspace:\n - repo `__GH_AW_GITHUB_REPOSITORY__` → `$GITHUB_WORKSPACE` (cwd) [shallow clone, fetch-depth=1]\n - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: [\"refs/pulls/open/*\"]` for all open PR refs, or `fetch: [\"main\", \"feature/my-branch\"]` for specific branches).\n - **Warning: No git credentials are available to the agent.** Credentials are\n intentionally removed after the checkout step for security. This means any git\n operation that needs to authenticate to the remote will fail. In private repositories, that includes:\n - `git fetch`, `git pull`, `git clone`, and `git push` (direct push, not via safe-output tools)\n - Checking out or switching to a remote branch that is not already fetched\n - Deepening a shallow clone (`git fetch --unshallow`)\n - On-demand blob fetches in partial/blobless clones (operations on files not in the initial checkout)\n Do NOT attempt to configure credentials, run `git credential fill`, or modify `.gitconfig` —\n authentication will not succeed. If you encounter credential prompts or authentication errors,\n stop immediately and report the limitation rather than spending turns trying to work around it.\n\n\n" + GH_AW_PROMPT_CONTENT_0004: "\n" + GH_AW_PROMPT_CONTENT_0005: "{{#runtime-import .github/prompts/00-base-contract.md}}\n" + GH_AW_PROMPT_CONTENT_0006: "{{#runtime-import .github/prompts/01-bash-and-shell-safety.md}}\n" + GH_AW_PROMPT_CONTENT_0007: "{{#runtime-import .github/prompts/02-mcp-access.md}}\n" + GH_AW_PROMPT_CONTENT_0008: "{{#runtime-import .github/prompts/03-data-download.md}}\n" + GH_AW_PROMPT_CONTENT_0009: "{{#runtime-import .github/prompts/04-analysis-pipeline.md}}\n" + GH_AW_PROMPT_CONTENT_0010: "{{#runtime-import .github/prompts/05-analysis-gate.md}}\n" + GH_AW_PROMPT_CONTENT_0011: "{{#runtime-import .github/prompts/06-article-generation.md}}\n" + GH_AW_PROMPT_CONTENT_0012: "{{#runtime-import .github/prompts/07-commit-and-pr.md}}\n" + GH_AW_PROMPT_CONTENT_0013: "{{#runtime-import .github/prompts/ext/tier-c-aggregation.md}}\n" + GH_AW_PROMPT_CONTENT_0014: "{{#runtime-import .github/prompts/ext/long-horizon-forecasting.md}}\n" + GH_AW_PROMPT_CONTENT_0015: "{{#runtime-import .github/workflows/news-year-ahead.md}}\n" + with: + script: | + const { setupGlobals } = require(process.env.GH_AW_ACTIONS_DIR + '/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(process.env.GH_AW_ACTIONS_DIR + '/create_prompt.cjs'); + await main(core); - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ENGINE_ID: "copilot" + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); + const { main } = require(path.join(actionsDir, 'interpolate_prompt.cjs')); await main(); - name: Substitute placeholders uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt GH_AW_ALLOWED_EXTENSIONS: '' GH_AW_CACHE_DESCRIPTION: '' GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} + GH_AW_EXPR_4EA6A7D6: ${{ inputs.article_date || 'today' }} GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }} GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }} GH_AW_GITHUB_ACTOR: ${{ github.actor }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} + GH_AW_GITHUB_WORKFLOW: ${{ github.workflow }} GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} + GH_AW_INPUTS_ARTICLE_DATE: ${{ inputs.article_date }} GH_AW_MCP_CLI_SERVERS_LIST: "- `github` — run `github --help` to see available tools\n- `riksdag-regering` — run `riksdag-regering --help` to see available tools\n- `safeoutputs` — run `safeoutputs --help` to see available tools\n- `scb` — run `scb --help` to see available tools\n- `world-bank` — run `world-bank --help` to see available tools" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); + const substitutePlaceholders = require(path.join(actionsDir, 'substitute_placeholders.cjs')); // Call the substitution function return await substitutePlaceholders({ @@ -402,27 +379,34 @@ jobs: GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A, GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A, + GH_AW_EXPR_4EA6A7D6: process.env.GH_AW_EXPR_4EA6A7D6, GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A, GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE, GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY, GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID, + GH_AW_GITHUB_WORKFLOW: process.env.GH_AW_GITHUB_WORKFLOW, GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, + GH_AW_INPUTS_ARTICLE_DATE: process.env.GH_AW_INPUTS_ARTICLE_DATE, GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST } }); - name: Validate prompt placeholders env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh" - name: Print prompt env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - # poutine:ignore untrusted_checkout_exec - run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + GH_AW_PROMPT: ${{ runner.temp }}/gh-aw/aw-prompts/prompt.txt + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh" + - name: Stage prompt files for artifact upload + run: | + mkdir -p /tmp/gh-aw/aw-prompts + cp -a "${RUNNER_TEMP}/gh-aw/aw-prompts/." /tmp/gh-aw/aw-prompts/ - name: Upload activation artifact - if: success() + if: success() || failure() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: activation @@ -455,12 +439,19 @@ jobs: concurrency: group: "gh-aw-copilot-${{ github.workflow }}" queue: max + timeout-minutes: 60 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GH_AW_ASSETS_ALLOWED_EXTS: "" GH_AW_ASSETS_BRANCH: "" GH_AW_ASSETS_MAX_SIZE_KB: 0 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs + GH_AW_PR_HEAD_BASE_BRANCH: "" + GH_AW_PR_HEAD_BASE_PR_NUMBER: "" + GH_AW_PR_HEAD_BASE_REF: "" + GH_AW_PR_HEAD_BASE_REPO: "" + GH_AW_PR_HEAD_BASE_SHA: "" + GH_AW_PR_HEAD_REPO: "" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_WORKFLOW_ID_SANITIZED: newsyearahead outputs: @@ -476,7 +467,10 @@ jobs: http_400_response_error: ${{ steps.detect-agent-errors.outputs.http_400_response_error || 'false' }} inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }} invocation_cap_exceeded: ${{ steps.detect-agent-errors.outputs.invocation_cap_exceeded || 'false' }} + max_cache_misses_exceeded: ${{ steps.detect-agent-errors.outputs.max_cache_misses_exceeded || 'false' }} mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }} + missing_model_pricing_error: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_error || 'false' }} + missing_model_pricing_model_name: ${{ steps.detect-agent-errors.outputs.missing_model_pricing_model_name || '' }} model: ${{ needs.activation.outputs.model }} model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }} output: ${{ steps.collect_output.outputs.output }} @@ -484,11 +478,12 @@ jobs: setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} + shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -497,17 +492,24 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths run: | + if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then + echo "RUNNER_TOOL_CACHE=${{ runner.tool_cache }}" >> "$GITHUB_ENV" + fi { echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" } >> "$GITHUB_OUTPUT" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" + - name: Check OTLP telemetry configuration + run: bash "${RUNNER_TEMP}/gh-aw/actions/check_otlp_default_credentials.sh" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: @@ -574,16 +576,19 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); + const { main } = require(path.join(actionsDir, 'checkout_pr_branch.cjs')); await main(); - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com + GH_AW_COMPILED_VERSION: v0.87.9 - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -592,13 +597,15 @@ jobs: GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }} with: script: | - const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const determineAutomaticLockdown = require(path.join(actionsDir, 'determine_automatic_lockdown.cjs')); await determineAutomaticLockdown(github, context, core); - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: "AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .github" + GH_AW_AGENT_FILES: "AGENTS.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: @@ -610,44 +617,34 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 ghcr.io/github/gh-aw-mcpg:v0.4.3@sha256:3c744710ea275cd5ee65db92a1099e0d980754bd9fafda9ce67704c67004dc83 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.6.0@sha256:2b0c48b070f61e9d3969269ead600f62d00fb237b60ac849ef3d166ee7de9ad3 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa ghcr.io/github/gh-aw-mcpg:v0.4.13@sha256:ec4008521c610e1113ed557ecec0ff64a2c2111e4cfa817bab54d9b7da24c7cc ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748 ghcr.io/github/github-mcp-server:v1.11.0@sha256:fbec75de11c255213fa08d80fb166abe73d851fff631c51c0079872967720699 node:26-alpine@sha256:725aeba2364a9b16beae49e180d83bd597dbd0b15c47f1f28875c290bfd255b9 - name: Install gh-aw extension - uses: github/gh-aw-actions/setup-cli@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup-cli@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: - version: 'v0.83.1' + version: 'v0.87.9' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - name: Copy gh-aw binary for MCP server + - name: Copy gh-aw binary for MCP Server run: | - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p "${RUNNER_TEMP}/gh-aw" - GH_AW_BIN="" - GH_AW_BIN=$(command -v gh-aw 2>/dev/null) || true - if [ -z "$GH_AW_BIN" ]; then - GH_AW_BIN=$(find "${HOME}/.local/share/gh/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -n "${GH_CONFIG_DIR:-}" ]; then - GH_AW_BIN=$(find "${GH_CONFIG_DIR}/extensions/gh-aw" -name 'gh-aw' -type f 2>/dev/null | head -1) || true - fi - if [ -z "$GH_AW_BIN" ] && [ -f "${GITHUB_WORKSPACE}/gh-aw" ]; then - GH_AW_BIN="${GITHUB_WORKSPACE}/gh-aw" - fi - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" "${RUNNER_TEMP}/gh-aw/gh-aw" - chmod +x "${RUNNER_TEMP}/gh-aw/gh-aw" - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Generate Safe Outputs Config + bash "${RUNNER_TEMP}/gh-aw/actions/copy_gh_aw_binary_for_mcp.sh" + - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_69bd3c4be5dd994b_EOF' - {"add_comment":{"max":1},"create_pull_request":{"draft":false,"expires":336,"fallback_as_issue":true,"if_no_changes":"warn","labels":["agentic-news","analysis-data","long-horizon","forward-look","year-ahead"],"max":1,"max_patch_files":100,"max_patch_size":10240,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"allowed"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_69bd3c4be5dd994b_EOF + - name: Generate Safe Outputs Config + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_FILE_ROOT: "${{ runner.temp }}/gh-aw" + GH_AW_FILE_CONFIG: "{\"files\":[{\"path\":\"safeoutputs/config.json\",\"content_env\":\"GH_AW_SAFE_OUTPUTS_CONFIG\"}]}" + GH_AW_SAFE_OUTPUTS_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"year-ahead\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'create_files.cjs')); + await main(); - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -670,9 +667,18 @@ jobs: "sanitize": true, "maxLength": 65000 }, + "comment_id": { + "optionalPositiveInteger": true + }, "item_number": { "issueOrPRNumber": true }, + "pr": { + "issueOrPRNumber": true + }, + "pr_number": { + "issueOrPRNumber": true + }, "reply_to_id": { "type": "string", "maxLength": 256 @@ -680,6 +686,16 @@ jobs: "repo": { "type": "string", "maxLength": 256 + }, + "target": { + "type": "string", + "enum": [ + "status" + ] + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" } } }, @@ -703,6 +719,12 @@ jobs: "sanitize": true, "maxLength": 256 }, + "dependencies": { + "type": "array", + "itemType": "string", + "itemSanitize": true, + "itemMaxLength": 256 + }, "draft": { "type": "boolean" }, @@ -716,6 +738,18 @@ jobs: "type": "string", "maxLength": 256 }, + "stack_position": { + "optionalPositiveInteger": true + }, + "stack_root": { + "type": "string", + "sanitize": true, + "maxLength": 256 + }, + "temporary_id": { + "type": "string", + "pattern": "^#?aw_[A-Za-z0-9_]{3,12}$" + }, "title": { "required": true, "type": "string", @@ -801,9 +835,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs'); + const { main } = require(path.join(actionsDir, 'generate_safe_outputs_tools.cjs')); await main(); - name: Start MCP Gateway id: start-mcp-gateway @@ -812,6 +848,7 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }} GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }} + GH_AW_SINK_VISIBILITY: ${{ steps.determine-automatic-lockdown.outputs.visibility }} GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }} GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} @@ -819,6 +856,11 @@ jobs: run: | set -eo pipefail mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config" + if [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -r "${GITHUB_EVENT_PATH}" ]; then + GH_AW_SAFEOUTPUTS_EVENT_PATH="${RUNNER_TEMP}/gh-aw/safeoutputs/github_event.json" + cp "${GITHUB_EVENT_PATH}" "${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + export GITHUB_EVENT_PATH="${GH_AW_SAFEOUTPUTS_EVENT_PATH}" + fi # Export gateway environment variables for MCP config and gateway script export MCP_GATEWAY_PORT="8080" @@ -830,17 +872,24 @@ jobs: export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" + export MCP_GATEWAY_ALLOWED_MOUNT_ROOTS="${GITHUB_WORKSPACE}:rw,${RUNNER_TEMP}/gh-aw:ro,${RUNNER_TEMP}/gh-aw/safeoutputs:rw,/opt:ro,/tmp:rw,/usr/bin/gh:ro" + export GH_AW_PR_HEAD_BASE_BRANCH="${GH_AW_PR_HEAD_BASE_BRANCH:-}" + export GH_AW_PR_HEAD_BASE_SHA="${GH_AW_PR_HEAD_BASE_SHA:-}" + export GH_AW_PR_HEAD_BASE_REPO="${GH_AW_PR_HEAD_BASE_REPO:-}" + export GH_AW_PR_HEAD_BASE_PR_NUMBER="${GH_AW_PR_HEAD_BASE_PR_NUMBER:-}" + export GH_AW_PR_HEAD_BASE_REF="${GH_AW_PR_HEAD_BASE_REF:-}" + export GH_AW_PR_HEAD_REPO="${GH_AW_PR_HEAD_REPO:-}" export DEBUG="*" export GH_AW_ENGINE="copilot" MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0') MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0') source "${RUNNER_TEMP}/gh-aw/actions/resolve_docker_socket_gid.sh" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.3' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network bridge -p 127.0.0.1:'"${MCP_GATEWAY_PORT}"':'"${MCP_GATEWAY_PORT}"' --name awmg-mcpg --add-host host.docker.internal:host-gateway --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_PR_HEAD_BASE_BRANCH -e GH_AW_PR_HEAD_BASE_SHA -e GH_AW_PR_HEAD_BASE_REPO -e GH_AW_PR_HEAD_BASE_PR_NUMBER -e GH_AW_PR_HEAD_BASE_REF -e GH_AW_PR_HEAD_REPO -e GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GH_AW_SINK_VISIBILITY -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -e RUNNER_TOOL_CACHE -e MCP_GATEWAY_ALLOWED_MOUNT_ROOTS -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.4.13' mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_f1ba411668f73441_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -861,13 +910,13 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, "github": { "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v1.6.0", + "container": "ghcr.io/github/github-mcp-server:v1.11.0", "env": { "GITHUB_FEATURES": "fields_param", "GITHUB_HOST": "${GITHUB_SERVER_URL}", @@ -893,7 +942,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -915,6 +964,14 @@ jobs: "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST": "\${GH_AW_POLICY_ALLOW_CREATE_PULL_REQUEST}", + "GH_AW_PR_HEAD_BASE_BRANCH": "\${GH_AW_PR_HEAD_BASE_BRANCH}", + "GH_AW_PR_HEAD_BASE_SHA": "\${GH_AW_PR_HEAD_BASE_SHA}", + "GH_AW_PR_HEAD_BASE_REPO": "\${GH_AW_PR_HEAD_BASE_REPO}", + "GH_AW_PR_HEAD_BASE_PR_NUMBER": "\${GH_AW_PR_HEAD_BASE_PR_NUMBER}", + "GH_AW_PR_HEAD_BASE_REF": "\${GH_AW_PR_HEAD_BASE_REF}", + "GH_AW_PR_HEAD_REPO": "\${GH_AW_PR_HEAD_REPO}", + "GITHUB_EVENT_NAME": "\${GITHUB_EVENT_NAME}", + "GITHUB_EVENT_PATH": "\${GITHUB_EVENT_PATH}", "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}", "GITHUB_SHA": "\${GITHUB_SHA}", "GITHUB_TOKEN": "\${GITHUB_TOKEN}", @@ -926,7 +983,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -948,7 +1005,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } }, @@ -968,7 +1025,7 @@ jobs: "accept": [ "*" ], - "sink-visibility": ${{ toJSON(steps.determine-automatic-lockdown.outputs.visibility) }} + "sink-visibility": "${GH_AW_SINK_VISIBILITY}" } } } @@ -978,10 +1035,15 @@ jobs: "domain": "${MCP_GATEWAY_DOMAIN}", "apiKey": "${MCP_GATEWAY_API_KEY}", "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", - "startupTimeout": 180 + "startupTimeout": 180, + "opentelemetry": { + "endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}", + "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", + "spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}" + } } } - GH_AW_MCP_CONFIG_f1ba411668f73441_EOF + GH_AW_MCP_CONFIG_1289a2d0a31de77b_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -992,9 +1054,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs'); + const { main } = require(path.join(actionsDir, 'mount_mcp_as_cli.cjs')); await main(); - name: Clean credentials continue-on-error: true @@ -1006,21 +1070,45 @@ jobs: - name: Execute GitHub Copilot CLI id: agentic_execution # Copilot CLI tool arguments (sorted): + # --allow-tool github + # --allow-tool riksdag-regering + # --allow-tool riksdag-regering(*) + # --allow-tool safeoutputs + # --allow-tool scb + # --allow-tool scb(*) + # --allow-tool shell + # --allow-tool web_fetch + # --allow-tool world-bank + # --allow-tool world-bank(*) + # --allow-tool write timeout-minutes: 60 run: | set -o pipefail printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT + trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"; if [ "$gh_aw_exit_code" -ne 0 ]; then echo "::error::Agent execution exited with code $gh_aw_exit_code"; fi' EXIT mkdir -p "$HOME/.copilot" printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" export XDG_CONFIG_HOME="$HOME" export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json" + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + touch /tmp/gh-aw/agent-step-summary.md GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) export GH_AW_NODE_BIN export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" (umask 177 && touch /tmp/gh-aw/agent-stdio.log) - printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.imf.org","api.individual.githubcopilot.com","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","host.docker.internal","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.enterprise.githubcopilot.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["fable","sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + # shellcheck disable=SC2016 + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json","network":{"allowDomains":["*.docker.com","*.docker.io","*.githubusercontent.com","api.imf.org","api.npms.io","api.scb.se","api.snapcraft.io","api.worldbank.org","archive.ubuntu.com","auth.docker.io","azure.archive.ubuntu.com","blacktrigram.com","bra.se","bun.sh","cdn.jsdelivr.net","cdn.playwright.dev","ciacompliancemanager.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","data.europa.eu","data.imf.org","data.riksdagen.se","data.worldbank.org","datahelpdesk.worldbank.org","datamarketplace.imf.org","dataservices.imf.org","deb.nodesource.com","deno.land","digital-strategy.ec.europa.eu","dl.k8s.io","docs.github.com","ec.europa.eu","economy-finance.ec.europa.eu","esm.sh","euparliamentmonitor.com","eur-lex.europa.eu","europarl.europa.eu","g0v.se","gcr.io","get.pnpm.io","ghcr.io","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","googleapis.deno.dev","googlechromelabs.github.io","governance.worldbank.org","hack23.com","hack23.github.io","json-schema.org","json.schemastore.org","jsr.io","keyserver.ubuntu.com","lagradet.se","lfs.github.com","mcr.microsoft.com","nodejs.org","npm.pkg.github.com","npmjs.com","npmjs.org","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","patch-diff.githubusercontent.com","patchdiff.githubusercontent.com","pkgs.k8s.io","playwright.download.prss.microsoft.com","ppa.launchpad.net","production.cloudflare.docker.com","quay.io","raw.githubusercontent.com","regeringen.se","registry.bower.io","registry.hub.docker.com","registry.npmjs.com","registry.npmjs.org","registry.yarnpkg.com","repo.yarnpkg.com","riksdag-regering-ai.onrender.com","riksdagen.se","riksdagsmonitor.com","riksdagsmonitor.hack23.com","riksdagsmonitor.pages.dev","s.symcb.com","s.symcd.com","scb-mcp.onrender.com","security.ubuntu.com","skimdb.npmjs.com","statskontoret.se","storage.googleapis.com","telemetry.vercel.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.av.se","www.blacktrigram.com","www.boverket.se","www.ciacompliancemanager.com","www.consilium.europa.eu","www.do.se","www.domstol.se","www.ei.se","www.energimyndigheten.se","www.enisa.europa.eu","www.esv.se","www.euparliamentmonitor.com","www.europarl.europa.eu","www.finanspolitiskaradet.se","www.googleapis.com","www.government.se","www.hack23.com","www.imf.org","www.imy.se","www.konj.se","www.konkurrensverket.se","www.kriminalvarden.se","www.lagradet.se","www.migrationsverket.se","www.msb.se","www.naturvardsverket.se","www.npmjs.com","www.npmjs.org","www.regelradet.se","www.regeringen.se","www.riksbank.se","www.riksdagen.se","www.riksdagsmonitor.com","www.riksrevisionen.se","www.scb.se","www.statskontoret.se","www.svt.se","www.val.se","www.worldbank.org","yarnpkg.com"],"isolation":true,"topologyAttach":["awmg-mcpg"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxCacheMisses":5,"maxAiCredits":3000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.5","gpt-5.6","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"auto":["copilot/auto","large"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex","kimi"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"detection":["small"],"evals":["small"],"fable":["copilot/*fable*","anthropic/*fable*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","google/nano-banana*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-3.6-flash":["copilot/gemini-3.6*flash*","google/gemini-3.6*flash*","gemini/gemini-3.6*flash*"],"gemini-3.7-flash":["copilot/gemini-3.7*flash*","google/gemini-3.7*flash*","gemini/gemini-3.7*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-omni":["copilot/gemini-omni*","google/gemini-omni*","gemini/gemini-omni*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.1":["copilot/gpt-5.1*","openai/gpt-5.1*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"gpt-5.6":["copilot/gpt-5.6*","openai/gpt-5.6*"],"grok":["copilot/*grok*","openai/*grok*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"image-generation":["copilot/gpt-image*","openai/gpt-image*","openai/chatgpt-image*","copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","google/imagen*"],"kimi":["copilot/kimi*","openai/kimi*"],"kiwi":["copilot/kiwi*","openai/kiwi*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"lyria":["google/lyria*","gemini/lyria*","copilot/lyria*"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"mai-code-1-flash-picker":["copilot/MAI-Code-1-Flash-picker*","copilot/mai-code-1-flash-picker*","openai/MAI-Code-1-Flash-picker*"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"nano-banana":["copilot/nano-banana*","google/nano-banana*","gemini/nano-banana*"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"raptor-mini":["copilot/raptor*","openai/raptor*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"small-agent":["haiku","gpt-5-mini","gemini-flash"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4.5*","copilot/*sonnet-4.6*","copilot/*sonnet-5*","copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*","anthropic/*sonnet-5*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"veo":["google/veo*","gemini/veo*"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35"},"logging":{"proxyLogsDir":"/tmp/gh-aw/sandbox/firewall/logs","auditDir":"/tmp/gh-aw/sandbox/firewall/audit"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -1038,14 +1126,19 @@ jobs: fi fi # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + GH_AW_AWF_ENGINE_NAME=copilot \ + GH_AW_AWF_HARNESS_MARKER='[copilot-harness]' \ + GH_AW_AWF_LOG_FILE=/tmp/gh-aw/agent-stdio.log \ + GH_AW_AWF_ATTEMPT_LOG_NAME=copilot \ + bash "${RUNNER_TEMP}/gh-aw/actions/run_awf_with_startup_retries.sh" -- \ + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" "${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs" "${RUNNER_TEMP}/gh-aw/bin/copilot" --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --no-ask-user --allow-tool github --allow-tool riksdag-regering --allow-tool '\''riksdag-regering(*)'\'' --allow-tool safeoutputs --allow-tool scb --allow-tool '\''scb(*)'\'' --allow-tool shell --allow-tool web_fetch --allow-tool world-bank --allow-tool '\''world-bank(*)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 GH_AW_LLM_PROVIDER: github GH_AW_MAX_TURNS: ${{ vars.NEWS_MAX_TURNS || 300 }} GH_AW_PHASE: agent @@ -1054,7 +1147,7 @@ jobs: GH_AW_STARTUP_TIMEOUT: 180 GH_AW_TIMEOUT_MINUTES: 60 GH_AW_TOOL_TIMEOUT: 120 - GH_AW_VERSION: v0.83.1 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1075,7 +1168,18 @@ jobs: if: always() id: detect-agent-errors continue-on-error: true - run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs" + env: + GH_AW_AGENTIC_EXECUTION_OUTCOME: ${{ steps.agentic_execution.outcome }} + GH_AW_ENGINE_STEP_TIMEOUT_MINUTES: 60 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'detect_agent_errors.cjs')); + await main(); - name: Configure Git credentials env: GITHUB_REPOSITORY: ${{ github.repository }} @@ -1100,9 +1204,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs'); + const { main } = require(path.join(actionsDir, 'redact_secrets.cjs')); await main(); env: GH_AW_SECRET_NAMES: 'GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN,IMF_SDMX_SUBSCRIPTION_KEY' @@ -1126,14 +1232,16 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); + const { main } = require(path.join(actionsDir, 'collect_ndjson_output.cjs')); await main(); - name: Parse agent logs for step summary if: always() @@ -1143,9 +1251,11 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_copilot_log.cjs')); await main(); - name: Parse MCP Gateway logs for step summary if: always() @@ -1153,9 +1263,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); + const { main } = require(path.join(actionsDir, 'parse_mcp_gateway_log.cjs')); await main(); - name: Print firewall logs if: always() @@ -1169,9 +1281,11 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); await main(); - name: Print AWF reflect summary if: always() @@ -1179,10 +1293,23 @@ jobs: uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs'); + const { main } = require(path.join(actionsDir, 'awf_reflect_summary.cjs')); await main(); + - name: Generate observability summary + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'generate_observability_summary.cjs')); + await main(core); - name: Write agent output placeholder if missing if: always() run: | @@ -1208,6 +1335,18 @@ jobs: include-hidden-files: true path: /tmp/gh-aw/cache-memory retention-days: 14 + # Small dedicated copy of the agent output so safe-output processing + # survives a failed or timed-out upload of the larger agent artifact + - name: Upload agent output fallback artifact + if: always() + continue-on-error: true + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: agent-output-fallback + path: | + /tmp/gh-aw/agent_output.json + /tmp/gh-aw/safeoutputs.jsonl + if-no-files-found: ignore - name: Upload agent artifacts if: always() continue-on-error: true @@ -1224,6 +1363,8 @@ jobs: /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/agent/ /tmp/gh-aw/github_rate_limits.jsonl + /tmp/gh-aw/otel.jsonl + /tmp/gh-aw/otlp-export-errors.jsonl /tmp/gh-aw/safeoutputs.jsonl /tmp/gh-aw/agent_output.json /tmp/gh-aw/aw-*.patch @@ -1244,9 +1385,10 @@ jobs: if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || needs.activation.outputs.oauth_token_check_failed == 'true' || needs.activation.outputs.stale_lock_file_failed == 'true' || - needs.activation.outputs.secret_verification_result == 'failed' || needs.activation.outputs.daily_ai_credits_exceeded == 'true') + needs.activation.outputs.daily_ai_credits_exceeded == 'true') runs-on: ubuntu-slim permissions: + actions: read contents: write issues: write pull-requests: write @@ -1264,7 +1406,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1273,15 +1415,16 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1289,42 +1432,29 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Download safe outputs items manifest + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi + - name: Download detection artifact + id: download-detection-artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: detection + path: /tmp/gh-aw/threat-detection/ + - name: Download Safe Outputs Items Manifest id: download-safe-outputs-manifest if: always() continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: safe-outputs-items + pattern: safe-outputs-items + merge-multiple: true path: /tmp/gh-aw/ - name: Collect usage artifact files if: always() continue-on-error: true - run: | - mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection - echo "Usage artifact source file status:" - for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.json /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do - [ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file" - done - [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true - [ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true - [ -f /tmp/gh-aw/agent_usage.json ] && cp /tmp/gh-aw/agent_usage.json /tmp/gh-aw/usage/agent_usage.json || true - [ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true - [ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true - [ -f /tmp/gh-aw/evals/evals.jsonl ] && cp /tmp/gh-aw/evals/evals.jsonl /tmp/gh-aw/usage/evals.jsonl || true - [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -s /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true - [ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl - [ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl - mkdir -p /tmp/gh-aw/usage/activity - node "${RUNNER_TEMP}/gh-aw/actions/generate_usage_activity_summary.cjs" - find /tmp/gh-aw/usage -type f -print | sort + run: bash "${RUNNER_TEMP}/gh-aw/actions/collect_usage_artifact_files.sh" - name: Upload usage artifact if: always() continue-on-error: true @@ -1338,6 +1468,8 @@ jobs: /tmp/gh-aw/usage/agent_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl /tmp/gh-aw/usage/evals.jsonl + /tmp/gh-aw/usage/graders/grader_manifest.json + /tmp/gh-aw/usage/graders/grader_results.json /tmp/gh-aw/usage/github_rate_limits.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl @@ -1360,9 +1492,11 @@ jobs: with: github-token: ${{ github.token }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context); - const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs'); + const { main } = require(path.join(actionsDir, 'write_daily_aic_usage_cache.cjs')); await main(); - name: Save daily AIC usage cache id: save-daily-aic-cache @@ -1392,7 +1526,7 @@ jobs: GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-year-ahead.md" GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" + GH_AW_NOOP_REPORT_AS_ISSUE: "false" GH_AW_AIC: ${{ needs.agent.outputs.aic }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }} @@ -1400,9 +1534,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); + const { main } = require(path.join(actionsDir, 'handle_noop_message.cjs')); await main(); - name: Log detection run id: detection_runs @@ -1417,9 +1553,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs'); + const { main } = require(path.join(actionsDir, 'handle_detection_runs.cjs')); await main(); - name: Record missing tool id: missing_tool @@ -1432,9 +1570,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); + const { main } = require(path.join(actionsDir, 'missing_tool.cjs')); await main(); - name: Record incomplete id: report_incomplete @@ -1447,9 +1587,11 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs'); + const { main } = require(path.join(actionsDir, 'report_incomplete_handler.cjs')); await main(); - name: Handle agent failure id: handle_agent_failure @@ -1476,6 +1618,10 @@ jobs: GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }} GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }} GH_AW_HTTP_400_RESPONSE_ERROR: ${{ needs.agent.outputs.http_400_response_error }} + GH_AW_MAX_CACHE_MISSES_EXCEEDED: ${{ needs.agent.outputs.max_cache_misses_exceeded }} + GH_AW_MISSING_MODEL_PRICING_ERROR: ${{ needs.agent.outputs.missing_model_pricing_error }} + GH_AW_MISSING_MODEL_PRICING_MODEL_NAME: ${{ needs.agent.outputs.missing_model_pricing_model_name }} + GH_AW_SHELL_EXPANSION_GUARD_REJECTED: ${{ needs.agent.outputs.shell_expansion_guard_rejected }} GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com" GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }} GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }} @@ -1496,9 +1642,30 @@ jobs: with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); + const { main } = require(path.join(actionsDir, 'handle_agent_failure.cjs')); + await main(); + - name: Report failed jobs + id: report_failed_jobs + if: always() + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} + GH_AW_WORKFLOW_NAME: "News: Year Ahead" + GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/news-year-ahead.md" + GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + GH_AW_REPORT_FAILED_JOBS: "true" + with: + github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'report_failed_jobs.cjs')); await main(); detection: @@ -1510,6 +1677,7 @@ jobs: permissions: contents: read copilot-requests: write + timeout-minutes: 10 env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -1520,7 +1688,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1529,15 +1697,22 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Download activation artifact + continue-on-error: true + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: activation + path: /tmp/gh-aw - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1545,7 +1720,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Checkout repository for patch context if: needs.agent.outputs.has_patch == 'true' uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -1557,7 +1734,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.38@sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.38@sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c ghcr.io/github/gh-aw-firewall/squid:0.27.38@sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.9@sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.9@sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8 ghcr.io/github/gh-aw-firewall/squid:0.28.9@sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa - name: Check if detection needed id: detection_guard if: always() @@ -1581,21 +1758,7 @@ jobs: - name: Prepare threat detection files if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - rm -f /tmp/gh-aw/agent_usage.json - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then - echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context." - fi - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - for f in /tmp/gh-aw/aw-*.bundle; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true + bash "${RUNNER_TEMP}/gh-aw/actions/prepare_threat_detection_files.sh" - name: Setup threat detection if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -1603,82 +1766,52 @@ jobs: WORKFLOW_NAME: "News: Year Ahead" WORKFLOW_DESCRIPTION: "Generates year-ahead annual political-economic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Long-horizon-forecast workflow with 365-day window — anchored in IMF WEO Apr/Oct vintages, covers the Swedish budget rhythm (BP autumn + VP spring), Riksmöte calendar, EU presidency rotations, and full Nordic-peer comparison. Tier-C aggregation × 2.0 depth multiplier. PESTLE + wildcards-blackswans + quantitative-swot mandatory. Runs 5th of January and 5th of July to track WEO vintage rotation." HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + GH_AW_DETECTION_SKIP_PROMPT_SUMMARY: "true" with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); + const { main } = require(path.join(actionsDir, 'setup_threat_detection.cjs')); await main(); - name: Ensure threat-detection directory and log if: always() && steps.detection_guard.outputs.run_detection == 'true' run: | mkdir -p /tmp/gh-aw/threat-detection touch /tmp/gh-aw/threat-detection/detection.log - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version: '24' - package-manager-cache: false + - name: Install AWF binary + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.9 --rootless - name: Install GitHub Copilot CLI - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.73 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.38 - - name: Execute GitHub Copilot CLI + GH_AW_COMPILED_VERSION: v0.87.9 + - name: Install threat-detect binary if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - timeout-minutes: 20 run: | - set -o pipefail - printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt - trap 'gh_aw_exit_code=$?; mkdir -p /tmp/gh-aw >/dev/null 2>&1 || true; printf "%s" "$gh_aw_exit_code" > /tmp/gh-aw/agent_execution_exit_code.txt || true; rm -f "$HOME/.copilot/settings.json"' EXIT - mkdir -p "$HOME/.copilot" - printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json" - export XDG_CONFIG_HOME="$HOME" - touch /tmp/gh-aw/agent-step-summary.md - GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true) - export GH_AW_NODE_BIN - export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK" - (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) - GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}" - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.38/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"fable\",\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.38,squid=sha256:6c19094d95aad5f9f128ad5e583f0f2b894b158aa66c3b86dd9bcc90970a2917,agent=sha256:cb928eb62d9139a013c2d278dab19af232d35a2d83dca71a3d98eb431f786243,api-proxy=sha256:cd6145620d96acee46e1ede25180a13aa36002467e663db0caa453a8bc8eb60c,cli-proxy=sha256:c30c5319da37505d42f95cb3faa2cfa55e794ccb5cc805dbd9201410d1ac2a3e\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json - export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" - GH_AW_DOCKER_HOST="" - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - GH_AW_DOCKER_HOST="${DOCKER_HOST}" - fi - if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then - _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" - fi - GH_AW_TOOL_CACHE_MOUNT="" - GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" - if [ -d "$GH_AW_TOOL_CACHE" ]; then - if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then - GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" - fi - fi - # shellcheck disable=SC1003,SC2016,SC2086 - awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --skip-pull \ - -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + bash "${RUNNER_TEMP}/gh-aw/actions/install_threat_detect_binary.sh" v0.5.1 + - name: Execute threat detection with AWF + id: detection_agentic_execution + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + timeout-minutes: 10 env: AWF_REFLECT_ENABLED: 1 COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode COPILOT_GITHUB_TOKEN: ${{ github.token }} - COPILOT_MODEL: claude-opus-4.8 + COPILOT_MODEL: claude-opus-5 + GH_AW_HARNESS_MAX_RETRIES: 0 GH_AW_LLM_PROVIDER: github GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }} GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }} GH_AW_PHASE: detection GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.83.1 + GH_AW_TIMEOUT_MINUTES: 10 + GH_AW_VERSION: v0.87.9 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1694,58 +1827,102 @@ jobs: RUNNER_TEMP: ${{ runner.temp }} S2STOKENS: true TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }} - - name: Parse threat detection token usage for step summary - id: parse_detection_token_usage - if: always() + WORKFLOW_NAME: "News: Year Ahead" + WORKFLOW_DESCRIPTION: "Generates year-ahead annual political-economic outlook articles and renders HTML in all 14 supported languages in a single agentic run via executive-brief cascade. Long-horizon-forecast workflow with 365-day window — anchored in IMF WEO Apr/Oct vintages, covers the Swedish budget rhythm (BP autumn + VP spring), Riksmöte calendar, EU presidency rotations, and full Nordic-peer comparison. Tier-C aggregation × 2.0 depth multiplier. PESTLE + wildcards-blackswans + quantitative-swot mandatory. Runs 5th of January and 5th of July to track WEO vintage rotation." + HAS_PATCH: ${{ needs.agent.outputs.has_patch }} + GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" + run: | + set -o pipefail + printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt + GH_AW_COPILOT_SRC="$(command -v copilot 2>/dev/null || true)" + if [ -z "$GH_AW_COPILOT_SRC" ] || [ ! -x "$GH_AW_COPILOT_SRC" ]; then + echo "GitHub Copilot CLI executable not found on PATH after installation" >&2 + exit 127 + fi + GH_AW_COPILOT_BIN="${RUNNER_TEMP}/gh-aw/bin/copilot" + mkdir -p "${RUNNER_TEMP}/gh-aw/bin" + if [ "$GH_AW_COPILOT_SRC" != "$GH_AW_COPILOT_BIN" ]; then + cp "$GH_AW_COPILOT_SRC" "$GH_AW_COPILOT_BIN" + fi + chmod 755 "$GH_AW_COPILOT_BIN" + + (umask 177 && touch /tmp/gh-aw/threat-detection/detection.log) + GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.9/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.npms.io\",\"bun.sh\",\"cdn.jsdelivr.net\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"jsr.io\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"riksdag-regering-ai.onrender.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.9,squid=sha256:3d5dba0b0a139bbb11b5d5b8b44f277d2b18f69cf43090e3c283d750cf864baa,agent=sha256:54b2fb3068efc15a4cc1bd4033f8fa056a9b1779baeba0cb80ae95ea55e7e343,api-proxy=sha256:a0ffb1dc926c6e5a500b336893e032a8f167d3db43c869be886874ef14280bb8,cli-proxy=sha256:38d7ac0585ee5aa6a06eb71e087d514b059db36005c7783c6485e0dfd36fea35\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json + export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" + GH_AW_DOCKER_HOST="" + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + GH_AW_DOCKER_HOST="${DOCKER_HOST}" + fi + if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then + _GH_AW_CHROOT_JSON=$(jq -c --arg src "${RUNNER_TEMP}/gh-aw" --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home "${RUNNER_TEMP}/gh-aw/home" '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; } + printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + fi + GH_AW_TOOL_CACHE_MOUNT="" + GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}" + if [ -d "$GH_AW_TOOL_CACHE" ]; then + if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then + GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro" + fi + fi + # shellcheck disable=SC1003,SC2016,SC2086 + awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --mount /tmp/gh-aw:/tmp/gh-aw:rw --mount /tmp/gh-aw/threat-detection:/tmp/gh-aw/threat-detection:rw --log-level info --skip-pull \ + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && threat-detect --engine copilot --output /tmp/gh-aw/threat-detection/detection_result.json /tmp/gh-aw/threat-detection' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log + - name: Render detection log + if: always() && steps.detection_guard.outputs.run_detection == 'true' continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage with: script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs'); + const { main } = require(path.join(actionsDir, 'render_detection_log.cjs')); await main(); - - name: Upload threat detection log + - name: Copy detection firewall logs + if: always() && steps.detection_guard.outputs.run_detection == 'true' + continue-on-error: true + run: | + mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall + if [ -d /tmp/gh-aw/sandbox/firewall/logs ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/logs && cp -r /tmp/gh-aw/sandbox/firewall/logs/. /tmp/gh-aw/threat-detection/sandbox/firewall/logs/; fi + if [ -d /tmp/gh-aw/sandbox/firewall/audit ]; then mkdir -p /tmp/gh-aw/threat-detection/sandbox/firewall/audit && cp -r /tmp/gh-aw/sandbox/firewall/audit/. /tmp/gh-aw/threat-detection/sandbox/firewall/audit/; fi + - name: Upload threat detection artifact if: always() && steps.detection_guard.outputs.run_detection == 'true' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: detection - path: /tmp/gh-aw/threat-detection/detection.log + path: | + /tmp/gh-aw/threat-detection/detection_result.json + /tmp/gh-aw/threat-detection/sandbox/firewall/logs/ + /tmp/gh-aw/threat-detection/sandbox/firewall/audit/ if-no-files-found: ignore - - name: Parse and conclude threat detection - id: detection_conclusion + - name: Parse threat detection token usage for step summary + id: parse_detection_token_usage if: always() continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + env: + GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage + with: + script: | + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); + setupGlobals(core, github, context, exec, io, getOctokit); + const { main } = require(path.join(actionsDir, 'parse_token_usage.cjs')); + await main(); + - name: Conclude threat detection + id: detection_conclusion + if: always() + continue-on-error: true env: RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }} GH_AW_DETECTION_CONTINUE_ON_ERROR: "true" - with: - script: | - try { - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - } catch (loadErr) { - const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false'; - const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure'; - const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr)); - core.error(msg); - core.setOutput('reason', 'parse_error'); - if (continueOnError && !detectionExecutionFailed) { - core.warning('\u26A0\uFE0F ' + msg); - core.setOutput('conclusion', 'warning'); - core.setOutput('success', 'false'); - } else { - core.setOutput('conclusion', 'failure'); - core.setOutput('success', 'false'); - core.setFailed(msg); - } - } + run: | + bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json safe_outputs: needs: @@ -1768,8 +1945,7 @@ jobs: GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }} GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: "claude-opus-4.8" - GH_AW_ENGINE_VERSION: "1.0.73" + GH_AW_ENGINE_MODEL: "claude-opus-5" GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }} GH_AW_WORKFLOW_ID: "news-year-ahead" @@ -1784,12 +1960,20 @@ jobs: create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }} created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }} + process_safe_outputs_items_applied: ${{ steps.process_safe_outputs.outputs.items_applied }} + process_safe_outputs_items_cancelled: ${{ steps.process_safe_outputs.outputs.items_cancelled }} + process_safe_outputs_items_deferred: ${{ steps.process_safe_outputs.outputs.items_deferred }} + process_safe_outputs_items_failed: ${{ steps.process_safe_outputs.outputs.items_failed }} + process_safe_outputs_items_skipped: ${{ steps.process_safe_outputs.outputs.items_skipped }} + process_safe_outputs_items_succeeded: ${{ steps.process_safe_outputs.outputs.items_succeeded }} + process_safe_outputs_items_warnings: ${{ steps.process_safe_outputs.outputs.items_warnings }} process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} + process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1798,15 +1982,18 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" + - name: Mask OTLP telemetry headers + run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" - name: Download agent output artifact id: download-agent-output continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: agent + pattern: "{agent,agent-output-fallback}" + merge-multiple: true path: /tmp/gh-aw/ - name: Setup agent output environment variable id: setup-agent-output-env @@ -1814,7 +2001,9 @@ jobs: run: | mkdir -p /tmp/gh-aw/ find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + if [ -f "/tmp/gh-aw/agent_output.json" ]; then + echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" + fi - name: Download patch artifact continue-on-error: true uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 @@ -1850,17 +2039,19 @@ jobs: env: GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }} - GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.imf.org,api.individual.githubcopilot.com,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" + GH_AW_ALLOWED_DOMAINS: "*.docker.com,*.docker.io,*.githubusercontent.com,api.imf.org,api.npms.io,api.scb.se,api.snapcraft.io,api.worldbank.org,archive.ubuntu.com,auth.docker.io,azure.archive.ubuntu.com,blacktrigram.com,bra.se,bun.sh,cdn.jsdelivr.net,cdn.playwright.dev,ciacompliancemanager.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,data.europa.eu,data.imf.org,data.riksdagen.se,data.worldbank.org,datahelpdesk.worldbank.org,datamarketplace.imf.org,dataservices.imf.org,deb.nodesource.com,deno.land,digital-strategy.ec.europa.eu,dl.k8s.io,docs.github.com,ec.europa.eu,economy-finance.ec.europa.eu,esm.sh,euparliamentmonitor.com,eur-lex.europa.eu,europarl.europa.eu,g0v.se,gcr.io,get.pnpm.io,ghcr.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,googleapis.deno.dev,googlechromelabs.github.io,governance.worldbank.org,hack23.com,hack23.github.io,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lagradet.se,lfs.github.com,localhost,mcr.microsoft.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,patchdiff.githubusercontent.com,pkgs.k8s.io,playwright.download.prss.microsoft.com,ppa.launchpad.net,production.cloudflare.docker.com,quay.io,raw.githubusercontent.com,regeringen.se,registry.bower.io,registry.hub.docker.com,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,riksdag-regering-ai.onrender.com,riksdagen.se,riksdagsmonitor.com,riksdagsmonitor.hack23.com,riksdagsmonitor.pages.dev,s.symcb.com,s.symcd.com,scb-mcp.onrender.com,security.ubuntu.com,skimdb.npmjs.com,statskontoret.se,storage.googleapis.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.av.se,www.blacktrigram.com,www.boverket.se,www.ciacompliancemanager.com,www.consilium.europa.eu,www.do.se,www.domstol.se,www.ei.se,www.energimyndigheten.se,www.enisa.europa.eu,www.esv.se,www.euparliamentmonitor.com,www.europarl.europa.eu,www.finanspolitiskaradet.se,www.googleapis.com,www.government.se,www.hack23.com,www.imf.org,www.imy.se,www.konj.se,www.konkurrensverket.se,www.kriminalvarden.se,www.lagradet.se,www.migrationsverket.se,www.msb.se,www.naturvardsverket.se,www.npmjs.com,www.npmjs.org,www.regelradet.se,www.regeringen.se,www.riksbank.se,www.riksdagen.se,www.riksdagsmonitor.com,www.riksrevisionen.se,www.scb.se,www.statskontoret.se,www.svt.se,www.val.se,www.worldbank.org,yarnpkg.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} - GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"year-ahead\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}" + GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"draft\":false,\"expires\":336,\"fallback_as_issue\":true,\"if_no_changes\":\"warn\",\"labels\":[\"agentic-news\",\"analysis-data\",\"long-horizon\",\"forward-look\",\"year-ahead\"],\"max\":1,\"max_patch_files\":100,\"max_patch_size\":10240,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\"],\"protected_files_policy\":\"allowed\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}" GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); + const path = require('path'); + const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); + const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); + const { main } = require(path.join(actionsDir, 'process_safe_outputs.cjs')); await main(); - name: Upload Safe Outputs Items if: always() @@ -1870,6 +2061,7 @@ jobs: path: | /tmp/gh-aw/safe-output-items.jsonl /tmp/gh-aw/temporary-id-map.json + /tmp/gh-aw/safe-output-errors.json if-no-files-found: ignore update_cache_memory: @@ -1887,7 +2079,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@8bdba8075360648fe6802302a5b4e016361dc6ac # v0.83.1 + uses: github/gh-aw-actions/setup@49dc896ccb7d6d975514cfe232bcbd68cc12e2c1 # v0.87.9 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1896,8 +2088,8 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "News: Year Ahead" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/news-year-ahead.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.73" - GH_AW_INFO_AWF_VERSION: "v0.27.38" + GH_AW_INFO_VERSION: "1.0.80" + GH_AW_INFO_AWF_VERSION: "v0.28.9" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download cache-memory artifact (default) id: download_cache_default diff --git a/.github/workflows/news-year-ahead.md b/.github/workflows/news-year-ahead.md index af822c8cd1e..c0bd6c1311f 100644 --- a/.github/workflows/news-year-ahead.md +++ b/.github/workflows/news-year-ahead.md @@ -290,7 +290,7 @@ steps: force-generation: ${{ inputs.force_generation }} analysis-depth: ${{ inputs.analysis_depth }} default-analysis-depth: comprehensive -model: claude-opus-4.8 +model: claude-opus-5 engine: id: copilot --- @@ -326,7 +326,7 @@ The dedicated `news-translate` workflow runs on a separate track and translates > 🟡 **Plan to call `safeoutputs___create_pull_request` by agent minute 42 (hard deadline 45)** to reserve job-level headroom for setup variance and the safe-outputs runner. See `00-base-contract.md §Session timing` and `07-commit-and-pr.md §Deadline enforcement`. > -> 🔴 **Token budget awareness**: This workflow uses `claude-opus-4.8` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** +> 🔴 **Token budget awareness**: This workflow uses `claude-opus-5` which consumes tokens rapidly on complex analysis. The 25M token budget can be exhausted in ~20 minutes of intensive MCP querying + large file writes. **Check `agent_minute` before EVERY phase transition. If agent_minute ≥ 20 and zero analysis artifacts exist on disk, immediately compress scope to a minimal viable set and target PR by minute 35.** | Minutes | Phase | |---------|-------| diff --git a/Article-Generation.md b/Article-Generation.md index a2a52e3e919..3df335e9639 100644 --- a/Article-Generation.md +++ b/Article-Generation.md @@ -165,7 +165,7 @@ It declares: | **Schedule** | Daily around 07:00 on weekdays | | **Manual inputs** | `article_date`, `force_generation`, `analysis_depth` (no `languages` input — every run renders all 14). All `workflow_dispatch` inputs are validated and exported to `$GITHUB_ENV` by the [`./.github/actions/news-resolve-inputs`](.github/actions/news-resolve-inputs/action.yml) composite (runs right after `news-prewarm`) so the agent's bash sandbox sees the canonical `ARTICLE_DATE` / `SUBFOLDER` / `ANALYSIS_DEPTH` / `FORCE_GENERATION` variables verbatim via `awf --env-all`. See [`.github/prompts/00-base-contract.md §Runtime input contract`](.github/prompts/00-base-contract.md) for the per-workflow extra-input table (`CYCLE_ANCHOR`, `COVERAGE_DEPTH`, `LOOKBACK_HOURS`, `ARTICLE_TYPES`, `FOCUS`, `LANGUAGES_RESOLVED`, `MAX_BRIEFS_RESOLVED`, `FORCE_RETRANSLATE`, `TRANSLATE_SUBFOLDER`). | | **Runtime** | Node.js `26` | -| **Engine** | Copilot with `claude-opus-4.8` (the 13 analysis/article-generating news workflows; `news-translate` keeps `claude-sonnet-4.6` for high-volume translation throughput) | +| **Engine** | Copilot with `claude-opus-5` (the 13 analysis/article-generating news workflows; `news-translate` keeps `claude-sonnet-4.6` for high-volume translation throughput) | | **Permissions** | Read-only content/issues/PR/actions/discussions/security-events for AI job | | **MCP gateway** | Enabled | | **Safe outputs** | One PR max, labels `agentic-news`, `analysis-data` (no translation dispatch — all 14 languages rendered in-run) | diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md index 7e7306db4ff..548ff14ccd2 100644 --- a/THREAT_MODEL.md +++ b/THREAT_MODEL.md @@ -1905,7 +1905,7 @@ This section provides comprehensive AI security analysis per [Hack23 AI Policy]( **Per [Hack23 AI Policy § 4.3](https://github.com/Hack23/ISMS-PUBLIC/blob/main/AI_Policy.md)**, all LLM applications MUST maintain model cards documenting capabilities, limitations, and security characteristics. > **Dual-model architecture.** Riksdagsmonitor runs **two** Anthropic models through the GitHub Copilot API: -> - **Claude Opus 4.8** — the reasoning model that drives the **13 analysis/article workflows** and the full 23-artifact analysis pipeline (`engine.model: claude-opus-4.8`). It carries the integrity-critical workload: source synthesis, significance scoring, evidence citation, and English/Swedish article drafting. +> - **Claude Opus 4.8** — the reasoning model that drives the **13 analysis/article workflows** and the full 23-artifact analysis pipeline (`engine.model: claude-opus-5`). It carries the integrity-critical workload: source synthesis, significance scoring, evidence citation, and English/Swedish article drafting. > - **Claude Sonnet 4.6** — the faster model used **only** for the high-volume **news-translate** fan-out (`engine.model: claude-sonnet-4.6`), translating rendered EN+SV articles into the 12 remaining languages. > > Sonnet 4.6 was the repo-wide baseline through v0.74.3; the analysis/article pipeline was promoted to the Opus reasoning model to strengthen factual grounding and reduce overreliance (LLM09) risk. GPT-5.4 / GPT-5.4-mini eligibility is resolved upstream but not yet A/B-tested on this repository. @@ -2032,7 +2032,7 @@ This section provides comprehensive AI security analysis per [Hack23 AI Policy]( #### Maintenance & Monitoring **Model Version Management**: -- ✅ `engine.model` pinned per workflow: `claude-opus-4.8` (13 analysis/article workflows), `claude-sonnet-4.6` (news-translate) +- ✅ `engine.model` pinned per workflow: `claude-opus-5` (13 analysis/article workflows), `claude-sonnet-4.6` (news-translate) - ✅ Compiled `.lock.yml` files version-control the exact engine/model selection (reviewable in PRs) - ✅ GitHub Copilot API versioning (GitHub-managed) - ⚠️ No automated model update testing (GPT-5.4 / GPT-5.4-mini A/B test pending) diff --git a/WORKFLOWS.md b/WORKFLOWS.md index c7cf2335c53..32dda975694 100644 --- a/WORKFLOWS.md +++ b/WORKFLOWS.md @@ -708,7 +708,7 @@ flowchart TD ### 🤖 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. +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-5`** (strongest reasoning for the analysis pipeline), while the high-volume **`news-translate` workflow stays on `claude-sonnet-4.6`** for translation-fan-out throughput. ```mermaid flowchart TD diff --git a/docs/api/documents/THREAT_MODEL.html b/docs/api/documents/THREAT_MODEL.html index 7a4e9ec2841..17e804da1d2 100644 --- a/docs/api/documents/THREAT_MODEL.html +++ b/docs/api/documents/THREAT_MODEL.html @@ -3614,7 +3614,7 @@

Model Version Management:


-

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.

+

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-5 (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
diff --git a/docs/api/media/Article-Generation.md b/docs/api/media/Article-Generation.md index a2a52e3e919..3df335e9639 100644 --- a/docs/api/media/Article-Generation.md +++ b/docs/api/media/Article-Generation.md @@ -165,7 +165,7 @@ It declares: | **Schedule** | Daily around 07:00 on weekdays | | **Manual inputs** | `article_date`, `force_generation`, `analysis_depth` (no `languages` input — every run renders all 14). All `workflow_dispatch` inputs are validated and exported to `$GITHUB_ENV` by the [`./.github/actions/news-resolve-inputs`](.github/actions/news-resolve-inputs/action.yml) composite (runs right after `news-prewarm`) so the agent's bash sandbox sees the canonical `ARTICLE_DATE` / `SUBFOLDER` / `ANALYSIS_DEPTH` / `FORCE_GENERATION` variables verbatim via `awf --env-all`. See [`.github/prompts/00-base-contract.md §Runtime input contract`](.github/prompts/00-base-contract.md) for the per-workflow extra-input table (`CYCLE_ANCHOR`, `COVERAGE_DEPTH`, `LOOKBACK_HOURS`, `ARTICLE_TYPES`, `FOCUS`, `LANGUAGES_RESOLVED`, `MAX_BRIEFS_RESOLVED`, `FORCE_RETRANSLATE`, `TRANSLATE_SUBFOLDER`). | | **Runtime** | Node.js `26` | -| **Engine** | Copilot with `claude-opus-4.8` (the 13 analysis/article-generating news workflows; `news-translate` keeps `claude-sonnet-4.6` for high-volume translation throughput) | +| **Engine** | Copilot with `claude-opus-5` (the 13 analysis/article-generating news workflows; `news-translate` keeps `claude-sonnet-4.6` for high-volume translation throughput) | | **Permissions** | Read-only content/issues/PR/actions/discussions/security-events for AI job | | **MCP gateway** | Enabled | | **Safe outputs** | One PR max, labels `agentic-news`, `analysis-data` (no translation dispatch — all 14 languages rendered in-run) | diff --git a/docs/api/media/README-3.md b/docs/api/media/README-3.md index 0a125d9c4c2..5ff8b1c0972 100644 --- a/docs/api/media/README-3.md +++ b/docs/api/media/README-3.md @@ -109,7 +109,7 @@ Every news workflow declares the **same** tool & runtime surface for parity, res | Field | Value | Purpose | |-------|-------|---------| | `runtimes.node.version` | `"26"` | Pinned Node 26 for IMF CLI + render scripts | -| `engine.id` / `engine.model` | `copilot` / `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.id` / `engine.model` | `copilot` / `claude-opus-5` (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-timeout` | ~~`1h`~~ **removed** | Was 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`](https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/github-tools.md) | | `tools.bash` / `tools.edit` / `tools.web-fetch` / `tools.agentic-workflows` | enabled | Full local tool surface; `web-fetch` reaches non-MCP public sources (`statskontoret.se`, `riksdagsmonitor.com`) through the AWF firewall | diff --git a/docs/test-results/vitest-results.json b/docs/test-results/vitest-results.json index d5f89ca6f1c..31a88fe3610 100644 --- a/docs/test-results/vitest-results.json +++ b/docs/test-results/vitest-results.json @@ -1 +1 @@ -{"numTotalTestSuites":1615,"numPassedTestSuites":1615,"numFailedTestSuites":0,"numPendingTestSuites":0,"numTotalTests":7605,"numPassedTests":7571,"numFailedTests":0,"numPendingTests":34,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1787953656920,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface the safety doc itself exists and is the only allowlisted source of pattern strings","status":"passed","title":"the safety doc itself exists and is the only allowlisted source of pattern strings","duration":4.229150000000004,"failureMessages":[],"location":{"line":255,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-committee-reports.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-committee-reports.md contains no banned bash patterns in fenced code blocks","duration":1.7056140000000255,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-election-cycle.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-election-cycle.md contains no banned bash patterns in fenced code blocks","duration":0.7225730000000112,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-evening-analysis.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-evening-analysis.md contains no banned bash patterns in fenced code blocks","duration":0.6791809999999714,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-interpellations.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-interpellations.md contains no banned bash patterns in fenced code blocks","duration":0.5793239999999855,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-month-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-month-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.5301330000000348,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-monthly-review.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-monthly-review.md contains no banned bash patterns in fenced code blocks","duration":0.5585149999999999,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-motions.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-motions.md contains no banned bash patterns in fenced code blocks","duration":0.49733200000002853,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-propositions.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-propositions.md contains no banned bash patterns in fenced code blocks","duration":0.6525220000000331,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-quarter-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-quarter-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.5025210000000015,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-realtime-monitor.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-realtime-monitor.md contains no banned bash patterns in fenced code blocks","duration":0.567924000000005,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-translate.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-translate.md contains no banned bash patterns in fenced code blocks","duration":0.5972489999999766,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-week-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-week-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.4668350000000032,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-weekly-review.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-weekly-review.md contains no banned bash patterns in fenced code blocks","duration":0.46835699999996905,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-year-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-year-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.44745799999998326,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/00-base-contract.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/00-base-contract.md contains no banned bash patterns in fenced code blocks","duration":1.2079709999999864,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/02-mcp-access.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/02-mcp-access.md contains no banned bash patterns in fenced code blocks","duration":0.6259320000000343,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/03-data-download.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/03-data-download.md contains no banned bash patterns in fenced code blocks","duration":1.2184520000000134,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/04-analysis-pipeline.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/04-analysis-pipeline.md contains no banned bash patterns in fenced code blocks","duration":0.6528119999999831,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/05-analysis-gate.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/05-analysis-gate.md contains no banned bash patterns in fenced code blocks","duration":2.420812999999953,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/06-article-generation.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/06-article-generation.md contains no banned bash patterns in fenced code blocks","duration":1.0866750000000138,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/07-commit-and-pr.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/07-commit-and-pr.md contains no banned bash patterns in fenced code blocks","duration":1.0482330000000388,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/README.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/README.md contains no banned bash patterns in fenced code blocks","duration":0.7051500000000033,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/seo-metadata-contract.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/seo-metadata-contract.md contains no banned bash patterns in fenced code blocks","duration":0.6248499999999808,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/advanced-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/advanced-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5267370000000255,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5621719999999755,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ai-governance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ai-governance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6534440000000359,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/api-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/api-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6589239999999563,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/automated-content-generation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/automated-content-generation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5915479999999889,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/behavioral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/behavioral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9244419999999991,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/business-development/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/business-development/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.869117000000017,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/business-model-canvas/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/business-model-canvas/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7162910000000124,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/c4-architecture-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/c4-architecture-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7536510000000476,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/change-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/change-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.67897099999999,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ci-cd-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ci-cd-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.636743000000024,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/cia-data-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/cia-data-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6531130000000189,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/cis-controls/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/cis-controls/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7748920000000226,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/code-quality-checks/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/code-quality-checks/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6438160000000153,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/code-review-practices/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/code-review-practices/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6387860000000387,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/comparative-politics-reporting/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/comparative-politics-reporting/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8401339999999777,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/compliance-checklist/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/compliance-checklist/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9732319999999959,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/contribution-guidelines/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/contribution-guidelines/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7038080000000377,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/copilot-agent-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/copilot-agent-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6644139999999652,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-pipeline-engineering/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-pipeline-engineering/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7263409999999908,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-protection/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-protection/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8212280000000192,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-science-for-intelligence/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-science-for-intelligence/SKILL.md contains no banned bash patterns in fenced code blocks","duration":4.007734999999968,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-visualization-principles/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-visualization-principles/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6225650000000087,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/design-system-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/design-system-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5822299999999814,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/documentation-portfolio/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/documentation-portfolio/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6393080000000282,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/documentation-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/documentation-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6205319999999688,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/economic-policy-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/economic-policy-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7019050000000107,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/editorial-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/editorial-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6770970000000034,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/electoral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/electoral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7847300000000246,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/european-parliament-api/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/european-parliament-api/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5985610000000179,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gdpr-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gdpr-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6492749999999887,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-authentication-credentials/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-authentication-credentials/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8699290000000133,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-containerization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-containerization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8708409999999844,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-continuous-ai-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-continuous-ai-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9371649999999931,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-firewall/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-firewall/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1155799999999658,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-github-actions-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-github-actions-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1723049999999944,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-logging-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-logging-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9354220000000169,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-mcp-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-mcp-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1180329999999685,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-mcp-gateway/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-mcp-gateway/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.507474000000002,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-safe-outputs/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-safe-outputs/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8753389999999968,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-security-architecture/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-security-architecture/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.218691999999976,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-tools-ecosystem/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-tools-ecosystem/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0211330000000203,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-workflow-authoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-workflow-authoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0575410000000147,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/github-actions-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/github-actions-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8017320000000154,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/github-agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/github-agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4229050000000143,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/global-government-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/global-government-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.853398000000027,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/hack23-future-architecture-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/hack23-future-architecture-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4127960000000144,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/hack23-isms-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/hack23-isms-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9560299999999984,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/html-accessibility/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/html-accessibility/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9073700000000144,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/incident-response/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/incident-response/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8746380000000045,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/information-security-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/information-security-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8829840000000218,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/input-validation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/input-validation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9019490000000019,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/intelligence-analysis-techniques/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/intelligence-analysis-techniques/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1421589999999924,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/investigative-journalism/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/investigative-journalism/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.969244999999944,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/iso-27001-controls/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/iso-27001-controls/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0953210000000126,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/issue-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/issue-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2023619999999937,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/language-expertise/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/language-expertise/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1178330000000187,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/legislative-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/legislative-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":2.563431000000037,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/marketing/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/marketing/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9252749999999423,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-gateway-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-gateway-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5888349999999036,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-gateway-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-gateway-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2853569999999763,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-server-development/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-server-development/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.139242999999965,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/multi-language-localization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/multi-language-localization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.203873999999928,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/myndigheter-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/myndigheter-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2088940000001003,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/nist-csf-mapping/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/nist-csf-mapping/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.148800999999935,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/open-source-governance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/open-source-governance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.186001000000033,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/osint-methodologies/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/osint-methodologies/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2982110000000375,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/performance-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/performance-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2048269999999093,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/playwright-testing/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/playwright-testing/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2482969999999796,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/political-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/political-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.3226359999999886,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/political-science-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/political-science-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4144679999999425,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/product-management-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/product-management-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2724319999999807,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/prospective-news-coverage/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/prospective-news-coverage/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.3396189999999706,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/regulatory-affairs/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/regulatory-affairs/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9861590000000433,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/responsive-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/responsive-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.8174129999999877,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/riksdag-regering-mcp/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/riksdag-regering-mcp/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.996609000000035,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/risk-assessment-frameworks/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/risk-assessment-frameworks/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9838449999999739,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secrets-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secrets-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7709760000000188,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-code-review/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-code-review/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.935944999999947,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-development-lifecycle/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-development-lifecycle/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7451579999999467,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-development-policy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-development-policy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5365880000000516,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/security-by-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/security-by-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5589599999999564,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/security-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/security-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5178319999999985,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/seo-best-practices/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/seo-best-practices/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5242739999999912,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/seo-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/seo-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5541109999999208,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/static-site-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/static-site-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7893909999999096,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/strategic-communication-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/strategic-communication-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7121559999999363,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/swedish-political-system/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/swedish-political-system/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.71358900000007,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/testing-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/testing-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.614663999999948,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/threat-modeling/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/threat-modeling/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7588739999999916,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ui-ux-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ui-ux-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7814560000000483,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/vulnerability-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/vulnerability-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9136140000000523,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Allowed eval replacements are documented and self-consistent"],"fullName":"Agentic Workflow Bash & Shell Safety Allowed eval replacements are documented and self-consistent safety doc still names the three allowed eval replacements","status":"passed","title":"safety doc still names the three allowed eval replacements","duration":2.643269999999916,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Allowed eval replacements are documented and self-consistent"],"fullName":"Agentic Workflow Bash & Shell Safety Allowed eval replacements are documented and self-consistent no agent-visible file authorises a fourth eval-replacement shape","status":"passed","title":"no agent-visible file authorises a fourth eval-replacement shape","duration":16.867084999999975,"failureMessages":[],"location":{"line":299,"column":5},"meta":{},"tags":[]}],"startTime":1787953807235,"endTime":1787953807385.8672,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic-workflow-bash-safety.test.ts"},{"assertionResults":[{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-evening-analysis.md should document get_sync_status() call","status":"passed","title":"news-evening-analysis.md should document get_sync_status() call","duration":7.120672000000013,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-evening-analysis.md should warn about stale data","status":"passed","title":"news-evening-analysis.md should warn about stale data","duration":1.7746319999999969,"failureMessages":[],"location":{"line":58,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-realtime-monitor.md should document get_sync_status() call","status":"passed","title":"news-realtime-monitor.md should document get_sync_status() call","duration":2.2326400000000035,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-realtime-monitor.md should warn about stale data","status":"passed","title":"news-realtime-monitor.md should warn about stale data","duration":1.4788990000000126,"failureMessages":[],"location":{"line":58,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-evening-analysis.md should document explicit date parameters","status":"passed","title":"news-evening-analysis.md should document explicit date parameters","duration":2.585050000000024,"failureMessages":[],"location":{"line":81,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-evening-analysis.md should NOT rely on implicit \"latest\" patterns","status":"passed","title":"news-evening-analysis.md should NOT rely on implicit \"latest\" patterns","duration":2.472578999999996,"failureMessages":[],"location":{"line":98,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-realtime-monitor.md should document explicit date parameters","status":"passed","title":"news-realtime-monitor.md should document explicit date parameters","duration":2.273285000000044,"failureMessages":[],"location":{"line":81,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-realtime-monitor.md should NOT rely on implicit \"latest\" patterns","status":"passed","title":"news-realtime-monitor.md should NOT rely on implicit \"latest\" patterns","duration":1.9193729999999505,"failureMessages":[],"location":{"line":98,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation news-evening-analysis.md should document post-query filtering","status":"passed","title":"news-evening-analysis.md should document post-query filtering","duration":2.043274999999994,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation workflows should annotate tools with date support","status":"passed","title":"workflows should annotate tools with date support","duration":2.008100000000013,"failureMessages":[],"location":{"line":164,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation news-evening-analysis.md should document post-query fromDate filtering guidance","status":"passed","title":"news-evening-analysis.md should document post-query fromDate filtering guidance","duration":1.8616549999999847,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Cross-Referencing Strategy"],"fullName":"Agentic Workflow MCP Query Patterns Cross-Referencing Strategy news-evening-analysis.md should document cross-referencing of data sources","status":"passed","title":"news-evening-analysis.md should document cross-referencing of data sources","duration":3.5262420000000247,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-evening-analysis.md should document error scenarios","status":"passed","title":"news-evening-analysis.md should document error scenarios","duration":1.2753979999999956,"failureMessages":[],"location":{"line":219,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-evening-analysis.md should document stale/partial data handling","status":"passed","title":"news-evening-analysis.md should document stale/partial data handling","duration":1.6391489999999749,"failureMessages":[],"location":{"line":241,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-realtime-monitor.md should document error scenarios","status":"passed","title":"news-realtime-monitor.md should document error scenarios","duration":1.134333999999967,"failureMessages":[],"location":{"line":219,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-realtime-monitor.md should document stale/partial data handling","status":"passed","title":"news-realtime-monitor.md should document stale/partial data handling","duration":1.5181820000000243,"failureMessages":[],"location":{"line":241,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-evening-analysis.md should document the MCP surface inline or via prompt modules","status":"passed","title":"news-evening-analysis.md should document the MCP surface inline or via prompt modules","duration":1.2584959999999796,"failureMessages":[],"location":{"line":263,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-evening-analysis.md should emphasize get_sync_status() first","status":"passed","title":"news-evening-analysis.md should emphasize get_sync_status() first","duration":1.1235940000000255,"failureMessages":[],"location":{"line":294,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-realtime-monitor.md should document the MCP surface inline or via prompt modules","status":"passed","title":"news-realtime-monitor.md should document the MCP surface inline or via prompt modules","duration":1.1142059999999674,"failureMessages":[],"location":{"line":263,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-realtime-monitor.md should emphasize get_sync_status() first","status":"passed","title":"news-realtime-monitor.md should emphasize get_sync_status() first","duration":1.4319710000000327,"failureMessages":[],"location":{"line":294,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices workflows should have date calculation examples","status":"passed","title":"workflows should have date calculation examples","duration":1.6785320000000183,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices workflows should include dynamic riksmöte calculation instructions","status":"passed","title":"workflows should include dynamic riksmöte calculation instructions","duration":1.6541070000000104,"failureMessages":[],"location":{"line":328,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices all news workflows should not hardcode the parliamentary session year","status":"passed","title":"all news workflows should not hardcode the parliamentary session year","duration":9.407573000000014,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Workflow Compilation"],"fullName":"Agentic Workflow MCP Query Patterns Workflow Compilation news-evening-analysis.md should compile without errors","status":"passed","title":"news-evening-analysis.md should compile without errors","duration":2.018429000000026,"failureMessages":[],"location":{"line":360,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Workflow Compilation"],"fullName":"Agentic Workflow MCP Query Patterns Workflow Compilation news-realtime-monitor.md should compile without errors","status":"passed","title":"news-realtime-monitor.md should compile without errors","duration":3.7051969999999983,"failureMessages":[],"location":{"line":360,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Regression Prevention"],"fullName":"Agentic Workflow MCP Query Patterns Regression Prevention evening analysis should maintain enhanced query patterns","status":"passed","title":"evening analysis should maintain enhanced query patterns","duration":1.197170999999969,"failureMessages":[],"location":{"line":386,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Regression Prevention"],"fullName":"Agentic Workflow MCP Query Patterns Regression Prevention workflows should not use ambiguous \"latest\" language","status":"passed","title":"workflows should not use ambiguous \"latest\" language","duration":1.4189360000000306,"failureMessages":[],"location":{"line":408,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Tool Date Parameter Support Matrix"],"fullName":"MCP Tool Date Parameter Support Matrix effective prompt for evening analysis should scope MCP queries by date","status":"passed","title":"effective prompt for evening analysis should scope MCP queries by date","duration":1.0432839999999715,"failureMessages":[],"location":{"line":463,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-committee-reports.md should import the MCP access prompt module","status":"passed","title":"news-committee-reports.md should import the MCP access prompt module","duration":0.5726119999999923,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-committee-reports.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-committee-reports.md should not embed inline python3 JSON-parsing scripts","duration":1.309020999999973,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-evening-analysis.md should import the MCP access prompt module","status":"passed","title":"news-evening-analysis.md should import the MCP access prompt module","duration":0.678910999999971,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-evening-analysis.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-evening-analysis.md should not embed inline python3 JSON-parsing scripts","duration":0.9703460000000064,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-interpellations.md should import the MCP access prompt module","status":"passed","title":"news-interpellations.md should import the MCP access prompt module","duration":0.47906699999998636,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-interpellations.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-interpellations.md should not embed inline python3 JSON-parsing scripts","duration":0.556822000000011,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-month-ahead.md should import the MCP access prompt module","status":"passed","title":"news-month-ahead.md should import the MCP access prompt module","duration":0.47168299999998453,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-month-ahead.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-month-ahead.md should not embed inline python3 JSON-parsing scripts","duration":0.5634660000000054,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-monthly-review.md should import the MCP access prompt module","status":"passed","title":"news-monthly-review.md should import the MCP access prompt module","duration":0.4721139999999764,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-monthly-review.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-monthly-review.md should not embed inline python3 JSON-parsing scripts","duration":0.6159139999999752,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-motions.md should import the MCP access prompt module","status":"passed","title":"news-motions.md should import the MCP access prompt module","duration":0.4916210000000092,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-motions.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-motions.md should not embed inline python3 JSON-parsing scripts","duration":0.5864879999999744,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-propositions.md should import the MCP access prompt module","status":"passed","title":"news-propositions.md should import the MCP access prompt module","duration":0.493344000000036,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-propositions.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-propositions.md should not embed inline python3 JSON-parsing scripts","duration":0.6698440000000119,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-realtime-monitor.md should import the MCP access prompt module","status":"passed","title":"news-realtime-monitor.md should import the MCP access prompt module","duration":0.5894729999999981,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-realtime-monitor.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-realtime-monitor.md should not embed inline python3 JSON-parsing scripts","duration":0.5937910000000102,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-week-ahead.md should import the MCP access prompt module","status":"passed","title":"news-week-ahead.md should import the MCP access prompt module","duration":0.5471949999999879,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-week-ahead.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-week-ahead.md should not embed inline python3 JSON-parsing scripts","duration":0.6167639999999892,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-weekly-review.md should import the MCP access prompt module","status":"passed","title":"news-weekly-review.md should import the MCP access prompt module","duration":0.675423999999964,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-weekly-review.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-weekly-review.md should not embed inline python3 JSON-parsing scripts","duration":0.6459300000000212,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards prompts/02-mcp-access.md should define the canonical MCP access contract","status":"passed","title":"prompts/02-mcp-access.md should define the canonical MCP access contract","duration":0.7086570000000165,"failureMessages":[],"location":{"line":548,"column":3},"meta":{},"tags":[]}],"startTime":1787953667246,"endTime":1787953667324.7087,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic-workflow-mcp-queries.test.ts"},{"assertionResults":[{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation renders a localised navigation table with one row per available artifact + audit appendix","status":"passed","title":"renders a localised navigation table with one row per available artifact + audit appendix","duration":6.4800840000000335,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation localises the heading per language (sv)","status":"passed","title":"localises the heading per language (sv)","duration":0.6548860000000332,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation omits per-document row when no documents/*-analysis.md artifacts present","status":"passed","title":"omits per-document row when no documents/*-analysis.md artifacts present","duration":0.5446100000000342,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation includes per-document row when documents/*-analysis.md present","status":"passed","title":"includes per-document row when documents/*-analysis.md present","duration":0.6226659999999811,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation always includes the audit-appendix row even when no curated artifacts matched","status":"passed","title":"always includes the audit-appendix row even when no curated artifacts matched","duration":0.5295810000000074,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation points the audit row at political-classification when that is the available audit artifact","status":"passed","title":"points the audit row at political-classification when that is the available audit artifact","duration":0.7306180000000495,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation renders rows for ALL analysis artifacts, not just the curated lenses","status":"passed","title":"renders rows for ALL analysis artifacts, not just the curated lenses","duration":0.9459410000000616,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation uses the localised colIcon header for the icon column (not hard-coded English \"Icon\")","status":"passed","title":"uses the localised colIcon header for the icon column (not hard-coded English \"Icon\")","duration":0.7366389999999683,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation skips JSON artifacts and unknown extensions (no broken in-page anchors)","status":"passed","title":"skips JSON artifacts and unknown extensions (no broken in-page anchors)","duration":0.6240179999999782,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation de-duplicates filename-variant alias groups (election-2026-analysis vs election-cycle-analysis)","status":"passed","title":"de-duplicates filename-variant alias groups (election-2026-analysis vs election-cycle-analysis)","duration":0.7651019999999562,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation skips README.md and article*.md aggregator outputs","status":"passed","title":"skips README.md and article*.md aggregator outputs","duration":0.6531739999999218,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderAnalysisArtifactsReference"],"fullName":"article-aside — renderAnalysisArtifactsReference returns the empty string when no artifacts supplied","status":"passed","title":"returns the empty string when no artifacts supplied","duration":0.4747989999999618,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderAnalysisArtifactsReference"],"fullName":"article-aside — renderAnalysisArtifactsReference renders one source card per artifact with icon, i18n title, and GitHub blob url","status":"passed","title":"renders one source card per artifact with icon, i18n title, and GitHub blob url","duration":0.7371799999999666,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderMethodsReference"],"fullName":"article-aside — renderMethodsReference renders the four methodology cards plus a CTA back to political-intelligence","status":"passed","title":"renders the four methodology cards plus a CTA back to political-intelligence","duration":0.6880690000000413,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderMethodsReference"],"fullName":"article-aside — renderMethodsReference points the CTA to the language-specific catalogue page (sv)","status":"passed","title":"points the CTA to the language-specific catalogue page (sv)","duration":0.40649100000007365,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders rm-article-sources strictly BEFORE rm-methods-reference","status":"passed","title":"renders rm-article-sources strictly BEFORE rm-methods-reference","duration":49.441985000000045,"failureMessages":[],"location":{"line":268,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders the navigation table BEFORE the analysis-artifacts reference","status":"passed","title":"renders the navigation table BEFORE the analysis-artifacts reference","duration":5.55018199999995,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders the methods reference for all 14 languages","status":"passed","title":"renders the methods reference for all 14 languages","duration":44.41408100000001,"failureMessages":[],"location":{"line":298,"column":3},"meta":{},"tags":[]}],"startTime":1787953793416,"endTime":1787953793531.414,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-aside.test.ts"},{"assertionResults":[{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections removes every embedded carrier section while keeping analytical sections","status":"passed","title":"removes every embedded carrier section while keeping analytical sections","duration":4.398975999999948,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections collapses the blank-line gap left by removed carriers and ends with a single newline","status":"passed","title":"collapses the blank-line gap left by removed carriers and ends with a single newline","duration":0.7116829999999936,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections is a no-op for a body with no carrier sections","status":"passed","title":"is a no-op for a body with no carrier sections","duration":0.7009620000000041,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections strips a stray `## Executive Brief En` carrier (executive-brief_en.md) so it never leaks into the TOC","status":"passed","title":"strips a stray `## Executive Brief En` carrier (executive-brief_en.md) so it never leaks into the TOC","duration":0.555940000000021,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections preserves the legacy unsuffixed `## Executive Brief` lead heading (no language suffix)","status":"passed","title":"preserves the legacy unsuffixed `## Executive Brief` lead heading (no language suffix)","duration":0.46960999999998876,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead English: strips carriers but keeps the canonical English lead verbatim","status":"passed","title":"English: strips carriers but keeps the canonical English lead verbatim","duration":0.549018999999987,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead English: also strips a stray `## Executive Brief En` carrier while keeping the canonical lead","status":"passed","title":"English: also strips a stray `## Executive Brief En` carrier while keeping the canonical lead","duration":0.5395300000000134,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English with a brief: swaps the lead body to localized prose under the stable H2","status":"passed","title":"non-English with a brief: swaps the lead body to localized prose under the stable H2","duration":14.320760000000007,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English brief: cleaning strips front-matter and the first H1, demotes ## to ###","status":"passed","title":"non-English brief: cleaning strips front-matter and the first H1, demotes ## to ###","duration":0.9329270000000065,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English brief: repoints the lead provenance comment at executive-brief_.md","status":"passed","title":"non-English brief: repoints the lead provenance comment at executive-brief_.md","duration":0.6263529999999946,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English without a brief: keeps the English lead (localized-if-exists, English-otherwise)","status":"passed","title":"non-English without a brief: keeps the English lead (localized-if-exists, English-otherwise)","duration":0.4694390000000226,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English with an empty/whitespace brief: falls back to the English lead","status":"passed","title":"non-English with an empty/whitespace brief: falls back to the English lead","duration":0.36242899999996325,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead does not inject English normalize-terminology glosses into localized prose","status":"passed","title":"does not inject English normalize-terminology glosses into localized prose","duration":0.5103659999999763,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead targets the first H2 generically (legacy `## Executive Brief` lead heading)","status":"passed","title":"targets the first H2 generically (legacy `## Executive Brief` lead heading)","duration":0.5483969999999658,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead handles a lead section that is the only H2 (no trailing analytical section)","status":"passed","title":"handles a lead section that is the only H2 (no trailing analytical section)","duration":0.5438490000000229,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]}],"startTime":1787953826389,"endTime":1787953826416.544,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-brief-lead.test.ts"},{"assertionResults":[{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata returns the raw front-matter values verbatim","status":"passed","title":"returns the raw front-matter values verbatim","duration":11.22403300000002,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata parses the front-matter date into YYYY-MM-DD","status":"passed","title":"parses the front-matter date into YYYY-MM-DD","duration":0.861233000000027,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata infers the article type from the canonical path (committee-reports)","status":"passed","title":"infers the article type from the canonical path (committee-reports)","duration":0.8138739999999984,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata produces a branded with brand suffix and NO date prefix","status":"passed","title":"produces a branded <title> with brand suffix and NO date prefix","duration":1.1119619999999486,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata forwards keywords / description into the buildArticleSeoMetadata output","status":"passed","title":"forwards keywords / description into the buildArticleSeoMetadata output","duration":0.7065230000000042,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata falls back to \"today\" when the front-matter date is missing","status":"passed","title":"falls back to \"today\" when the front-matter date is missing","duration":1.021532000000036,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata exposes articleSection matching the value buildChrome passes to article:section","status":"passed","title":"exposes articleSection matching the value buildChrome passes to article:section","duration":0.6365509999999972,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) accepts an ISO Date instance","status":"passed","title":"accepts an ISO Date instance","duration":0.5125499999999761,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) accepts a YYYY-MM-DD string","status":"passed","title":"accepts a YYYY-MM-DD string","duration":0.48171100000001843,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) falls back to the injected \"now\" when the input is missing","status":"passed","title":"falls back to the injected \"now\" when the input is missing","duration":0.4928530000000251,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["inferArticleType (re-exported)"],"fullName":"inferArticleType (re-exported) recognises realtime-pulse canonical paths","status":"passed","title":"recognises realtime-pulse canonical paths","duration":0.744213000000002,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["inferArticleType (re-exported)"],"fullName":"inferArticleType (re-exported) falls back to political-intelligence for unknown paths","status":"passed","title":"falls back to political-intelligence for unknown paths","duration":0.47831500000000915,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget audit regression: max=88 EN title no longer overshoots the 70-char hardMax","status":"passed","title":"audit regression: max=88 EN title no longer overshoots the 70-char hardMax","duration":2.779092999999989,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget short H1 ships with the brand suffix and NO date prefix","status":"passed","title":"short H1 ships with the brand suffix and NO date prefix","duration":1.0189579999999978,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=en never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=en never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8367269999999962,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=sv never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=sv never overshoots titleWindowForLanguage(lang).hardMax","duration":0.9817980000000261,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=da never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=da never overshoots titleWindowForLanguage(lang).hardMax","duration":1.0872549999999706,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=no never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=no never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8238129999999728,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=fi never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=fi never overshoots titleWindowForLanguage(lang).hardMax","duration":0.6863250000000107,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=de never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=de never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7179639999999949,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=fr never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=fr never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8237219999999752,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=es never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=es never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7528599999999983,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=nl never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=nl never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7558449999999652,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ar never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ar never overshoots titleWindowForLanguage(lang).hardMax","duration":1.121690000000001,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=he never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=he never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7201780000000326,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ja never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ja never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8372669999999971,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ko never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ko never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7334829999999783,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=zh never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=zh never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7618969999999763,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget truncated branded title from the news/index card regression no longer reads \"…Five… — Riksdagsmonitor\"","status":"passed","title":"truncated branded title from the news/index card regression no longer reads \"…Five… — Riksdagsmonitor\"","duration":0.8229709999999386,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]}],"startTime":1787953825362,"endTime":1787953825398.823,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-head-metadata.test.ts"},{"assertionResults":[{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish returns English markdown unchanged when lang === \"en\"","status":"passed","title":"returns English markdown unchanged when lang === \"en\"","duration":5.007345999999984,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish overlays localized title/language but keeps English executive-brief description","status":"passed","title":"overlays localized title/language but keeps English executive-brief description","duration":8.358641000000034,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish keeps canonical-identity front-matter fields from the English source","status":"passed","title":"keeps canonical-identity front-matter fields from the English source","duration":1.8800800000000208,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish places the localized body BEFORE the English body, separated by the boundary heading","status":"passed","title":"places the localized body BEFORE the English body, separated by the boundary heading","duration":1.1795590000000402,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish preserves every English body section in the merged output","status":"passed","title":"preserves every English body section in the merged output","duration":1.1544920000000047,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish preserves the localized body content verbatim","status":"passed","title":"preserves the localized body content verbatim","duration":0.7631590000000301,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish emits the localized aside note on the boundary line so readers know why English follows","status":"passed","title":"emits the localized aside note on the boundary line so readers know why English follows","duration":0.8689570000000231,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish falls back to the English body when the localized file has no body content (FM only)","status":"passed","title":"falls back to the English body when the localized file has no body content (FM only)","duration":1.5063499999999976,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish forces language: <lang> even when the localized file forgot to set it","status":"passed","title":"forces language: <lang> even when the localized file forgot to set it","duration":1.3221859999999879,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores empty-string localized title/description so English fallback wins","status":"passed","title":"ignores empty-string localized title/description so English fallback wins","duration":1.428754999999967,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores localizedBriefMarkdown — does NOT rewrite title/description from the brief","status":"passed","title":"ignores localizedBriefMarkdown — does NOT rewrite title/description from the brief","duration":0.7737989999999968,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores localizedBriefMarkdown even when the localized article is missing","status":"passed","title":"ignores localizedBriefMarkdown even when the localized article is missing","duration":1.1150779999999827,"failureMessages":[],"location":{"line":292,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish falls back to English title/description when both localized inputs are missing","status":"passed","title":"falls back to English title/description when both localized inputs are missing","duration":0.6857840000000124,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"sv\"","status":"passed","title":"emits a non-empty H2 + aside note for \"sv\"","duration":0.6601059999999848,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"da\"","status":"passed","title":"emits a non-empty H2 + aside note for \"da\"","duration":0.5625739999999837,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"no\"","status":"passed","title":"emits a non-empty H2 + aside note for \"no\"","duration":0.5231090000000336,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"fi\"","status":"passed","title":"emits a non-empty H2 + aside note for \"fi\"","duration":0.5486169999999788,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"de\"","status":"passed","title":"emits a non-empty H2 + aside note for \"de\"","duration":0.48360499999995454,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"fr\"","status":"passed","title":"emits a non-empty H2 + aside note for \"fr\"","duration":0.5049559999999929,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"es\"","status":"passed","title":"emits a non-empty H2 + aside note for \"es\"","duration":0.5158959999999979,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"nl\"","status":"passed","title":"emits a non-empty H2 + aside note for \"nl\"","duration":0.5177290000000312,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ar\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ar\"","duration":0.5282589999999914,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"he\"","status":"passed","title":"emits a non-empty H2 + aside note for \"he\"","duration":0.5093339999999671,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ja\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ja\"","duration":0.49261200000000827,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ko\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ko\"","duration":0.5261449999999854,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"zh\"","status":"passed","title":"emits a non-empty H2 + aside note for \"zh\"","duration":0.6841309999999794,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]}],"startTime":1787953795304,"endTime":1787953795337.684,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-merge.test.ts"},{"assertionResults":[{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult success branch has ok=true and value","status":"passed","title":"PipelineResult success branch has ok=true and value","duration":4.335527999999954,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult failure branch has ok=false and error","status":"passed","title":"PipelineResult failure branch has ok=false and error","duration":0.9173779999999851,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult success branch supports optional warnings","status":"passed","title":"PipelineResult success branch supports optional warnings","duration":1.5384599999999864,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult failure branch supports optional warnings","status":"passed","title":"PipelineResult failure branch supports optional warnings","duration":0.6308909999999059,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts ValidationDiagnostic supports all severity levels","status":"passed","title":"ValidationDiagnostic supports all severity levels","duration":0.7718449999999848,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts ArticleSection ties markdown to its source file","status":"passed","title":"ArticleSection ties markdown to its source file","duration":0.7817239999999401,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path produces a successful result with minimal analysis folder","status":"passed","title":"produces a successful result with minimal analysis folder","duration":34.01702999999998,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path extracts title from the executive-brief H1","status":"passed","title":"extracts title from the executive-brief H1","duration":3.1966449999999895,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path extracts description from the BLUF paragraph","status":"passed","title":"extracts description from the BLUF paragraph","duration":1.9959370000000263,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path includes YAML front-matter with required fields","status":"passed","title":"includes YAML front-matter with required fields","duration":2.4262730000000374,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path config overrides are wired into the front-matter","status":"passed","title":"config overrides are wired into the front-matter","duration":2.604155999999989,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path aggregates multiple artifacts in canonical order","status":"passed","title":"aggregates multiple artifacts in canonical order","duration":20.333439999999996,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases returns error when subfolder does not exist","status":"passed","title":"returns error when subfolder does not exist","duration":0.7383929999999737,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases returns error when executive-brief.md is missing","status":"passed","title":"returns error when executive-brief.md is missing","duration":0.8017610000000559,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases handles empty executive-brief.md gracefully","status":"passed","title":"handles empty executive-brief.md gracefully","duration":2.091316000000006,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases handles executive-brief.md with only YAML front-matter","status":"passed","title":"handles executive-brief.md with only YAML front-matter","duration":6.066368000000011,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases excludes README.md from aggregation","status":"passed","title":"excludes README.md from aggregation","duration":1.9094450000000052,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases excludes article.md and article.<lang>.md from aggregation","status":"passed","title":"excludes article.md and article.<lang>.md from aggregation","duration":1.9630450000000792,"failureMessages":[],"location":{"line":324,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases handles artifacts with malformed YAML front-matter","status":"passed","title":"handles artifacts with malformed YAML front-matter","duration":1.278925000000072,"failureMessages":[],"location":{"line":339,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases handles supplementary artifacts not in AGGREGATION_ORDER","status":"passed","title":"handles supplementary artifacts not in AGGREGATION_ORDER","duration":2.05973599999993,"failureMessages":[],"location":{"line":366,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) demotes ## to ###","status":"passed","title":"demotes ## to ###","duration":0.7142979999999852,"failureMessages":[],"location":{"line":387,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) demotes ### to ####","status":"passed","title":"demotes ### to ####","duration":0.6263030000000072,"failureMessages":[],"location":{"line":391,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) caps at ###### (does not produce #######)","status":"passed","title":"caps at ###### (does not produce #######)","duration":0.595956000000001,"failureMessages":[],"location":{"line":395,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) leaves H1 untouched (already stripped upstream)","status":"passed","title":"leaves H1 untouched (already stripped upstream)","duration":0.6196199999999408,"failureMessages":[],"location":{"line":399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) preserves headings inside fenced code blocks","status":"passed","title":"preserves headings inside fenced code blocks","duration":0.6019370000000208,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) preserves headings inside tilde-fenced code blocks","status":"passed","title":"preserves headings inside tilde-fenced code blocks","duration":0.549398999999994,"failureMessages":[],"location":{"line":408,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles multiple headings at different levels","status":"passed","title":"handles multiple headings at different levels","duration":0.6114140000000816,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles empty string","status":"passed","title":"handles empty string","duration":0.574226000000067,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles text without headings","status":"passed","title":"handles text without headings","duration":0.6797819999999319,"failureMessages":[],"location":{"line":423,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) does not demote hash characters in non-heading context","status":"passed","title":"does not demote hash characters in non-heading context","duration":0.6319229999999152,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) rewrites relative .md links to GitHub blob URLs","status":"passed","title":"rewrites relative .md links to GitHub blob URLs","duration":0.7033969999999954,"failureMessages":[],"location":{"line":437,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves absolute https:// links","status":"passed","title":"preserves absolute https:// links","duration":0.7323010000000068,"failureMessages":[],"location":{"line":443,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves fragment-only links","status":"passed","title":"preserves fragment-only links","duration":0.9518820000000687,"failureMessages":[],"location":{"line":448,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves mailto: links","status":"passed","title":"preserves mailto: links","duration":0.5668809999999667,"failureMessages":[],"location":{"line":453,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles relative links with anchors","status":"passed","title":"handles relative links with anchors","duration":0.5637749999999642,"failureMessages":[],"location":{"line":458,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles relative paths with ../","status":"passed","title":"handles relative paths with ../","duration":0.592640000000074,"failureMessages":[],"location":{"line":464,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles empty body","status":"passed","title":"handles empty body","duration":0.5960159999999632,"failureMessages":[],"location":{"line":470,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles multiple links in the same line","status":"passed","title":"handles multiple links in the same line","duration":0.6040219999999863,"failureMessages":[],"location":{"line":474,"column":3},"meta":{},"tags":[]}],"startTime":1787953735539,"endTime":1787953735645.604,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-pipeline.test.ts"},{"assertionResults":[{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps HIGH confidence in a green chip","status":"passed","title":"wraps HIGH confidence in a green chip","duration":4.095128000000045,"failureMessages":[],"location":{"line":17,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps MEDIUM confidence in an amber chip","status":"passed","title":"wraps MEDIUM confidence in an amber chip","duration":0.6299089999999978,"failureMessages":[],"location":{"line":24,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps LOW confidence in a red chip","status":"passed","title":"wraps LOW confidence in a red chip","duration":0.48821399999997084,"failureMessages":[],"location":{"line":30,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips handles multiple confidence levels in same string","status":"passed","title":"handles multiple confidence levels in same string","duration":0.5228089999999952,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.5215870000000109,"failureMessages":[],"location":{"line":43,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not modify heading id attributes containing high/medium/low","status":"passed","title":"does not modify heading id attributes containing high/medium/low","duration":0.5889129999999909,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not modify href attributes containing high/medium/low","status":"passed","title":"does not modify href attributes containing high/medium/low","duration":0.49079000000000406,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not inject spans into class or data attributes","status":"passed","title":"does not inject spans into class or data attributes","duration":0.5123199999999883,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges wraps Admiralty codes in styled badges with tooltips","status":"passed","title":"wraps Admiralty codes in styled badges with tooltips","duration":0.8726390000000492,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges handles multiple codes","status":"passed","title":"handles multiple codes","duration":0.6911049999999932,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges does not match non-Admiralty patterns","status":"passed","title":"does not match non-Admiralty patterns","duration":0.7104800000000182,"failureMessages":[],"location":{"line":91,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges does not modify attributes containing Admiralty-like patterns","status":"passed","title":"does not modify attributes containing Admiralty-like patterns","duration":0.5417640000000006,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+7d as urgent","status":"passed","title":"wraps T+7d as urgent","duration":0.6570999999999572,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+30d as near","status":"passed","title":"wraps T+30d as near","duration":0.46278599999999415,"failureMessages":[],"location":{"line":112,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+90d as horizon","status":"passed","title":"wraps T+90d as horizon","duration":0.4607029999999668,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators preserves original text inside span","status":"passed","title":"preserves original text inside span","duration":0.44260799999995015,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators does not modify attributes containing timeline-like patterns","status":"passed","title":"does not modify attributes containing timeline-like patterns","duration":0.47020099999997456,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure wraps Document Analysis H2 in details element","status":"passed","title":"wraps Document Analysis H2 in details element","duration":1.4615359999999669,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure wraps Intelligence Notes in details element","status":"passed","title":"wraps Intelligence Notes in details element","duration":0.5404819999999972,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure does not wrap non-matching headings","status":"passed","title":"does not wrap non-matching headings","duration":0.5762389999999868,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure escapes residual markup in the disclosure summary","status":"passed","title":"escapes residual markup in the disclosure summary","duration":0.7264299999999935,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure strips overlapping tags without reconstituting markup in the summary","status":"passed","title":"strips overlapping tags without reconstituting markup in the summary","duration":0.5682140000000118,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure handles Swedish headings","status":"passed","title":"handles Swedish headings","duration":0.5226289999999949,"failureMessages":[],"location":{"line":182,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc generates TOC from H2 headings","status":"passed","title":"generates TOC from H2 headings","duration":1.4731479999999806,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc wraps the TOC in a collapsible sidebar disclosure","status":"passed","title":"wraps the TOC in a collapsible sidebar disclosure","duration":0.5855660000000285,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc assigns canonical icons and reading-depth layers from the section id","status":"passed","title":"assigns canonical icons and reading-depth layers from the section id","duration":0.7190160000000105,"failureMessages":[],"location":{"line":210,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc falls back to a default icon for unknown dynamic sections","status":"passed","title":"falls back to a default icon for unknown dynamic sections","duration":0.6223449999999957,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc returns empty string for single-section articles","status":"passed","title":"returns empty string for single-section articles","duration":0.5838229999999953,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc uses Swedish label for sv lang","status":"passed","title":"uses Swedish label for sv lang","duration":0.6539539999999988,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc localizes the layer badge label for non-English languages","status":"passed","title":"localizes the layer badge label for non-English languages","duration":0.6148110000000315,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc escapes residual markup in TOC link text","status":"passed","title":"escapes residual markup in TOC link text","duration":0.7900500000000079,"failureMessages":[],"location":{"line":253,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc localizes TOC entry text by language-stable section id for non-English","status":"passed","title":"localizes TOC entry text by language-stable section id for non-English","duration":0.9432360000000131,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc keeps English TOC entry text byte-identical to the body heading","status":"passed","title":"keeps English TOC entry text byte-identical to the body heading","duration":0.6480829999999855,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc reuses the reader-guide per-document label for the per-document section","status":"passed","title":"reuses the reader-guide per-document label for the per-document section","duration":0.6497460000000501,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc falls back to the heading text for sections without a curated localisation","status":"passed","title":"falls back to the heading text for sections without a curated localisation","duration":0.5895739999999705,"failureMessages":[],"location":{"line":292,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter renders English methodology footer","status":"passed","title":"renders English methodology footer","duration":0.7690299999999866,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter renders Swedish methodology footer","status":"passed","title":"renders Swedish methodology footer","duration":0.5565819999999917,"failureMessages":[],"location":{"line":310,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter falls back to English for unsupported languages","status":"passed","title":"falls back to English for unsupported languages","duration":0.5539880000000039,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","applyScannabilityTransforms"],"fullName":"Article Scannability Transforms applyScannabilityTransforms applies inline transforms and returns TOC + footer (no progressive disclosure)","status":"passed","title":"applies inline transforms and returns TOC + footer (no progressive disclosure)","duration":0.9673710000000142,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]}],"startTime":1787953788443,"endTime":1787953788472.9673,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-scannability.test.ts"},{"assertionResults":[{"ancestorTitles":["buildArticleKeywords — EN path (regression baseline)"],"fullName":"buildArticleKeywords — EN path (regression baseline) keeps the original EN ordering and includes the EN core keyword set","status":"passed","title":"keeps the original EN ordering and includes the EN core keyword set","duration":4.888503999999955,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English frontmatter `keywords:` seed","status":"passed","title":"does NOT include the English frontmatter `keywords:` seed","duration":1.0770770000000311,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English Language-Meta `name`","status":"passed","title":"does NOT include the English Language-Meta `name`","duration":0.6129280000000108,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English article-type ID hyphen-slug","status":"passed","title":"does NOT include the English article-type ID hyphen-slug","duration":0.5645470000000046,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include English canonical-path slug parts","status":"passed","title":"does NOT include English canonical-path slug parts","duration":0.6287680000000364,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks DOES include the German core keyword set","status":"passed","title":"DOES include the German core keyword set","duration":0.7993170000000305,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT inject any English `update` word in the publication keyword","status":"passed","title":"does NOT inject any English `update` word in the publication keyword","duration":0.6393279999999777,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks includes the German government keyword (institutional floor)","status":"passed","title":"includes the German government keyword (institutional floor)","duration":0.5175889999999868,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks surfaces the localized article-type label","status":"passed","title":"surfaces the localized article-type label","duration":0.6643640000000346,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT leak EN title tokens (Enshrines / Protection / Abortion) under DE","status":"passed","title":"does NOT leak EN title tokens (Enshrines / Protection / Abortion) under DE","duration":0.5261849999999981,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — Arabic (RTL) localization"],"fullName":"buildArticleKeywords — Arabic (RTL) localization uses native Arabic core keywords and no English leakage","status":"passed","title":"uses native Arabic core keywords and no English leakage","duration":1.3207729999999742,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — Japanese (CJK) localization"],"fullName":"buildArticleKeywords — Japanese (CJK) localization uses native Japanese core keywords and no English leakage","status":"passed","title":"uses native Japanese core keywords and no English leakage","duration":0.7230429999999615,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=en including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=en including Riksdagsmonitor","duration":0.6755559999999718,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=sv including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=sv including Riksdagsmonitor","duration":0.45394999999996344,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=da including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=da including Riksdagsmonitor","duration":0.5163969999999836,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=no including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=no including Riksdagsmonitor","duration":0.4419680000000312,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=fi including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=fi including Riksdagsmonitor","duration":0.5153940000000148,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=de including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=de including Riksdagsmonitor","duration":0.47003100000000586,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=fr including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=fr including Riksdagsmonitor","duration":0.5101960000000076,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=es including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=es including Riksdagsmonitor","duration":0.4838970000000131,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=nl including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=nl including Riksdagsmonitor","duration":0.6627809999999954,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ar including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ar including Riksdagsmonitor","duration":0.5599379999999883,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=he including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=he including Riksdagsmonitor","duration":0.6255820000000085,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ja including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ja including Riksdagsmonitor","duration":0.5051559999999995,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ko including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ko including Riksdagsmonitor","duration":0.4894170000000031,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=zh including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=zh including Riksdagsmonitor","duration":0.5987509999999929,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]}],"startTime":1787953830951,"endTime":1787953830971.5986,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-seo-localized-keywords.test.ts"},{"assertionResults":[{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips a trailing \"and\" connector left after word-boundary truncation","status":"passed","title":"strips a trailing \"and\" connector left after word-boundary truncation","duration":6.6264659999999935,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips a trailing \"with\" connector","status":"passed","title":"strips a trailing \"with\" connector","duration":2.2467169999999896,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression ships short brief H1s as \"{H1} — Riksdagsmonitor\" with NO date prefix","status":"passed","title":"ships short brief H1s as \"{H1} — Riksdagsmonitor\" with NO date prefix","duration":0.9580339999999978,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips trailing connector AND date prefix when H1 just fits without brand","status":"passed","title":"strips trailing connector AND date prefix when H1 just fits without brand","duration":0.5535669999999868,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression never prepends a localized date prefix in any of the 14 supported languages","status":"passed","title":"never prepends a localized date prefix in any of the 14 supported languages","duration":1.9180510000000481,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips Swedish connector \"och\" when truncating a Swedish H1","status":"passed","title":"strips Swedish connector \"och\" when truncating a Swedish H1","duration":0.608019000000013,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips German connector \"und\" when truncating a German H1","status":"passed","title":"strips German connector \"und\" when truncating a German H1","duration":0.5581549999999993,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression preserves a bare trailing uppercase `A` (live: `Plan A`, `Section A`, `Group A`)","status":"passed","title":"preserves a bare trailing uppercase `A` (live: `Plan A`, `Section A`, `Group A`)","duration":0.7114220000000273,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard strips a 2-word noun-phrase tail after the last comma","status":"passed","title":"strips a 2-word noun-phrase tail after the last comma","duration":0.6426240000000121,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard strips a 1-word noun tail (`the`-style determiner is a connector and is already stripped upstream)","status":"passed","title":"strips a 1-word noun tail (`the`-style determiner is a connector and is already stripped upstream)","duration":0.7876640000000066,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves the original text when the tail is too long (likely real clause)","status":"passed","title":"preserves the original text when the tail is too long (likely real clause)","duration":0.5269059999999968,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves the text when the head is short (would over-strip)","status":"passed","title":"preserves the text when the head is short (would over-strip)","duration":0.43124699999998484,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves text with no comma","status":"passed","title":"preserves text with no comma","duration":0.44062500000001137,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves a tail that ends with a sentence terminator (real prose)","status":"passed","title":"preserves a tail that ends with a sentence terminator (real prose)","duration":0.45865799999995716,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]}],"startTime":1787953823322,"endTime":1787953823340.4587,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-seo-title-truncation.test.ts"},{"assertionResults":[{"ancestorTitles":["article-type-i18n","coverage"],"fullName":"article-type-i18n coverage every map entry covers all 14 languages with a non-empty string","status":"passed","title":"every map entry covers all 14 languages with a non-empty string","duration":15.611520999999982,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","coverage"],"fullName":"article-type-i18n coverage every registry article-type id has a localised label map","status":"passed","title":"every registry article-type id has a localised label map","duration":1.177124000000049,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() returns the localised label when both type and language are registered","status":"passed","title":"returns the localised label when both type and language are registered","duration":0.6559080000000108,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() falls back to the supplied English label for unknown type ids","status":"passed","title":"falls back to the supplied English label for unknown type ids","duration":0.391413,"failureMessages":[],"location":{"line":51,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() returns the English entry when lang is \"en\"","status":"passed","title":"returns the English entry when lang is \"en\"","duration":0.5538569999999936,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() preserves RTL strings exactly (Arabic, Hebrew)","status":"passed","title":"preserves RTL strings exactly (Arabic, Hebrew)","duration":0.5181709999999953,"failureMessages":[],"location":{"line":59,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() returns a distinct emoji icon for every registered article type","status":"passed","title":"returns a distinct emoji icon for every registered article type","duration":1.4289359999999647,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() falls back to 🔍 for unknown article-type ids","status":"passed","title":"falls back to 🔍 for unknown article-type ids","duration":0.441737000000046,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() returns the registered icon for known types","status":"passed","title":"returns the registered icon for known types","duration":0.5764289999999619,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]}],"startTime":1787953907316,"endTime":1787953907337.5764,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-type-i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity parses as JSON and declares a semantic version","status":"passed","title":"parses as JSON and declares a semantic version","duration":4.780238999999995,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity declares at least the 13 known article types","status":"passed","title":"declares at least the 13 known article types","duration":2.3227190000000064,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity every type id is unique","status":"passed","title":"every type id is unique","duration":0.520183999999972,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity every subfolder is unique","status":"passed","title":"every subfolder is unique","duration":0.4132940000000076,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — workflow ↔ registry parity"],"fullName":"article-types registry — workflow ↔ registry parity every type with a workflow points to a real news-*.md source","status":"passed","title":"every type with a workflow points to a real news-*.md source","duration":0.8708300000000122,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — workflow ↔ registry parity"],"fullName":"article-types registry — workflow ↔ registry parity every news-*.md (except news-translate) has a registry entry","status":"passed","title":"every news-*.md (except news-translate) has a registry entry","duration":0.643714999999986,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules every long-horizon-forecast declares longHorizonRules","status":"passed","title":"every long-horizon-forecast declares longHorizonRules","duration":0.6919060000000172,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules quarter / year / cycle have ascending tier-C multipliers","status":"passed","title":"quarter / year / cycle have ascending tier-C multipliers","duration":0.6726400000000012,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules cycle horizon is at least 4 years (1460 days)","status":"passed","title":"cycle horizon is at least 4 years (1460 days)","duration":0.6115550000000098,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules election-cycle declares cycle-trajectory.md as an extra artifact","status":"passed","title":"election-cycle declares cycle-trajectory.md as an extra artifact","duration":0.5166169999999966,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules year-ahead and election-cycle mandate PESTLE","status":"passed","title":"year-ahead and election-cycle mandate PESTLE","duration":0.5750170000000026,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence current cycle ends where next cycle begins","status":"passed","title":"current cycle ends where next cycle begins","duration":0.4512149999999906,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence current cycle covers Tidö mandate (2022-09-11 → 2026-09-13)","status":"passed","title":"current cycle covers Tidö mandate (2022-09-11 → 2026-09-13)","duration":0.5021399999999971,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence next cycle ends 2030-09-08","status":"passed","title":"next cycle ends 2030-09-08","duration":0.4196359999999686,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — horizon bands"],"fullName":"article-types registry — horizon bands declares the canonical seven horizon bands","status":"passed","title":"declares the canonical seven horizon bands","duration":0.7836670000000368,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — horizon bands"],"fullName":"article-types registry — horizon bands each band has ascending or equal day-count by horizon","status":"passed","title":"each band has ascending or equal day-count by horizon","duration":0.5740949999999998,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — reference-quality-thresholds parity"],"fullName":"article-types registry — reference-quality-thresholds parity quarter-ahead, year-ahead, election-cycle have threshold blocks","status":"passed","title":"quarter-ahead, year-ahead, election-cycle have threshold blocks","duration":0.517879999999991,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"year-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":1.2777119999999513,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: every declared band exists in horizonBands registry","status":"passed","title":"year-ahead: every declared band exists in horizonBands registry","duration":0.5691560000000209,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"year-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.6327549999999746,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: forwardIndicatorHorizons matches fixture (4 bands)","status":"passed","title":"election-cycle: forwardIndicatorHorizons matches fixture (4 bands)","duration":0.6142600000000016,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: every declared band exists in horizonBands registry","status":"passed","title":"election-cycle: every declared band exists in horizonBands registry","duration":0.5226180000000227,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"election-cycle: WEP ceilings in fixture match horizonBands registry","duration":0.48982699999999113,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"week-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":0.5591670000000022,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: every declared band exists in horizonBands registry","status":"passed","title":"week-ahead: every declared band exists in horizonBands registry","duration":0.6927569999999719,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"week-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.5345009999999775,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: forwardIndicatorHorizons matches fixture (6 bands)","status":"passed","title":"month-ahead: forwardIndicatorHorizons matches fixture (6 bands)","duration":0.5785130000000436,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: every declared band exists in horizonBands registry","status":"passed","title":"month-ahead: every declared band exists in horizonBands registry","duration":0.5340199999999982,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"month-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.5762789999999995,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"quarter-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":0.5633450000000266,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: every declared band exists in horizonBands registry","status":"passed","title":"quarter-ahead: every declared band exists in horizonBands registry","duration":0.6365910000000099,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"quarter-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.6871470000000386,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts six-band coverage: month-ahead declares all 6 bands (72h, week, month, quarter, year, election)","status":"passed","title":"six-band coverage: month-ahead declares all 6 bands (72h, week, month, quarter, year, election)","duration":0.9590049999999906,"failureMessages":[],"location":{"line":280,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts back-compat: single-type articles retain 4-band legacy schema","status":"passed","title":"back-compat: single-type articles retain 4-band legacy schema","duration":0.7652520000000322,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]}],"startTime":1787953822339,"endTime":1787953822366.7651,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n defaults to null when flag is absent","status":"passed","title":"defaults to null when flag is absent","duration":4.601725999999985,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses integer value correctly","status":"passed","title":"parses integer value correctly","duration":0.9285489999999754,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n accepts value 0 (explicit disable)","status":"passed","title":"accepts value 0 (explicit disable)","duration":0.5899740000000975,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n accepts larger values","status":"passed","title":"accepts larger values","duration":0.4595510000000331,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on negative value","status":"passed","title":"throws on negative value","duration":1.5456040000000257,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on non-integer value","status":"passed","title":"throws on non-integer value","duration":0.7887560000000349,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on fractional value","status":"passed","title":"throws on fractional value","duration":0.7621669999999767,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n combines correctly with other flags","status":"passed","title":"combines correctly with other flags","duration":0.7539620000000014,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses --full-text-for-all as a boolean flag","status":"passed","title":"parses --full-text-for-all as a boolean flag","duration":0.5617419999999811,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveAutoFullTextTopN"],"fullName":"resolveAutoFullTextTopN raises long-horizon top-N requests to the floor of 10","status":"passed","title":"raises long-horizon top-N requests to the floor of 10","duration":0.606555999999955,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveAutoFullTextTopN"],"fullName":"resolveAutoFullTextTopN uses all selected documents when --full-text-for-all is enabled","status":"passed","title":"uses all selected documents when --full-text-for-all is enabled","duration":0.5267360000000281,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN returns empty array when topN is 0","status":"passed","title":"returns empty array when topN is 0","duration":1.8535200000000032,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN returns empty array when docs list is empty","status":"passed","title":"returns empty array when docs list is empty","duration":0.7195169999999962,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN fetches full text for top-N documents and persists to full-text/ dir","status":"passed","title":"fetches full text for top-N documents and persists to full-text/ dir","duration":3.1307520000000295,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN only fetches top-N documents even when more docs provided","status":"passed","title":"only fetches top-N documents even when more docs provided","duration":2.611780000000067,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN creates full-text directory automatically","status":"passed","title":"creates full-text directory automatically","duration":1.2204649999999901,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response records success=false when content is below FULL_TEXT_MIN_LENGTH","status":"passed","title":"records success=false when content is below FULL_TEXT_MIN_LENGTH","duration":1.3589439999999513,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response falls back from text to fullText field when text is too short","status":"passed","title":"falls back from text to fullText field when text is too short","duration":1.2770600000000059,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response falls back to html field when text and fullText are too short","status":"passed","title":"falls back to html field when text and fullText are too short","duration":1.2906860000000506,"failureMessages":[],"location":{"line":267,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — fetchDocumentDetails throws"],"fullName":"fetchFullTextForTopN graceful degradation — fetchDocumentDetails throws records success=false with reason when MCP call rejects","status":"passed","title":"records success=false with reason when MCP call rejects","duration":1.4787189999999555,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — fetchDocumentDetails throws"],"fullName":"fetchFullTextForTopN graceful degradation — fetchDocumentDetails throws continues to next document after one fails","status":"passed","title":"continues to next document after one fails","duration":1.6353920000000244,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","dokId resolution"],"fullName":"fetchFullTextForTopN dokId resolution skips documents with no resolvable dok_id","status":"passed","title":"skips documents with no resolvable dok_id","duration":1.1813419999999724,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","dokId resolution"],"fullName":"fetchFullTextForTopN dokId resolution resolves dok_id from dokument_id when dok_id is absent","status":"passed","title":"resolves dok_id from dokument_id when dok_id is absent","duration":1.4481109999999262,"failureMessages":[],"location":{"line":340,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content writes markdown file with header and content","status":"passed","title":"writes markdown file with header and content","duration":1.6101850000000013,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content filePath in outcome is relative to outputDir (not CWD)","status":"passed","title":"filePath in outcome is relative to outputDir (not CWD)","duration":1.3851539999999432,"failureMessages":[],"location":{"line":374,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content sanitizes MP profile text (isPersonProfileText filter)","status":"passed","title":"sanitizes MP profile text (isPersonProfileText filter)","duration":1.2004779999999755,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["serializeDataManifest (via buildWeeklySummaryMarkdown sanity)"],"fullName":"serializeDataManifest (via buildWeeklySummaryMarkdown sanity) buildWeeklySummaryMarkdown still works after refactor","status":"passed","title":"buildWeeklySummaryMarkdown still works after refactor","duration":1.099066999999991,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract parseArgs exposes autoFullTextTopN=2 when flag is set","status":"passed","title":"parseArgs exposes autoFullTextTopN=2 when flag is set","duration":0.9235390000000052,"failureMessages":[],"location":{"line":431,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract fetchFullTextForTopN returns outcome with filePath for successful fetch","status":"passed","title":"fetchFullTextForTopN returns outcome with filePath for successful fetch","duration":1.60837099999992,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract analysis-gate can determine if top-2 full texts are available from outcomes","status":"passed","title":"analysis-gate can determine if top-2 full texts are available from outcomes","duration":1.5156979999999294,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract serializes coverage-state and deferred queue sections in the manifest","status":"passed","title":"serializes coverage-state and deferred queue sections in the manifest","duration":1.821649999999977,"failureMessages":[],"location":{"line":471,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract escapes pipes and collapses newlines in diagnostic manifest cells","status":"passed","title":"escapes pipes and collapses newlines in diagnostic manifest cells","duration":1.3825590000000147,"failureMessages":[],"location":{"line":537,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract escapes backslashes before pipes so escaped-pipe sentinels are unambiguous","status":"passed","title":"escapes backslashes before pipes so escaped-pipe sentinels are unambiguous","duration":1.1899079999999458,"failureMessages":[],"location":{"line":589,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) treats explicit indexing phrases as not_indexed","status":"passed","title":"treats explicit indexing phrases as not_indexed","duration":1.1658429999999953,"failureMessages":[],"location":{"line":644,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) treats transport-level failures as fetch_error, NOT not_indexed","status":"passed","title":"treats transport-level failures as fetch_error, NOT not_indexed","duration":1.1371489999999085,"failureMessages":[],"location":{"line":650,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) only treats bare \"not found\" as not_indexed when paired with the dok_id","status":"passed","title":"only treats bare \"not found\" as not_indexed when paired with the dok_id","duration":1.09241499999996,"failureMessages":[],"location":{"line":658,"column":3},"meta":{},"tags":[]}],"startTime":1787953666729,"endTime":1787953666778.0925,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/auto-full-text-top-n.test.ts"},{"assertionResults":[{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should exist in DOM","status":"passed","title":"should exist in DOM","duration":7.35496900000004,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have back-to-top class","status":"passed","title":"should have back-to-top class","duration":1.2588170000000218,"failureMessages":[],"location":{"line":41,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have proper aria-label for accessibility","status":"passed","title":"should have proper aria-label for accessibility","duration":0.7393749999999955,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have arrow content","status":"passed","title":"should have arrow content","duration":0.7227530000000115,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have id=\"back-to-top\"","status":"passed","title":"should have id=\"back-to-top\"","duration":0.76636400000001,"failureMessages":[],"location":{"line":53,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should not have visible class initially","status":"passed","title":"should not have visible class initially","duration":0.612446000000034,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should add visible class when pageYOffset > 300","status":"passed","title":"should add visible class when pageYOffset > 300","duration":0.8842250000000149,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should remove visible class when pageYOffset <= 300","status":"passed","title":"should remove visible class when pageYOffset <= 300","duration":0.8134529999999813,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should remove visible class when pageYOffset is 0","status":"passed","title":"should remove visible class when pageYOffset is 0","duration":0.839492000000007,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should toggle correctly at boundary (300 = hidden, 301 = visible)","status":"passed","title":"should toggle correctly at boundary (300 = hidden, 301 = visible)","duration":0.7091279999999642,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should support scroll event listener registration","status":"passed","title":"should support scroll event listener registration","duration":3.5700140000000147,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should support smooth scrolling API","status":"passed","title":"should support smooth scrolling API","duration":0.7839969999999994,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should call scrollTo with smooth behavior when no motion preference","status":"passed","title":"should call scrollTo with smooth behavior when no motion preference","duration":1.6254330000000436,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should call scrollTo with auto behavior when prefers-reduced-motion","status":"passed","title":"should call scrollTo with auto behavior when prefers-reduced-motion","duration":1.07038399999999,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should always scroll to top: 0","status":"passed","title":"should always scroll to top: 0","duration":1.5563830000000394,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should support click event listener registration","status":"passed","title":"should support click event listener registration","duration":1.0796009999999683,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should check prefers-reduced-motion media query","status":"passed","title":"should check prefers-reduced-motion media query","duration":1.0505269999999882,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should detect when user prefers reduced motion","status":"passed","title":"should detect when user prefers reduced motion","duration":1.04051800000002,"failureMessages":[],"location":{"line":216,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should use auto behavior for reduced-motion users","status":"passed","title":"should use auto behavior for reduced-motion users","duration":0.8193840000000137,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should use smooth behavior for standard users","status":"passed","title":"should use smooth behavior for standard users","duration":0.752448999999956,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle missing button gracefully","status":"passed","title":"should handle missing button gracefully","duration":0.853868000000034,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle large scroll values","status":"passed","title":"should handle large scroll values","duration":0.8713020000000142,"failureMessages":[],"location":{"line":258,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle negative scroll values","status":"passed","title":"should handle negative scroll values","duration":0.873395999999957,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button — progressive-enhancement auto-inject"],"fullName":"Back to Top Button — progressive-enhancement auto-inject injects the button when the authored markup is missing","status":"passed","title":"injects the button when the authored markup is missing","duration":2.8070060000000012,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button — progressive-enhancement auto-inject"],"fullName":"Back to Top Button — progressive-enhancement auto-inject reuses the authored button when markup is already present","status":"passed","title":"reuses the authored button when markup is already present","duration":3.9388640000000237,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]}],"startTime":1787953820882,"endTime":1787953820919.939,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/back-to-top.test.js"},{"assertionResults":[{"ancestorTitles":["backfill-news-og-locale-alternate.ts","idempotency"],"fullName":"backfill-news-og-locale-alternate.ts idempotency skips files that already contain og:locale:alternate","status":"passed","title":"skips files that already contain og:locale:alternate","duration":3.8723000000000525,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","safety: no og:locale tag"],"fullName":"backfill-news-og-locale-alternate.ts safety: no og:locale tag does not invent an og:locale block when none exists","status":"passed","title":"does not invent an og:locale block when none exists","duration":0.9966760000000363,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","safety: unknown locale"],"fullName":"backfill-news-og-locale-alternate.ts safety: unknown locale skips files whose og:locale content is not in the lookup table","status":"passed","title":"skips files whose og:locale content is not in the lookup table","duration":0.5508209999999849,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=en (en_US)","status":"passed","title":"injects exactly 13 alternates for lang=en (en_US)","duration":1.2613010000000031,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=sv (sv_SE)","status":"passed","title":"injects exactly 13 alternates for lang=sv (sv_SE)","duration":0.7877050000000168,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=da (da_DK)","status":"passed","title":"injects exactly 13 alternates for lang=da (da_DK)","duration":0.6391160000000013,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=no (nb_NO)","status":"passed","title":"injects exactly 13 alternates for lang=no (nb_NO)","duration":0.7585710000000176,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=fi (fi_FI)","status":"passed","title":"injects exactly 13 alternates for lang=fi (fi_FI)","duration":0.6122059999999578,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=de (de_DE)","status":"passed","title":"injects exactly 13 alternates for lang=de (de_DE)","duration":1.0669980000000123,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=fr (fr_FR)","status":"passed","title":"injects exactly 13 alternates for lang=fr (fr_FR)","duration":0.9943610000000263,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=es (es_ES)","status":"passed","title":"injects exactly 13 alternates for lang=es (es_ES)","duration":0.9327670000000126,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=nl (nl_NL)","status":"passed","title":"injects exactly 13 alternates for lang=nl (nl_NL)","duration":0.8631060000000161,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ar (ar_SA)","status":"passed","title":"injects exactly 13 alternates for lang=ar (ar_SA)","duration":0.9229080000000067,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=he (he_IL)","status":"passed","title":"injects exactly 13 alternates for lang=he (he_IL)","duration":0.809285999999986,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ja (ja_JP)","status":"passed","title":"injects exactly 13 alternates for lang=ja (ja_JP)","duration":1.155033000000003,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ko (ko_KR)","status":"passed","title":"injects exactly 13 alternates for lang=ko (ko_KR)","duration":0.7805409999999711,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=zh (zh_CN)","status":"passed","title":"injects exactly 13 alternates for lang=zh (zh_CN)","duration":0.7447940000000131,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves 2-space leading indentation","status":"passed","title":"preserves 2-space leading indentation","duration":0.6210530000000176,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves 4-space leading indentation","status":"passed","title":"preserves 4-space leading indentation","duration":0.5065789999999879,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves zero leading indentation","status":"passed","title":"preserves zero leading indentation","duration":0.49300300000004427,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","idempotency on second pass"],"fullName":"backfill-news-og-locale-alternate.ts idempotency on second pass running the backfill twice produces the same result as running it once","status":"passed","title":"running the backfill twice produces the same result as running it once","duration":0.6863049999999475,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness every supported language has a unique og:locale value","status":"passed","title":"every supported language has a unique og:locale value","duration":0.48703199999999924,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Norwegian uses BCP-47 nb_NO (Norwegian Bokmål)","status":"passed","title":"Norwegian uses BCP-47 nb_NO (Norwegian Bokmål)","duration":0.5550289999999904,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Chinese uses zh_CN","status":"passed","title":"Chinese uses zh_CN","duration":0.45207700000003115,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Arabic uses ar_SA","status":"passed","title":"Arabic uses ar_SA","duration":0.4601519999999937,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization rewrites no_NO → nb_NO and injects 13 alternates","status":"passed","title":"rewrites no_NO → nb_NO and injects 13 alternates","duration":0.622175000000027,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization rewrites en_GB → en_US and injects 13 alternates","status":"passed","title":"rewrites en_GB → en_US and injects 13 alternates","duration":0.6444869999999696,"failureMessages":[],"location":{"line":171,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization does not flag canonical locales as normalized","status":"passed","title":"does not flag canonical locales as normalized","duration":0.5160060000000044,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization normalization is idempotent on second pass","status":"passed","title":"normalization is idempotent on second pass","duration":0.5569830000000024,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]}],"startTime":1787953841043,"endTime":1787953841068.557,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-news-og-locale-alternate.test.ts"},{"assertionResults":[{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html mirrors the browser stats-loader STAT_MAPPINGS exactly","status":"passed","title":"mirrors the browser stats-loader STAT_MAPPINGS exactly","duration":4.778137000000015,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html builds a lookup from a representative CSV slice","status":"passed","title":"builds a lookup from a representative CSV slice","duration":15.238623000000018,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html rewrites only the text content of matching stat spans","status":"passed","title":"rewrites only the text content of matching stat spans","duration":1.2333399999999983,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html is idempotent — re-baking concrete values is a no-op for those","status":"passed","title":"is idempotent — re-baking concrete values is a no-op for those","duration":0.5662090000000148,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html does not match across element boundaries","status":"passed","title":"does not match across element boundaries","duration":0.5614209999999957,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]}],"startTime":1787953892752,"endTime":1787953892774.5662,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/bake-stats-html.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines all ten HD-prefixed bill IDs from the brief","status":"passed","title":"mines all ten HD-prefixed bill IDs from the brief","duration":4.36098400000003,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines committee codes only when they appear in parens or with report digits","status":"passed","title":"mines committee codes only when they appear in parens or with report digits","duration":0.6133580000000052,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines party codes only from parenthetical lists (gating against bare-word noise)","status":"passed","title":"mines party codes only from parenthetical lists (gating against bare-word noise)","duration":0.4680670000000191,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) does NOT include section-header prose words as named entities","status":"passed","title":"does NOT include section-header prose words as named entities","duration":1.4552140000000122,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) does NOT produce multiline-spanning named entities","status":"passed","title":"does NOT produce multiline-spanning named entities","duration":0.3544239999999945,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 60-Second Read"],"fullName":"extractHeadlineSection — 60-Second Read finds the 60-Second Read section and returns its bullet lines","status":"passed","title":"finds the 60-Second Read section and returns its bullet lines","duration":2.0579830000000356,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 60-Second Read"],"fullName":"extractHeadlineSection — 60-Second Read returns heading=null and empty bullets when no headline section is present","status":"passed","title":"returns heading=null and empty bullets when no headline section is present","duration":0.9795239999999694,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["flattenBriefEntities — editorial priority ordering"],"fullName":"flattenBriefEntities — editorial priority ordering puts bill IDs ahead of committee codes ahead of party codes","status":"passed","title":"puts bill IDs ahead of committee codes ahead of party codes","duration":0.9571819999999889,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — empty / null safety"],"fullName":"extractBriefEntities — empty / null safety returns empty arrays for empty input","status":"passed","title":"returns empty arrays for empty input","duration":0.718373999999983,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — empty / null safety"],"fullName":"extractBriefEntities — empty / null safety CJK locales (no Latin capitals) mine universal IDs only, no named entities","status":"passed","title":"CJK locales (no Latin capitals) mine universal IDs only, no named entities","duration":0.7037980000000061,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [sv] matches \"## ⚡ 60 sekunders läsning\"","status":"passed","title":"[sv] matches \"## ⚡ 60 sekunders läsning\"","duration":0.7413579999999911,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [sv] matches \"## ⚡ 60-sekunders underrättelsepunkter\"","status":"passed","title":"[sv] matches \"## ⚡ 60-sekunders underrättelsepunkter\"","duration":0.45688499999999976,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [da] matches \"## ⚡ 60 sekunders læsning\"","status":"passed","title":"[da] matches \"## ⚡ 60 sekunders læsning\"","duration":0.5007080000000315,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [da] matches \"## ⚡ 60 sekunders efterretningspunkter\"","status":"passed","title":"[da] matches \"## ⚡ 60 sekunders efterretningspunkter\"","duration":0.4397040000000061,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [no] matches \"## ⚡ 60 sekunders lesning\"","status":"passed","title":"[no] matches \"## ⚡ 60 sekunders lesning\"","duration":0.5269569999999817,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [no] matches \"## ⚡ 60 sekunders etterretningspunkter\"","status":"passed","title":"[no] matches \"## ⚡ 60 sekunders etterretningspunkter\"","duration":0.48721199999999953,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fi] matches \"## ⚡ 60 sekunnin lukeminen\"","status":"passed","title":"[fi] matches \"## ⚡ 60 sekunnin lukeminen\"","duration":0.5807570000000055,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fi] matches \"## ⚡ 60 sekunnin tiedustelutiivistelmä\"","status":"passed","title":"[fi] matches \"## ⚡ 60 sekunnin tiedustelutiivistelmä\"","duration":0.45064400000001115,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [de] matches \"## ⚡ 60 Sekunden-Lektüre\"","status":"passed","title":"[de] matches \"## ⚡ 60 Sekunden-Lektüre\"","duration":0.5120979999999804,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [de] matches \"## ⚡ 60-Sekunden nachrichtendienstliche Punkte\"","status":"passed","title":"[de] matches \"## ⚡ 60-Sekunden nachrichtendienstliche Punkte\"","duration":0.46501999999998134,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fr] matches \"## ⚡ Lecture en 60 secondes\"","status":"passed","title":"[fr] matches \"## ⚡ Lecture en 60 secondes\"","duration":0.5651979999999526,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fr] matches \"## ⚡ Points de renseignement en 60 secondes\"","status":"passed","title":"[fr] matches \"## ⚡ Points de renseignement en 60 secondes\"","duration":0.5515419999999835,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] matches \"## ⚡ Lectura de 60 segundos\"","status":"passed","title":"[es] matches \"## ⚡ Lectura de 60 segundos\"","duration":0.5465940000000273,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] matches \"## ⚡ Puntos de inteligencia en 60 segundos\"","status":"passed","title":"[es] matches \"## ⚡ Puntos de inteligencia en 60 segundos\"","duration":0.5289100000000531,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [nl] matches \"## ⚡ 60 seconden lezing\"","status":"passed","title":"[nl] matches \"## ⚡ 60 seconden lezing\"","duration":0.47998799999999164,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [nl] matches \"## ⚡ 60 seconden inlichtingenpunten\"","status":"passed","title":"[nl] matches \"## ⚡ 60 seconden inlichtingenpunten\"","duration":0.5569830000000024,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ar] matches \"## ⚡ قراءة 60 ثانية\"","status":"passed","title":"[ar] matches \"## ⚡ قراءة 60 ثانية\"","duration":0.4718040000000201,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ar] matches \"## ⚡ نقاط الاستخبارات في 60 ثانية\"","status":"passed","title":"[ar] matches \"## ⚡ نقاط الاستخبارات في 60 ثانية\"","duration":0.5688349999999787,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [he] matches \"## ⚡ קריאה של 60 שניות\"","status":"passed","title":"[he] matches \"## ⚡ קריאה של 60 שניות\"","duration":0.5227280000000292,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [he] matches \"## ⚡ נקודות מודיעין ב-60 שניות\"","status":"passed","title":"[he] matches \"## ⚡ נקודות מודיעין ב-60 שניות\"","duration":0.5603790000000117,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ja] matches \"## ⚡ 60秒で読む\"","status":"passed","title":"[ja] matches \"## ⚡ 60秒で読む\"","duration":0.7570069999999873,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ja] matches \"## ⚡ 60秒インテリジェンスポイント\"","status":"passed","title":"[ja] matches \"## ⚡ 60秒インテリジェンスポイント\"","duration":0.7537310000000161,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ko] matches \"## ⚡ 60초 읽기\"","status":"passed","title":"[ko] matches \"## ⚡ 60초 읽기\"","duration":0.5786030000000437,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ko] matches \"## ⚡ 60초 인텔리전스 포인트\"","status":"passed","title":"[ko] matches \"## ⚡ 60초 인텔리전스 포인트\"","duration":0.7881849999999986,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] matches \"## ⚡ 60秒速读\"","status":"passed","title":"[zh] matches \"## ⚡ 60秒速读\"","duration":0.7499540000000025,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] matches \"## ⚡ 60秒情报要点\"","status":"passed","title":"[zh] matches \"## ⚡ 60秒情报要点\"","duration":0.6311210000000074,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [en] EN dictionary still matches `60-Second Read` (regression guard)","status":"passed","title":"[en] EN dictionary still matches `60-Second Read` (regression guard)","duration":0.6771779999999694,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] numbered list bullets (1. 2. …) are collected from Lectura en 60 segundos","status":"passed","title":"[es] numbered list bullets (1. 2. …) are collected from Lectura en 60 segundos","duration":0.7929440000000341,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] numbered list bullets (1. 2. …) are collected from 60秒速读","status":"passed","title":"[zh] numbered list bullets (1. 2. …) are collected from 60秒速读","duration":0.6693829999999821,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]}],"startTime":1787953821380,"endTime":1787953821410.6694,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/brief-extractor.test.ts"},{"assertionResults":[{"ancestorTitles":["brief-prefixes — dictionary coverage"],"fullName":"brief-prefixes — dictionary coverage contains entries for every supported language","status":"passed","title":"contains entries for every supported language","duration":4.634225000000015,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — dictionary coverage"],"fullName":"brief-prefixes — dictionary coverage every entry is a non-empty literal string","status":"passed","title":"every entry is a non-empty literal string","duration":9.295453000000009,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching returns the same RegExp instance across calls for the same language","status":"passed","title":"returns the same RegExp instance across calls for the same language","duration":1.1220799999999826,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching returns distinct compiled regexes for distinct languages","status":"passed","title":"returns distinct compiled regexes for distinct languages","duration":1.473228000000006,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching caches the result for every supported language","status":"passed","title":"caches the result for every supported language","duration":1.034877999999992,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching reset cache helper clears prior compilations","status":"passed","title":"reset cache helper clears prior compilations","duration":0.6208520000000135,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'en'","status":"passed","title":"strips the boilerplate prefix for 'en'","duration":0.7623570000000086,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'sv'","status":"passed","title":"strips the boilerplate prefix for 'sv'","duration":0.5962059999999951,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'da'","status":"passed","title":"strips the boilerplate prefix for 'da'","duration":0.7549439999999663,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'no'","status":"passed","title":"strips the boilerplate prefix for 'no'","duration":0.6708659999999895,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'fi'","status":"passed","title":"strips the boilerplate prefix for 'fi'","duration":0.6745329999999967,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'de'","status":"passed","title":"strips the boilerplate prefix for 'de'","duration":0.6369530000000054,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'fr'","status":"passed","title":"strips the boilerplate prefix for 'fr'","duration":0.586387000000002,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'es'","status":"passed","title":"strips the boilerplate prefix for 'es'","duration":0.5869490000000042,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'nl'","status":"passed","title":"strips the boilerplate prefix for 'nl'","duration":0.5882710000000202,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ar'","status":"passed","title":"strips the boilerplate prefix for 'ar'","duration":0.5761090000000308,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'he'","status":"passed","title":"strips the boilerplate prefix for 'he'","duration":0.5792849999999703,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ja'","status":"passed","title":"strips the boilerplate prefix for 'ja'","duration":0.5890029999999911,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ko'","status":"passed","title":"strips the boilerplate prefix for 'ko'","duration":0.5832920000000286,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'zh'","status":"passed","title":"strips the boilerplate prefix for 'zh'","duration":0.5654789999999821,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix returns the text unchanged when no prefix matches","status":"passed","title":"returns the text unchanged when no prefix matches","duration":0.8067199999999843,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix matches case-insensitively (UPPERCASE prefix)","status":"passed","title":"matches case-insensitively (UPPERCASE prefix)","duration":0.556933000000015,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix longer compound prefix wins over its shorter substring","status":"passed","title":"longer compound prefix wins over its shorter substring","duration":0.5618420000000128,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Underrättelsebriefing — Sverige Antar…'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Underrättelsebriefing — Sverige Antar…'","duration":0.4384410000000116,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Verkställande sammanfattning — Riksda…'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Verkställande sammanfattning — Riksda…'","duration":0.4580680000000257,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Kortanalys — Budgetproposition 2026'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Kortanalys — Budgetproposition 2026'","duration":0.38522100000000137,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['da'] strips corpus-observed prefix: 'Efterretningsbriefing — Parlamentsval…'","status":"passed","title":"['da'] strips corpus-observed prefix: 'Efterretningsbriefing — Parlamentsval…'","duration":0.5031020000000126,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['da'] strips corpus-observed prefix: 'Eksekutiv resumé — Parlamentet Vedtag…'","status":"passed","title":"['da'] strips corpus-observed prefix: 'Eksekutiv resumé — Parlamentet Vedtag…'","duration":0.43726799999996047,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['no'] strips corpus-observed prefix: 'Etterretningsbriefing — Stortingets V…'","status":"passed","title":"['no'] strips corpus-observed prefix: 'Etterretningsbriefing — Stortingets V…'","duration":0.46711399999998093,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['no'] strips corpus-observed prefix: 'Ledersammendrag — Ny Migrasjonslov Ve…'","status":"passed","title":"['no'] strips corpus-observed prefix: 'Ledersammendrag — Ny Migrasjonslov Ve…'","duration":0.4574060000000486,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fi'] strips corpus-observed prefix: 'Johtoryhmän tiivistelmä — Eduskunta H…'","status":"passed","title":"['fi'] strips corpus-observed prefix: 'Johtoryhmän tiivistelmä — Eduskunta H…'","duration":0.5632039999999847,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fi'] strips corpus-observed prefix: 'Johdon tiivistelmä — Budjettiesitys 2…'","status":"passed","title":"['fi'] strips corpus-observed prefix: 'Johdon tiivistelmä — Budjettiesitys 2…'","duration":0.5395809999999983,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['de'] strips corpus-observed prefix: 'Exekutivzusammenfassung — Bundestag V…'","status":"passed","title":"['de'] strips corpus-observed prefix: 'Exekutivzusammenfassung — Bundestag V…'","duration":0.5616110000000276,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['de'] strips corpus-observed prefix: 'Kurzanalyse — Migrationspolitik 2026'","status":"passed","title":"['de'] strips corpus-observed prefix: 'Kurzanalyse — Migrationspolitik 2026'","duration":0.4837259999999901,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fr'] strips corpus-observed prefix: 'Synthèse — Le Parlement Suédois Vote …'","status":"passed","title":"['fr'] strips corpus-observed prefix: 'Synthèse — Le Parlement Suédois Vote …'","duration":0.5481059999999616,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fr'] strips corpus-observed prefix: 'Note de synthèse exécutive — Réforme …'","status":"passed","title":"['fr'] strips corpus-observed prefix: 'Note de synthèse exécutive — Réforme …'","duration":2.10706399999998,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['es'] strips corpus-observed prefix: 'Nota ejecutiva — El Parlamento Sueco …'","status":"passed","title":"['es'] strips corpus-observed prefix: 'Nota ejecutiva — El Parlamento Sueco …'","duration":0.4381999999999948,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['nl'] strips corpus-observed prefix: 'Uitvoerende samenvatting — Het Zweeds…'","status":"passed","title":"['nl'] strips corpus-observed prefix: 'Uitvoerende samenvatting — Het Zweeds…'","duration":0.5739049999999679,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['nl'] strips corpus-observed prefix: 'Managementsamenvatting — Migratieherv…'","status":"passed","title":"['nl'] strips corpus-observed prefix: 'Managementsamenvatting — Migratieherv…'","duration":0.37720600000000104,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ar'] strips corpus-observed prefix: 'الملخص التنفيذي — البرلمان السويدي يص…'","status":"passed","title":"['ar'] strips corpus-observed prefix: 'الملخص التنفيذي — البرلمان السويدي يص…'","duration":0.4428490000000238,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ar'] strips corpus-observed prefix: 'إحاطة استخباراتية — تصويت مهم في البر…'","status":"passed","title":"['ar'] strips corpus-observed prefix: 'إحاطة استخباراتية — تصويت مهم في البر…'","duration":0.38567199999999957,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['he'] strips corpus-observed prefix: 'סיכום מנהלים — הפרלמנט השוודי מצביע ע…'","status":"passed","title":"['he'] strips corpus-observed prefix: 'סיכום מנהלים — הפרלמנט השוודי מצביע ע…'","duration":0.6533129999999687,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['he'] strips corpus-observed prefix: 'תדריך מנהלים — חקיקה חדשה בשוודיה'","status":"passed","title":"['he'] strips corpus-observed prefix: 'תדריך מנהלים — חקיקה חדשה בשוודיה'","duration":0.4191240000000107,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ja'] strips corpus-observed prefix: '情報ブリーフィング — スウェーデン議会が移民改革を可決'","status":"passed","title":"['ja'] strips corpus-observed prefix: '情報ブリーフィング — スウェーデン議会が移民改革を可決'","duration":0.5054569999999785,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ja'] strips corpus-observed prefix: 'インテリジェンスブリーフィング — 重要な立法決定'","status":"passed","title":"['ja'] strips corpus-observed prefix: 'インテリジェンスブリーフィング — 重要な立法決定'","duration":0.42273099999999886,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ko'] strips corpus-observed prefix: '집행 브리핑 — 스웨덴 의회가 이민법을 통과'","status":"passed","title":"['ko'] strips corpus-observed prefix: '집행 브리핑 — 스웨덴 의회가 이민법을 통과'","duration":0.5130100000000084,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ko'] strips corpus-observed prefix: '임원 브리핑 — 중요한 입법 결정'","status":"passed","title":"['ko'] strips corpus-observed prefix: '임원 브리핑 — 중요한 입법 결정'","duration":0.4402340000000322,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['zh'] strips corpus-observed prefix: '执行简报 — 瑞典议会通过移民改革法案'","status":"passed","title":"['zh'] strips corpus-observed prefix: '执行简报 — 瑞典议会通过移民改革法案'","duration":0.55072100000001,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['zh'] strips corpus-observed prefix: '行政简报 — 重要立法决定'","status":"passed","title":"['zh'] strips corpus-observed prefix: '行政简报 — 重要立法决定'","duration":0.6747529999999529,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]}],"startTime":1787953825866,"endTime":1787953825910.6748,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/brief-prefixes.test.ts"},{"assertionResults":[{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should store data via loadText and cache under the module prefix","status":"passed","title":"should store data via loadText and cache under the module prefix","duration":7.059045999999967,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should evict only prefixed entries on QuotaExceededError and retry","status":"passed","title":"should evict only prefixed entries on QuotaExceededError and retry","duration":1.2941730000000007,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should NOT evict on SecurityError (storage disabled)","status":"passed","title":"should NOT evict on SecurityError (storage disabled)","duration":0.8748580000000175,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Election-cycle cache eviction"],"fullName":"Election-cycle cache eviction should evict only election-cycle entries on QuotaExceededError","status":"passed","title":"should evict only election-cycle entries on QuotaExceededError","duration":29.696957999999995,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Election-cycle cache eviction"],"fullName":"Election-cycle cache eviction should NOT evict on SecurityError (storage disabled)","status":"passed","title":"should NOT evict on SecurityError (storage disabled)","duration":0.9248010000000022,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader eviction strategy"],"fullName":"Shared data-loader eviction strategy should evict oldest half of PREFIXED cache entries by timestamp","status":"passed","title":"should evict oldest half of PREFIXED cache entries by timestamp","duration":0.815477000000044,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader eviction strategy"],"fullName":"Shared data-loader eviction strategy should evict at least one entry even when only one exists","status":"passed","title":"should evict at least one entry even when only one exists","duration":0.5361039999999662,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]}],"startTime":1787953821839,"endTime":1787953821881.5361,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cache-eviction.test.ts"},{"assertionResults":[{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch emits normalized calendar status for an org-scoped fetch","status":"passed","title":"emits normalized calendar status for an org-scoped fetch","duration":4.6064250000000015,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch captures fetch errors without throwing","status":"passed","title":"captures fetch errors without throwing","duration":0.8539490000000001,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch filters scoped events in injected MCP client mode","status":"passed","title":"filters scoped events in injected MCP client mode","duration":1.5381800000000112,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]}],"startTime":1787953927437,"endTime":1787953927444.538,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/calendar-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data returns empty catalog for empty data root","status":"passed","title":"returns empty catalog for empty data root","duration":5.826740000000029,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs proposition files","status":"passed","title":"catalogs proposition files","duration":3.0100360000000137,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data detects existing analysis files","status":"passed","title":"detects existing analysis files","duration":1.1235829999999964,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data filters by type","status":"passed","title":"filters by type","duration":0.9581029999999942,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data filters pending-only","status":"passed","title":"filters pending-only","duration":1.58680099999998,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data excludes .meta.json files from entries","status":"passed","title":"excludes .meta.json files from entries","duration":1.230673999999965,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles nested date directories (votes/YYYY-MM-DD/)","status":"passed","title":"handles nested date directories (votes/YYYY-MM-DD/)","duration":1.0750229999999874,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs documents/votes/ for votes without valid datum","status":"passed","title":"catalogs documents/votes/ for votes without valid datum","duration":0.9271160000000123,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data deduplicates votes appearing in both documents/votes and votes/YYYY-MM-DD","status":"passed","title":"deduplicates votes appearing in both documents/votes and votes/YYYY-MM-DD","duration":1.701755999999989,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles malformed meta.json gracefully","status":"passed","title":"handles malformed meta.json gracefully","duration":1.052129999999977,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data records file size","status":"passed","title":"records file size","duration":0.9450300000000311,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs multiple types at once","status":"passed","title":"catalogs multiple types at once","duration":1.8551740000000336,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data generates analysis paths alongside data files","status":"passed","title":"generates analysis paths alongside data files","duration":0.8624250000000302,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles nested type subdirectories with duplicate basenames","status":"passed","title":"handles nested type subdirectories with duplicate basenames","duration":1.1649610000000052,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]}],"startTime":1787953840090,"endTime":1787953840114.165,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/catalog-downloaded-data.test.ts"},{"assertionResults":[{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth parses a valid JSON config and instantiates Chart.js","status":"passed","title":"parses a valid JSON config and instantiates Chart.js","duration":6.351392000000033,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth rejects configs whose raw attribute contains a function literal","status":"passed","title":"rejects configs whose raw attribute contains a function literal","duration":2.628130999999996,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth rejects configs with function literal and additional whitespace variants","status":"passed","title":"rejects configs with function literal and additional whitespace variants","duration":1.7953520000000367,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth ignores canvases with missing or malformed data-chart-config","status":"passed","title":"ignores canvases with missing or malformed data-chart-config","duration":1.958517000000029,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion disables animation on parsed config when user prefers reduced motion","status":"passed","title":"disables animation on parsed config when user prefers reduced motion","duration":1.1144370000000094,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion preserves original animation settings when user has no reduced-motion preference","status":"passed","title":"preserves original animation settings when user has no reduced-motion preference","duration":1.7825179999999818,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion clears animations/transitions objects when reduced-motion is requested","status":"passed","title":"clears animations/transitions objects when reduced-motion is requested","duration":1.1174330000000054,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion handles configs without an options field gracefully","status":"passed","title":"handles configs without an options field gracefully","duration":0.9944409999999948,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]}],"startTime":1787953891344,"endTime":1787953891361.9944,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chart-init.test.js"},{"assertionResults":[{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes YAML frontmatter","status":"passed","title":"removes YAML frontmatter","duration":4.196146999999996,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes code fences","status":"passed","title":"removes code fences","duration":0.6243590000000268,"failureMessages":[],"location":{"line":29,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes inline code","status":"passed","title":"removes inline code","duration":0.5379970000000185,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter does NOT strip body text between two `---` thematic breaks (regression: regex `/m` flag)","status":"passed","title":"does NOT strip body text between two `---` thematic breaks (regression: regex `/m` flag)","duration":0.4752700000000232,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords extracts lowercase words","status":"passed","title":"extracts lowercase words","duration":1.224232000000029,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords handles Swedish characters","status":"passed","title":"handles Swedish characters","duration":1.2156049999999823,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords returns empty array for no words","status":"passed","title":"returns empty array for no words","duration":0.5244519999999966,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity detects 100% English content","status":"passed","title":"detects 100% English content","duration":1.0215929999999958,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity detects heavily Swedish content","status":"passed","title":"detects heavily Swedish content","duration":1.03751299999999,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity handles empty file","status":"passed","title":"handles empty file","duration":0.5556199999999762,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles finds regular markdown files","status":"passed","title":"finds regular markdown files","duration":1.6742750000000228,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes executive-brief_<lang>.md files","status":"passed","title":"excludes executive-brief_<lang>.md files","duration":0.8748580000000175,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes pass1/ subdirectories","status":"passed","title":"excludes pass1/ subdirectories","duration":0.7861619999999903,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes data-download-manifest.md","status":"passed","title":"excludes data-download-manifest.md","duration":0.6283060000000091,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes full-text/ subdirectories (raw downloaded Swedish source material)","status":"passed","title":"excludes full-text/ subdirectories (raw downloaded Swedish source material)","duration":0.8219190000000367,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage passes for all-English artifacts","status":"passed","title":"passes for all-English artifacts","duration":0.9146420000000148,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage detects Swedish violations","status":"passed","title":"detects Swedish violations","duration":0.7239959999999996,"failureMessages":[],"location":{"line":229,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage always exempts executive-brief_sv.md","status":"passed","title":"always exempts executive-brief_sv.md","duration":0.6741719999999987,"failureMessages":[],"location":{"line":247,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage skips short snippets with few Swedish words","status":"passed","title":"skips short snippets with few Swedish words","duration":0.7241960000000063,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage ignores Swedish prose inside blockquote-attributed source quotations","status":"passed","title":"ignores Swedish prose inside blockquote-attributed source quotations","duration":0.8076020000000312,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage ignores verbatim Swedish source-title lines","status":"passed","title":"ignores verbatim Swedish source-title lines","duration":0.9434760000000324,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage does NOT exempt bare `Title:` lines (only explicit source-attribution labels are exempted)","status":"passed","title":"does NOT exempt bare `Title:` lines (only explicit source-attribution labels are exempted)","duration":0.8353239999999573,"failureMessages":[],"location":{"line":318,"column":5},"meta":{},"tags":[]}],"startTime":1787953794789,"endTime":1787953794811.8352,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-analysis-language.test.ts"},{"assertionResults":[{"ancestorTitles":["check-brief-language — ENGLISH_MARKERS"],"fullName":"check-brief-language — ENGLISH_MARKERS contains unambiguous English function words","status":"passed","title":"contains unambiguous English function words","duration":3.8804870000000165,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — ENGLISH_MARKERS"],"fullName":"check-brief-language — ENGLISH_MARKERS excludes short ambiguous tokens that could appear in other languages","status":"passed","title":"excludes short ambiguous tokens that could appear in other languages","duration":0.6575010000000248,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity returns zero density for a Swedish brief","status":"passed","title":"returns zero density for a Swedish brief","duration":1.0335150000000226,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity detects high density when English fallback leaked into _sv.md","status":"passed","title":"detects high density when English fallback leaked into _sv.md","duration":0.724377000000004,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity strips fenced code blocks before measuring","status":"passed","title":"strips fenced code blocks before measuring","duration":0.41940599999998085,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity strips Markdown blockquote lines (attributed source quotations)","status":"passed","title":"strips Markdown blockquote lines (attributed source quotations)","duration":0.49623900000000276,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns false when absolute marker count is below the floor","status":"passed","title":"returns false when absolute marker count is below the floor","duration":0.43036599999999225,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns true when density exceeds 5% on Latin targets","status":"passed","title":"returns true when density exceeds 5% on Latin targets","duration":0.5258450000000039,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold uses a tighter 3% threshold for CJK targets","status":"passed","title":"uses a tighter 3% threshold for CJK targets","duration":0.6747540000000072,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold uses a tighter 2% threshold for RTL targets (ar, he)","status":"passed","title":"uses a tighter 2% threshold for RTL targets (ar, he)","duration":0.4585379999999759,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns false at exactly the threshold (strict >)","status":"passed","title":"returns false at exactly the threshold (strict >)","duration":0.4763719999999694,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages finds executive-brief_<lang>.md files and skips the English source","status":"passed","title":"finds executive-brief_<lang>.md files and skips the English source","duration":2.175845000000038,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages skips pass1/ and full-text/ subdirectories","status":"passed","title":"skips pass1/ and full-text/ subdirectories","duration":1.772718999999995,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages flags an English-fallback leak in _sv.md","status":"passed","title":"flags an English-fallback leak in _sv.md","duration":1.1059609999999793,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages passes a genuine Swedish translation","status":"passed","title":"passes a genuine Swedish translation","duration":0.7721059999999511,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages formats the violation report with relpath, lang, and density","status":"passed","title":"formats the violation report with relpath, lang, and density","duration":1.0951309999999808,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages returns empty report when no violations","status":"passed","title":"returns empty report when no violations","duration":0.47244499999999334,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]}],"startTime":1787953833458,"endTime":1787953833476.4724,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-brief-language.test.ts"},{"assertionResults":[{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 returns the first H1 after stripping YAML frontmatter","status":"passed","title":"returns the first H1 after stripping YAML frontmatter","duration":3.9386760000000436,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 returns null when there is no H1","status":"passed","title":"returns null when there is no H1","duration":0.6710269999999809,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 does not treat a body `---` thematic break as frontmatter","status":"passed","title":"does not treat a body `---` thematic break as frontmatter","duration":0.42947400000002744,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 strips trailing whitespace from the H1","status":"passed","title":"strips trailing whitespace from the H1","duration":0.3690000000000282,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags definite-form party names","status":"passed","title":"flags definite-form party names","duration":1.2374070000000188,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags Tidö-coalition Swedish slugs","status":"passed","title":"flags Tidö-coalition Swedish slugs","duration":0.46458999999998696,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags untranslated political nouns","status":"passed","title":"flags untranslated political nouns","duration":0.4044579999999769,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag Riksdag / Regeringen — convention loans allowed in EN prose","status":"passed","title":"does NOT flag Riksdag / Regeringen — convention loans allowed in EN prose","duration":0.4804600000000505,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag English party-name forms","status":"passed","title":"does NOT flag English party-name forms","duration":0.4739270000000033,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag bill / proposition IDs that contain digits","status":"passed","title":"does NOT flag bill / proposition IDs that contain digits","duration":0.48418600000002243,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) flags full weekday + day + month + year prefix","status":"passed","title":"flags full weekday + day + month + year prefix","duration":1.2063190000000077,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) flags abbreviated weekday + month prefix","status":"passed","title":"flags abbreviated weekday + month prefix","duration":0.5284889999999791,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) does NOT flag headlines that merely start with a weekday word (no date)","status":"passed","title":"does NOT flag headlines that merely start with a weekday word (no date)","duration":0.4755599999999731,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) does NOT flag mid-sentence weekday references","status":"passed","title":"does NOT flag mid-sentence weekday references","duration":0.42673899999999776,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) flags ISO date at the start","status":"passed","title":"flags ISO date at the start","duration":0.5747860000000173,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) flags ISO date at the end after a separator","status":"passed","title":"flags ISO date at the end after a separator","duration":0.6929569999999785,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) does NOT flag mid-sentence ISO dates","status":"passed","title":"does NOT flag mid-sentence ISO dates","duration":0.48357600000002776,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Executive Brief — prefix with leading emoji","status":"passed","title":"flags Executive Brief — prefix with leading emoji","duration":1.1108010000000377,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Realtime Monitor — prefix","status":"passed","title":"flags Realtime Monitor — prefix","duration":0.5085219999999708,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Pass 2 and Methodology Reflection scaffolding","status":"passed","title":"flags Pass 2 and Methodology Reflection scaffolding","duration":0.7700219999999831,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) does NOT flag headlines that mention \"brief\" mid-sentence","status":"passed","title":"does NOT flag headlines that mention \"brief\" mid-sentence","duration":0.47951799999998457,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) flags bare leaf-label H1 for shallow subfolder","status":"passed","title":"flags bare leaf-label H1 for shallow subfolder","duration":1.3239300000000185,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) flags full-path H1 for nested subfolder","status":"passed","title":"flags full-path H1 for nested subfolder","duration":0.6071769999999788,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) ignores trailing/leading whitespace and punctuation when matching","status":"passed","title":"ignores trailing/leading whitespace and punctuation when matching","duration":1.3073380000000157,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) does NOT flag a real actor+verb headline that mentions the category word","status":"passed","title":"does NOT flag a real actor+verb headline that mentions the category word","duration":0.7765640000000076,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) returns false when subfolder is missing","status":"passed","title":"returns false when subfolder is missing","duration":0.5735029999999597,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) prettifies multi-segment subfolder paths via space-join","status":"passed","title":"prettifies multi-segment subfolder paths via space-join","duration":0.5129200000000083,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) normaliseHeadlineForCompare strips punctuation and lowercases","status":"passed","title":"normaliseHeadlineForCompare strips punctuation and lowercases","duration":0.561540999999977,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) subfolderFromBriefPath extracts subfolder relative to analysis/daily/<date>","status":"passed","title":"subfolderFromBriefPath extracts subfolder relative to analysis/daily/<date>","duration":0.7465880000000311,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) subfolderFromBriefPath returns null for non-canonical paths","status":"passed","title":"subfolderFromBriefPath returns null for non-canonical paths","duration":0.5697759999999903,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) validateH1 wires Rule E with subfolder argument","status":"passed","title":"validateH1 wires Rule E with subfolder argument","duration":1.7460399999999936,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) validateH1 does not fire Rule E when subfolder is omitted","status":"passed","title":"validateH1 does not fire Rule E when subfolder is omitted","duration":0.5913869999999974,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) returns empty array for a clean editorial headline","status":"passed","title":"returns empty array for a clean editorial headline","duration":0.6557180000000358,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) returns multiple issues when several rules fire","status":"passed","title":"returns multiple issues when several rules fire","duration":0.7528599999999983,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) flags weekday-date-prefix + scaffolding combination","status":"passed","title":"flags weekday-date-prefix + scaffolding combination","duration":0.6986780000000294,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) passes a real editorial headline from the repository","status":"passed","title":"passes a real editorial headline from the repository","duration":0.5759090000000242,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]}],"startTime":1787953827825,"endTime":1787953827854.576,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-headline-quality.test.ts"},{"assertionResults":[{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs passes on the current committed state (14 sources ↔ 14 triggers ↔ 14 slug branches)","status":"passed","title":"passes on the current committed state (14 sources ↔ 14 triggers ↔ 14 slug branches)","duration":48.06778499999996,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs fails when a workflow name is mistyped in the fallback yml (the Translate Articles regression)","status":"passed","title":"fails when a workflow name is mistyped in the fallback yml (the Translate Articles regression)","duration":41.953484,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs fails when a news-*.md is added without a matching trigger entry","status":"passed","title":"fails when a news-*.md is added without a matching trigger entry","duration":42.41301400000003,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953904850,"endTime":1787953904982.413,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-pat-fallback-coverage.test.ts"},{"assertionResults":[{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation types are importable (TypeScript compile check)","status":"passed","title":"types are importable (TypeScript compile check)","duration":3.7017809999999827,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation helpers.ts exports depth, renderHreflangBlock, fallbackAlternateHref","status":"passed","title":"helpers.ts exports depth, renderHreflangBlock, fallbackAlternateHref","duration":0.619199999999978,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation head.ts exports renderChromeHead","status":"passed","title":"head.ts exports renderChromeHead","duration":0.504052999999999,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation header.ts exports buildHeaderHtml","status":"passed","title":"header.ts exports buildHeaderHtml","duration":0.4038760000000252,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation footer.ts exports buildFooterHtml","status":"passed","title":"footer.ts exports buildFooterHtml","duration":0.44962199999997665,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns empty string for root-level files","status":"passed","title":"returns empty string for root-level files","duration":0.5207839999999919,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns ../ for one level deep","status":"passed","title":"returns ../ for one level deep","duration":0.45639399999998886,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns ../../ for two levels deep","status":"passed","title":"returns ../../ for two levels deep","duration":0.3391250000000241,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() strips leading slashes before computing depth","status":"passed","title":"strips leading slashes before computing depth","duration":0.5461129999999912,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — fallbackAlternateHref()"],"fullName":"chrome/helpers — fallbackAlternateHref() returns base unchanged for English","status":"passed","title":"returns base unchanged for English","duration":0.44986299999999346,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — fallbackAlternateHref()"],"fullName":"chrome/helpers — fallbackAlternateHref() appends _lang suffix for non-English","status":"passed","title":"appends _lang suffix for non-English","duration":0.4741180000000327,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() emits canonical + self alternate when no alternates provided","status":"passed","title":"emits canonical + self alternate when no alternates provided","duration":0.7048699999999712,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() emits all provided alternates + x-default","status":"passed","title":"emits all provided alternates + x-default","duration":0.6207829999999603,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() uses English alternate as x-default","status":"passed","title":"uses English alternate as x-default","duration":0.4439610000000016,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure starts with <!DOCTYPE html>","status":"passed","title":"starts with <!DOCTYPE html>","duration":1.1833260000000223,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure includes <html lang=\"…\" dir=\"…\">","status":"passed","title":"includes <html lang=\"…\" dir=\"…\">","duration":0.43175899999999956,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure sets dir=\"rtl\" for Arabic","status":"passed","title":"sets dir=\"rtl\" for Arabic","duration":0.3990180000000123,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure sets dir=\"rtl\" for Hebrew","status":"passed","title":"sets dir=\"rtl\" for Hebrew","duration":0.5177290000000312,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure includes charset and viewport meta","status":"passed","title":"includes charset and viewport meta","duration":0.49735099999998056,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure closes with </head>","status":"passed","title":"closes with </head>","duration":0.5961260000000266,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes branded title with Riksdagsmonitor suffix","status":"passed","title":"includes branded title with Riksdagsmonitor suffix","duration":0.5880810000000452,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags does not double-brand when title contains Riksdagsmonitor","status":"passed","title":"does not double-brand when title contains Riksdagsmonitor","duration":0.6473219999999742,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes OpenGraph meta tags","status":"passed","title":"includes OpenGraph meta tags","duration":0.7359680000000139,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes Twitter Card meta tags","status":"passed","title":"includes Twitter Card meta tags","duration":0.6029780000000073,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags suppresses article meta when ogType is website","status":"passed","title":"suppresses article meta when ogType is website","duration":0.5683539999999994,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes article:published_time for article type","status":"passed","title":"includes article:published_time for article type","duration":0.5686850000000163,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — JSON-LD"],"fullName":"chrome/head — JSON-LD renders JSON-LD blocks in script tags","status":"passed","title":"renders JSON-LD blocks in script tags","duration":0.6444859999999721,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — JSON-LD"],"fullName":"chrome/head — JSON-LD escapes < in JSON-LD to prevent XSS","status":"passed","title":"escapes < in JSON-LD to prevent XSS","duration":0.602346999999952,"failureMessages":[],"location":{"line":262,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility includes skip-link targeting #main","status":"passed","title":"includes skip-link targeting #main","duration":1.5314979999999991,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility header has role=\"banner\"","status":"passed","title":"header has role=\"banner\"","duration":0.6404790000000276,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility main content area has tabindex=\"-1\" for programmatic focus","status":"passed","title":"main content area has tabindex=\"-1\" for programmatic focus","duration":0.6894110000000069,"failureMessages":[],"location":{"line":289,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility breadcrumb nav has aria-label","status":"passed","title":"breadcrumb nav has aria-label","duration":0.8475369999999884,"failureMessages":[],"location":{"line":294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility last breadcrumb item has aria-current=\"page\"","status":"passed","title":"last breadcrumb item has aria-current=\"page\"","duration":0.7060020000000122,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility language switcher dropdown items have role=\"menuitem\"","status":"passed","title":"language switcher dropdown items have role=\"menuitem\"","duration":0.7596729999999638,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling renders dir=\"rtl\" in <html> for ar","status":"passed","title":"renders dir=\"rtl\" in <html> for ar","duration":0.6045819999999935,"failureMessages":[],"location":{"line":319,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling header renders correctly for ar","status":"passed","title":"header renders correctly for ar","duration":0.7649420000000191,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling footer renders correctly for ar","status":"passed","title":"footer renders correctly for ar","duration":1.2368960000000015,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling renders dir=\"rtl\" in <html> for he","status":"passed","title":"renders dir=\"rtl\" in <html> for he","duration":0.7023659999999836,"failureMessages":[],"location":{"line":319,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling header renders correctly for he","status":"passed","title":"header renders correctly for he","duration":0.7290050000000292,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling footer renders correctly for he","status":"passed","title":"footer renders correctly for he","duration":0.7268709999999601,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher header dropdown contains 13 language links (all except current)","status":"passed","title":"header dropdown contains 13 language links (all except current)","duration":1.6770500000000084,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher horizontal language bar contains all 14 languages (1 current + 13 links)","status":"passed","title":"horizontal language bar contains all 14 languages (1 current + 13 links)","duration":1.138272000000029,"failureMessages":[],"location":{"line":348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher uses explicit hreflangAlternates when provided","status":"passed","title":"uses explicit hreflangAlternates when provided","duration":0.8495100000000093,"failureMessages":[],"location":{"line":359,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes role=\"contentinfo\"","status":"passed","title":"includes role=\"contentinfo\"","duration":0.7596320000000105,"failureMessages":[],"location":{"line":377,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes ISMS section with policies","status":"passed","title":"includes ISMS section with policies","duration":0.8070410000000265,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes trust badges with external links","status":"passed","title":"includes trust badges with external links","duration":0.8118100000000368,"failureMessages":[],"location":{"line":388,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes secondary language row","status":"passed","title":"includes secondary language row","duration":0.7627790000000232,"failureMessages":[],"location":{"line":394,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes copyright with current year","status":"passed","title":"includes copyright with current year","duration":0.7937659999998914,"failureMessages":[],"location":{"line":399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure closes with </body></html>","status":"passed","title":"closes with </body></html>","duration":0.9983690000000252,"failureMessages":[],"location":{"line":404,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes Mermaid/theme bootstrap scripts","status":"passed","title":"includes Mermaid/theme bootstrap scripts","duration":3.960739999999987,"failureMessages":[],"location":{"line":410,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts façade — buildChrome"],"fullName":"chrome.ts façade — buildChrome returns head/headerHtml/footerHtml matching sub-module outputs","status":"passed","title":"returns head/headerHtml/footerHtml matching sub-module outputs","duration":1.0739609999999402,"failureMessages":[],"location":{"line":423,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts façade — buildChrome"],"fullName":"chrome.ts façade — buildChrome façade renderChromeHead matches sub-module renderChromeHead","status":"passed","title":"façade renderChromeHead matches sub-module renderChromeHead","duration":0.7141870000000381,"failureMessages":[],"location":{"line":431,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — hreflang for all 14 languages"],"fullName":"chrome/head — hreflang for all 14 languages emits hreflang link for each provided alternate","status":"passed","title":"emits hreflang link for each provided alternate","duration":0.9255529999999226,"failureMessages":[],"location":{"line":442,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner includes hero banner by default","status":"passed","title":"includes hero banner by default","duration":0.7891070000000582,"failureMessages":[],"location":{"line":465,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner excludes hero banner when heroBanner=false","status":"passed","title":"excludes hero banner when heroBanner=false","duration":0.6900920000000497,"failureMessages":[],"location":{"line":474,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner uses custom banner image when provided","status":"passed","title":"uses custom banner image when provided","duration":0.7423800000000256,"failureMessages":[],"location":{"line":480,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next includes rel=prev when relPrev provided","status":"passed","title":"includes rel=prev when relPrev provided","duration":0.7188050000000885,"failureMessages":[],"location":{"line":492,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next includes rel=next when relNext provided","status":"passed","title":"includes rel=next when relNext provided","duration":0.8012600000000702,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next omits pagination links when neither relPrev nor relNext provided","status":"passed","title":"omits pagination links when neither relPrev nor relNext provided","duration":0.7451049999999668,"failureMessages":[],"location":{"line":505,"column":3},"meta":{},"tags":[]}],"startTime":1787953683396,"endTime":1787953683445.745,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-decomposition.test.ts"},{"assertionResults":[{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) includes the section header comment that introduces the block","status":"passed","title":"includes the section header comment that introduces the block","duration":3.635226999999986,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) uses :where() to target both header families with controlled specificity","status":"passed","title":"uses :where() to target both header families with controlled specificity","duration":0.76543300000003,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) uses :where() to target both footer families with controlled specificity","status":"passed","title":"uses :where() to target both footer families with controlled specificity","duration":0.646049000000005,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) harmonises both theme-toggle button variants","status":"passed","title":"harmonises both theme-toggle button variants","duration":0.5622030000000109,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) harmonises both language-switcher variants","status":"passed","title":"harmonises both language-switcher variants","duration":0.5748869999999897,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) makes both header families sticky at the top","status":"passed","title":"makes both header families sticky at the top","duration":0.8301040000000057,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) provides explicit light-mode polish for the header (rgba glass + cyan border)","status":"passed","title":"provides explicit light-mode polish for the header (rgba glass + cyan border)","duration":0.7385229999999865,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) enforces WCAG 2.5.5 touch targets (≥ 44×44) on mobile","status":"passed","title":"enforces WCAG 2.5.5 touch targets (≥ 44×44) on mobile","duration":0.6308210000000258,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) declares a visible :focus-visible outline using the cyan token","status":"passed","title":"declares a visible :focus-visible outline using the cyan token","duration":0.7643720000000371,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) wraps hover transforms inside prefers-reduced-motion: no-preference","status":"passed","title":"wraps hover transforms inside prefers-reduced-motion: no-preference","duration":0.40695299999998724,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) does not introduce any !important declarations in the harmonisation block","status":"passed","title":"does not introduce any !important declarations in the harmonisation block","duration":0.7016840000000002,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]}],"startTime":1787953907761,"endTime":1787953907770.7017,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-harmonisation.test.js"},{"assertionResults":[{"ancestorTitles":["chrome-i18n — hero & header-tagline keys"],"fullName":"chrome-i18n — hero & header-tagline keys defines every new key for every supported language","status":"passed","title":"defines every new key for every supported language","duration":9.101833,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — hero & header-tagline keys"],"fullName":"chrome-i18n — hero & header-tagline keys translates non-English values (no copy-paste of English strings)","status":"passed","title":"translates non-English values (no copy-paste of English strings)","duration":4.609591000000023,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language renders Swedish tagline for sv chrome","status":"passed","title":"renders Swedish tagline for sv chrome","duration":3.7609319999999684,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language renders Arabic tagline for ar chrome (RTL)","status":"passed","title":"renders Arabic tagline for ar chrome (RTL)","duration":0.8866799999999557,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language keeps the English tagline for en chrome","status":"passed","title":"keeps the English tagline for en chrome","duration":0.7594019999999659,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys defines every new CTA/ecosystem key for every supported language","status":"passed","title":"defines every new CTA/ecosystem key for every supported language","duration":2.493268999999998,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys translates non-English CTA/ecosystem values (differ from English)","status":"passed","title":"translates non-English CTA/ecosystem values (differ from English)","duration":1.7177659999999833,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders Political Intelligence CTA in header","status":"passed","title":"renders Political Intelligence CTA in header","duration":0.8114590000000135,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders EU Parliament Monitor link in footer","status":"passed","title":"renders EU Parliament Monitor link in footer","duration":0.8792459999999664,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders Hack23 Blog link in footer","status":"passed","title":"renders Hack23 Blog link in footer","duration":0.7514370000000099,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders translated Political Intelligence CTA for Swedish","status":"passed","title":"renders translated Political Intelligence CTA for Swedish","duration":0.774610999999993,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]}],"startTime":1787953865399,"endTime":1787953865425.7747,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-i18n-hero.test.ts"},{"assertionResults":[{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission emits FAQPage JSON-LD when ≥2 faqItems are supplied","status":"passed","title":"emits FAQPage JSON-LD when ≥2 faqItems are supplied","duration":8.076101999999992,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission does NOT emit FAQPage JSON-LD when only 1 faqItem is supplied","status":"passed","title":"does NOT emit FAQPage JSON-LD when only 1 faqItem is supplied","duration":1.1106100000000083,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission does NOT emit FAQPage JSON-LD when faqItems is empty","status":"passed","title":"does NOT emit FAQPage JSON-LD when faqItems is empty","duration":0.83271000000002,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) falls back to the page title when description is an empty string","status":"passed","title":"falls back to the page title when description is an empty string","duration":0.9691040000000157,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) falls back to the page title when description is whitespace only","status":"passed","title":"falls back to the page title when description is whitespace only","duration":0.8276299999999992,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) keeps a supplied non-empty description unchanged","status":"passed","title":"keeps a supplied non-empty description unchanged","duration":0.676085999999998,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge merges speakable into an existing WebPage node without duplication","status":"passed","title":"merges speakable into an existing WebPage node without duplication","duration":1.0194680000000176,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge does NOT mutate the caller-provided jsonLd objects","status":"passed","title":"does NOT mutate the caller-provided jsonLd objects","duration":1.207080000000019,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge emits a standalone WebPage node when no existing one is present","status":"passed","title":"emits a standalone WebPage node when no existing one is present","duration":0.8189629999999966,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links emits <link rel=\"next\"> when relNext is provided","status":"passed","title":"emits <link rel=\"next\"> when relNext is provided","duration":0.7400559999999814,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links emits <link rel=\"prev\"> when relPrev is provided","status":"passed","title":"emits <link rel=\"prev\"> when relPrev is provided","duration":1.007316000000003,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links HTML-escapes relNext/relPrev hrefs","status":"passed","title":"HTML-escapes relNext/relPrev hrefs","duration":0.9190609999999992,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links does not emit pagination links when neither relPrev nor relNext is provided","status":"passed","title":"does not emit pagination links when neither relPrev nor relNext is provided","duration":0.6424729999999954,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]}],"startTime":1787953856849,"endTime":1787953856868.6426,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-seo-features.test.ts"},{"assertionResults":[{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv file exists on disk","status":"passed","title":"file exists on disk","duration":3.9455879999999866,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.4007030000000213,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7629680000000008,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4299340000000029,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5348710000000096,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6030189999999607,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.46998000000002094,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5302429999999845,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6483139999999707,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.43393300000002455,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6806149999999889,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.38481000000001586,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.42328199999997196,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.44426100000004,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6091600000000312,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6931680000000142,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6431539999999814,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.40351600000002463,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4417879999999741,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.47656200000000126,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5715200000000209,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4962489999999775,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5737349999999992,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5655680000000416,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4654019999999832,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5556399999999826,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5541169999999624,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5072999999999865,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5908060000000432,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7168720000000235,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.675926000000004,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5885729999999967,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5109469999999874,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5303930000000037,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6214240000000473,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6395480000000475,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5359340000000543,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5733629999999721,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.566159999999968,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5481770000000097,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.8044360000000097,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7070940000000405,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5756079999999884,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.694500000000005,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":4.9208830000000034,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5689750000000231,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5029419999999618,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5186710000000403,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4751499999999851,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5397000000000389,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5001869999999826,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5103050000000167,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5234399999999937,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5627439999999524,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5187109999999961,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5961970000000179,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.593071000000009,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8278700000000185,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.0407490000000053,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7154899999999884,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6533729999999878,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.73753099999999,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6646349999999757,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6760659999999916,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.718685999999991,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7192759999999794,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.7031560000000354,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.7944269999999847,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.8007489999999962,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.779640000000029,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.858887999999979,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.8452329999999506,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8642380000000003,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.9099340000000211,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.005262000000016,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8908480000000054,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.9827610000000391,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.9378360000000043,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.0867150000000265,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.1716940000000022,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.1836669999999572,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.4920740000000023,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.7677099999999655,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.1488509999999792,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.0449859999999944,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.0803429999999707,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.151365999999939,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity every contract path is absolute and starts with /cia-data/","status":"passed","title":"every contract path is absolute and starts with /cia-data/","duration":1.8177230000000009,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity no contract has duplicate column entries","status":"passed","title":"no contract has duplicate column entries","duration":1.7745319999999083,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity no two contracts share the same path","status":"passed","title":"no two contracts share the same path","duration":1.2162069999999403,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]}],"startTime":1787953905875,"endTime":1787953905950.2163,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-csv-contracts.test.ts"},{"assertionResults":[{"ancestorTitles":["csv-validator: CsvContractError"],"fullName":"csv-validator: CsvContractError exposes structured fields on the error instance","status":"passed","title":"exposes structured fields on the error instance","duration":5.315502999999978,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) returns rows unchanged when all required columns and minRows are satisfied","status":"passed","title":"returns rows unchanged when all required columns and minRows are satisfied","duration":0.7767939999999953,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError when a required column is missing from the header","status":"passed","title":"throws CsvContractError when a required column is missing from the header","duration":0.8664120000000253,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError when row count is below minRows","status":"passed","title":"throws CsvContractError when row count is below minRows","duration":0.587771000000032,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError on zero rows (header keys unknown)","status":"passed","title":"throws CsvContractError on zero rows (header keys unknown)","duration":0.7961310000000026,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) defaults minRows to 1 when contract omits the field","status":"passed","title":"defaults minRows to 1 when contract omits the field","duration":1.3488849999999957,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (registered contract)"],"fullName":"csv-validator: validateCsvRows (registered contract) uses getCsvContract lookup when no override contract is supplied","status":"passed","title":"uses getCsvContract lookup when no override contract is supplied","duration":0.5498900000000049,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (registered contract)"],"fullName":"csv-validator: validateCsvRows (registered contract) returns input unchanged when no contract is registered for the path","status":"passed","title":"returns input unchanged when no contract is registered for the path","duration":0.4008209999999508,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRowsLenient"],"fullName":"csv-validator: validateCsvRowsLenient returns true and does not log when the contract is satisfied","status":"passed","title":"returns true and does not log when the contract is satisfied","duration":0.8163580000000366,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRowsLenient"],"fullName":"csv-validator: validateCsvRowsLenient returns false and logs to console.error on CsvContractError","status":"passed","title":"returns false and logs to console.error on CsvContractError","duration":0.7389429999999493,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]}],"startTime":1787953865892,"endTime":1787953865905.739,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-csv-validator.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract uses explicit imports so production tree shaking keeps the dashboard bootstrap","status":"passed","title":"uses explicit imports so production tree shaking keeps the dashboard bootstrap","duration":3.8500490000000127,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract keeps bootstrap ownership explicit without module import side effects","status":"passed","title":"keeps bootstrap ownership explicit without module import side effects","duration":0.8196849999999927,"failureMessages":[],"location":{"line":14,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract marks only the source entry bootstrap as side-effectful for the app build","status":"passed","title":"marks only the source entry bootstrap as side-effectful for the app build","duration":2.117775999999992,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract keeps the bootstrap import on the first line of executable code in cia-entry","status":"passed","title":"keeps the bootstrap import on the first line of executable code in cia-entry","duration":0.6581919999999855,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]}],"startTime":1787953916575,"endTime":1787953916582.6582,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-dashboard-entry-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections uses coalition alignment CSV when available","status":"passed","title":"uses coalition alignment CSV when available","duration":8.161090000000002,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections falls back to win-rate similarity when coalition alignment CSV is unavailable","status":"passed","title":"falls back to win-rate similarity when coalition alignment CSV is unavailable","duration":1.5599109999999996,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses and filters ministry dashboard rows","status":"passed","title":"parses and filters ministry dashboard rows","duration":2.961023999999952,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses demographics and keeps only Riksdag parties","status":"passed","title":"parses demographics and keeps only Riksdag parties","duration":1.5627860000000169,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses document activity and risk evolution with zero-row filtering","status":"passed","title":"parses document activity and risk evolution with zero-row filtering","duration":1.7073369999999954,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]}],"startTime":1787953890903,"endTime":1787953890918.7073,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-dashboard-sections.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should build election analysis from CSV sources","status":"passed","title":"should build election analysis from CSV sources","duration":8.63455700000003,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should parse party forecast data correctly","status":"passed","title":"should parse party forecast data correctly","duration":1.8333719999999971,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop confidenceInterval when CSV cells are empty strings","status":"passed","title":"should drop confidenceInterval when CSV cells are empty strings","duration":0.7626580000000445,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop forecast rows with non-numeric required fields","status":"passed","title":"should drop forecast rows with non-numeric required fields","duration":0.8521959999999922,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should parse coalition scenarios correctly","status":"passed","title":"should parse coalition scenarios correctly","duration":1.5094569999999976,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop coalition rows with non-numeric required fields","status":"passed","title":"should drop coalition rows with non-numeric required fields","duration":0.9155739999999923,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop coalition rows with invalid majority and empty risk level","status":"passed","title":"should drop coalition rows with invalid majority and empty risk level","duration":1.2068700000000376,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should return empty parties when CSV fetch fails","status":"passed","title":"should return empty parties when CSV fetch fails","duration":0.7190760000000296,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","CSV_SOURCES"],"fullName":"CIADataLoader CSV_SOURCES should include election forecast and coalition scenarios","status":"passed","title":"should include election forecast and coalition scenarios","duration":0.511667999999986,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","election analysis source behavior"],"fullName":"CIADataLoader election analysis source behavior should request election CSV files and never request election-analysis.json","status":"passed","title":"should request election CSV files and never request election-analysis.json","duration":0.9079499999999712,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]}],"startTime":1787953834876,"endTime":1787953834893.908,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-election.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator exposes the same constants and CSV_SOURCES as the extracted modules","status":"passed","title":"exposes the same constants and CSV_SOURCES as the extracted modules","duration":4.645118000000025,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV delegates to the shared helper","status":"passed","title":"parseCSV delegates to the shared helper","duration":3.059248000000025,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV handles quoted commas and multiline fields from larger CIA exports","status":"passed","title":"parseCSV handles quoted commas and multiline fields from larger CIA exports","duration":0.8896460000000275,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV normalizes headers and surfaces malformed CSV errors","status":"passed","title":"parseCSV normalizes headers and surfaces malformed CSV errors","duration":1.6349909999999568,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadCSV uses the configured base URL and fallback URL","status":"passed","title":"loadCSV uses the configured base URL and fallback URL","duration":1.2904660000000376,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadCSV recovers from network errors and warns on full failure","status":"passed","title":"loadCSV recovers from network errors and warns on full failure","duration":0.9814269999999965,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadAll wires up every per-domain loader","status":"passed","title":"loadAll wires up every per-domain loader","duration":1.2690259999999967,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadPartyPerformance and loadTop10Influential delegate to the loader modules","status":"passed","title":"loadPartyPerformance and loadTop10Influential delegate to the loader modules","duration":2.9491120000000137,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]}],"startTime":1787953867697,"endTime":1787953867713.9492,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadOverviewDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadOverviewDashboard aggregates active MP, party and risk totals","status":"passed","title":"aggregates active MP, party and risk totals","duration":7.841072999999994,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadOverviewDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadOverviewDashboard falls back to defaults when CSV sources are empty","status":"passed","title":"falls back to defaults when CSV sources are empty","duration":0.5947039999999788,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadElectionAnalysis"],"fullName":"CIA per-domain loaders (extracted modules) loadElectionAnalysis parses forecast and scenarios from CSV inputs","status":"passed","title":"parses forecast and scenarios from CSV inputs","duration":3.2843599999999924,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadVotingPatterns"],"fullName":"CIA per-domain loaders (extracted modules) loadVotingPatterns uses real coalition alignment data when available","status":"passed","title":"uses real coalition alignment data when available","duration":1.206249000000014,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadMinistryDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadMinistryDashboard sorts ministries by documents produced and filters zero rows","status":"passed","title":"sorts ministries by documents produced and filters zero rows","duration":1.050247000000013,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadDemographics"],"fullName":"CIA per-domain loaders (extracted modules) loadDemographics keeps only the 8 Riksdag parties","status":"passed","title":"keeps only the 8 Riksdag parties","duration":1.1753709999999842,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadDocumentActivity"],"fullName":"CIA per-domain loaders (extracted modules) loadDocumentActivity drops zero-count rows for both document types and decisions","status":"passed","title":"drops zero-count rows for both document types and decisions","duration":1.154642000000024,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadRiskEvolution"],"fullName":"CIA per-domain loaders (extracted modules) loadRiskEvolution emits temporal risk entries with zero filtering","status":"passed","title":"emits temporal risk entries with zero filtering","duration":0.8705899999999929,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadCommitteeNetwork"],"fullName":"CIA per-domain loaders (extracted modules) loadCommitteeNetwork filters inactive committees with no measured output","status":"passed","title":"filters inactive committees with no measured output","duration":1.6591870000000313,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadPartyPerformance"],"fullName":"CIA per-domain loaders (extracted modules) loadPartyPerformance joins performance, metrics and momentum and sorts by seats","status":"passed","title":"joins performance, metrics and momentum and sorts by seats","duration":1.4610959999999977,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadTop10Influential"],"fullName":"CIA per-domain loaders (extracted modules) loadTop10Influential ranks MPs by network connections and joins risk data","status":"passed","title":"ranks MPs by network connections and joins risk data","duration":1.3274260000000027,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","createLoadCSV"],"fullName":"CIA per-domain loaders (extracted modules) createLoadCSV builds a working closure bound to URLs","status":"passed","title":"builds a working closure bound to URLs","duration":0.9237300000000346,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/ + foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/ + foo.csv -> /base/foo.csv","duration":0.4915009999999711,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base + foo.csv -> /base/foo.csv","status":"passed","title":"joins /base + foo.csv -> /base/foo.csv","duration":0.3769060000000195,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/ + /foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/ + /foo.csv -> /base/foo.csv","duration":0.480419999999981,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base + /foo.csv -> /base/foo.csv","status":"passed","title":"joins /base + /foo.csv -> /base/foo.csv","duration":0.41618900000003123,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/// + ///foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/// + ///foo.csv -> /base/foo.csv","duration":0.4747590000000059,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins ../cia-data/ + voting/x.csv -> ../cia-data/voting/x.csv","status":"passed","title":"joins ../cia-data/ + voting/x.csv -> ../cia-data/voting/x.csv","duration":0.397213000000022,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins https://host.example/path/ + x.csv -> https://host.example/path/x.csv","status":"passed","title":"joins https://host.example/path/ + x.csv -> https://host.example/path/x.csv","duration":0.42384299999997666,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins https://host.example/path + x.csv -> https://host.example/path/x.csv","status":"passed","title":"joins https://host.example/path + x.csv -> https://host.example/path/x.csv","duration":0.4458750000000009,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL returns the path when base is empty","status":"passed","title":"returns the path when base is empty","duration":0.5210759999999937,"failureMessages":[],"location":{"line":321,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL returns the base when path is empty","status":"passed","title":"returns the base when path is empty","duration":0.45157599999998865,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]}],"startTime":1787953808885,"endTime":1787953808913.4517,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-loaders.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration exposes a non-empty local path and description for every CSV source","status":"passed","title":"exposes a non-empty local path and description for every CSV source","duration":5.859040999999991,"failureMessages":[],"location":{"line":10,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration uses unique local paths across all sources","status":"passed","title":"uses unique local paths across all sources","duration":0.5655790000000138,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration declares the 8 Swedish Riksdag parties","status":"passed","title":"declares the 8 Swedish Riksdag parties","duration":1.102354000000048,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration maps committee names to short org codes","status":"passed","title":"maps committee names to short org codes","duration":0.4724050000000375,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration exposes a positive committee meetings divisor","status":"passed","title":"exposes a positive committee meetings divisor","duration":0.5141619999999989,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration deep-freezes the shared source inventory so consumers cannot mutate it","status":"passed","title":"deep-freezes the shared source inventory so consumers cannot mutate it","duration":0.9006559999999695,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953924296,"endTime":1787953924305.9006,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-sources.test.ts"},{"assertionResults":[{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have coalition dashboard section","status":"passed","title":"should have coalition dashboard section","duration":10.454502999999988,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.4135879999999474,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":1.9787750000000415,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have D3.js visualization containers","status":"passed","title":"should have D3.js visualization containers","duration":1.8419289999999933,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have wide chart cards","status":"passed","title":"should have wide chart cards","duration":4.069899000000021,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have data attribution","status":"passed","title":"should have data attribution","duration":2.8794809999999984,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have ARIA labels on D3 containers","status":"passed","title":"should have ARIA labels on D3 containers","duration":2.2855090000000473,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have accessible fallback table for network","status":"passed","title":"should have accessible fallback table for network","duration":1.8975730000000226,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have table caption","status":"passed","title":"should have table caption","duration":2.8904210000000035,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have proper heading hierarchy","status":"passed","title":"should have proper heading hierarchy","duration":1.8196169999999938,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should configure local-first URLs for all CSV files","status":"passed","title":"should configure local-first URLs for all CSV files","duration":2.158811999999955,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should use local paths starting with cia-data/","status":"passed","title":"should use local paths starting with cia-data/","duration":2.4612879999999677,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should have remote fallback URLs for all files","status":"passed","title":"should have remote fallback URLs for all files","duration":2.5325109999999995,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse behavioral patterns CSV with real columns","status":"passed","title":"should parse behavioral patterns CSV with real columns","duration":2.4530429999999797,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse annual party votes CSV with real columns","status":"passed","title":"should parse annual party votes CSV with real columns","duration":4.121165000000019,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse decision trends CSV with real columns","status":"passed","title":"should parse decision trends CSV with real columns","duration":1.1980429999999842,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse decision patterns CSV with real columns","status":"passed","title":"should parse decision patterns CSV with real columns","duration":1.1935750000000098,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should calculate alignment scores between parties","status":"passed","title":"should calculate alignment scores between parties","duration":1.6105459999999994,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should identify coalition blocs","status":"passed","title":"should identify coalition blocs","duration":1.5336020000000872,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should aggregate behavioral data by party","status":"passed","title":"should aggregate behavioral data by party","duration":1.7860729999999876,"failureMessages":[],"location":{"line":232,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should prepare network data nodes for all 8 parties","status":"passed","title":"should prepare network data nodes for all 8 parties","duration":2.258919999999989,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should prepare network data links","status":"passed","title":"should prepare network data links","duration":1.980848999999921,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should generate correct number of links for 8 parties","status":"passed","title":"should generate correct number of links for 8 parties","duration":1.4504450000000588,"failureMessages":[],"location":{"line":271,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should handle empty CSV data gracefully","status":"passed","title":"should handle empty CSV data gracefully","duration":1.3546360000000277,"failureMessages":[],"location":{"line":279,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should provide fallback coalition data when CSV is empty","status":"passed","title":"should provide fallback coalition data when CSV is empty","duration":1.635691999999949,"failureMessages":[],"location":{"line":287,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should handle fetch failures with mock fallback","status":"passed","title":"should handle fetch failures with mock fallback","duration":2.336824999999976,"failureMessages":[],"location":{"line":308,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should skip aggregate rows with party \"-\"","status":"passed","title":"should skip aggregate rows with party \"-\"","duration":1.4924139999999397,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Loading State"],"fullName":"Coalition Dashboard Loading State should add loading class to container","status":"passed","title":"should add loading class to container","duration":1.7877069999999549,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Loading State"],"fullName":"Coalition Dashboard Loading State should remove loading class when data loads","status":"passed","title":"should remove loading class when data loads","duration":1.640090999999984,"failureMessages":[],"location":{"line":339,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should use alignment_rate directly as 0-1 scale without dividing by 100","status":"passed","title":"should use alignment_rate directly as 0-1 scale without dividing by 100","duration":1.6358519999999999,"failureMessages":[],"location":{"line":347,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should handle reverse-pair lookups when CSV stores only one direction","status":"passed","title":"should handle reverse-pair lookups when CSV stores only one direction","duration":1.6304829999999129,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should NOT divide alignment_rate by 100 (values are already 0-1)","status":"passed","title":"should NOT divide alignment_rate by 100 (values are already 0-1)","duration":1.7419909999999845,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should calculate node influence correctly with 0-1 alignment rates","status":"passed","title":"should calculate node influence correctly with 0-1 alignment rates","duration":2.0492169999999987,"failureMessages":[],"location":{"line":393,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should treat alignment value of 0 as valid, not fall back to 0.5","status":"passed","title":"should treat alignment value of 0 as valid, not fall back to 0.5","duration":4.7644599999999855,"failureMessages":[],"location":{"line":404,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should fall back to 0.5 only for missing alignment data","status":"passed","title":"should fall back to 0.5 only for missing alignment data","duration":1.1118910000000142,"failureMessages":[],"location":{"line":412,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should filter out non-party rows (e.g., party \"-\") when building alignment matrix","status":"passed","title":"should filter out non-party rows (e.g., party \"-\") when building alignment matrix","duration":1.335369999999898,"failureMessages":[],"location":{"line":419,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Mock Data Quality"],"fullName":"Coalition Dashboard Mock Data Quality should generate deterministic non-empty mock anomaly data for all parties","status":"passed","title":"should generate deterministic non-empty mock anomaly data for all parties","duration":2.4925369999999702,"failureMessages":[],"location":{"line":452,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Mock Data Quality"],"fullName":"Coalition Dashboard Mock Data Quality should generate deterministic non-empty mock annual votes data","status":"passed","title":"should generate deterministic non-empty mock annual votes data","duration":2.8199299999999994,"failureMessages":[],"location":{"line":468,"column":5},"meta":{},"tags":[]}],"startTime":1787953680216,"endTime":1787953680305.8198,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/coalition-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have committee dashboard section","status":"passed","title":"should have committee dashboard section","duration":10.874983999999984,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.4933090000000107,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":2.464104999999961,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have D3 visualization containers","status":"passed","title":"should have D3 visualization containers","duration":2.269820999999979,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have wide chart cards","status":"passed","title":"should have wide chart cards","duration":4.968635000000006,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have last updated timestamp","status":"passed","title":"should have last updated timestamp","duration":2.475174999999979,"failureMessages":[],"location":{"line":91,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have ARIA labels on D3 containers","status":"passed","title":"should have ARIA labels on D3 containers","duration":2.763695000000041,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have accessible fallback tables","status":"passed","title":"should have accessible fallback tables","duration":2.381779999999992,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have table captions","status":"passed","title":"should have table captions","duration":2.749479000000008,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have proper heading hierarchy","status":"passed","title":"should have proper heading hierarchy","duration":3.2991180000000213,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should parse committee productivity matrix CSV with real columns","status":"passed","title":"should parse committee productivity matrix CSV with real columns","duration":3.0706900000000132,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should parse committee ballot decision summary CSV with real columns","status":"passed","title":"should parse committee ballot decision summary CSV with real columns","duration":2.044828999999993,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should rank committees by effectiveness","status":"passed","title":"should rank committees by effectiveness","duration":2.114629999999977,"failureMessages":[],"location":{"line":154,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should calculate productivity metrics","status":"passed","title":"should calculate productivity metrics","duration":1.8494329999999763,"failureMessages":[],"location":{"line":165,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Source Configuration"],"fullName":"Committees Dashboard Data Source Configuration should use local-first URLs with cia-data/ prefix","status":"passed","title":"should use local-first URLs with cia-data/ prefix","duration":2.0797750000000406,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Source Configuration"],"fullName":"Committees Dashboard Data Source Configuration should have remote fallback URLs","status":"passed","title":"should have remote fallback URLs","duration":2.0787329999999997,"failureMessages":[],"location":{"line":186,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Error Handling"],"fullName":"Committees Dashboard Error Handling should handle empty CSV data","status":"passed","title":"should handle empty CSV data","duration":1.7472420000000284,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Error Handling"],"fullName":"Committees Dashboard Error Handling should handle fetch failures gracefully","status":"passed","title":"should handle fetch failures gracefully","duration":2.4041220000000294,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Chart Configuration"],"fullName":"Committees Dashboard Chart Configuration should create comparison bar chart","status":"passed","title":"should create comparison bar chart","duration":4.823381999999981,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Attribution"],"fullName":"Committees Dashboard Data Attribution should have data attribution section","status":"passed","title":"should have data attribution section","duration":1.5842670000000112,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Attribution"],"fullName":"Committees Dashboard Data Attribution should reference CIA Platform as data source","status":"passed","title":"should reference CIA Platform as data source","duration":1.5518659999999613,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]}],"startTime":1787953832936,"endTime":1787953832998.5518,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/committees-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows maps all 14 contract languages plus the BCP-47 `nb` alias for Norwegian","status":"passed","title":"maps all 14 contract languages plus the BCP-47 `nb` alias for Norwegian","duration":4.200203999999985,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows applies Latin window for unknown language","status":"passed","title":"applies Latin window for unknown language","duration":1.2209060000000136,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows uses tighter CJK windows","status":"passed","title":"uses tighter CJK windows","duration":0.5728630000000408,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows uses tighter RTL windows","status":"passed","title":"uses tighter RTL windows","duration":0.4970209999999611,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length PASS — title exactly at lower bound","status":"passed","title":"PASS — title exactly at lower bound","duration":1.3563699999999699,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — title below lower bound","status":"passed","title":"FAIL — title below lower bound","duration":0.7924339999999575,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — title above upper bound","status":"passed","title":"FAIL — title above upper bound","duration":0.7686089999999695,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — empty title","status":"passed","title":"FAIL — empty title","duration":0.5629339999999843,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — literal YYYY-MM-DD in title","status":"passed","title":"FAIL — literal YYYY-MM-DD in title","duration":0.6891299999999774,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — trailing brand suffix in title","status":"passed","title":"FAIL — trailing brand suffix in title","duration":1.0378029999999967,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — Executive Brief boilerplate prefix","status":"passed","title":"FAIL — Executive Brief boilerplate prefix","duration":0.6132790000000341,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — AI-generated filler phrase in title","status":"passed","title":"FAIL — AI-generated filler phrase in title","duration":0.47876600000000735,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — Brief ID leak in title","status":"passed","title":"FAIL — Brief ID leak in title","duration":0.5191319999999564,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases PASS — clean title","status":"passed","title":"PASS — clean title","duration":0.573914000000002,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — description at lower bound, terminated","status":"passed","title":"PASS — description at lower bound, terminated","duration":0.5907659999999737,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description below lower bound","status":"passed","title":"FAIL — description below lower bound","duration":0.5674220000000219,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description above upper bound","status":"passed","title":"FAIL — description above upper bound","duration":0.538739000000021,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description empty","status":"passed","title":"FAIL — description empty","duration":0.5294109999999819,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description ends mid-word","status":"passed","title":"FAIL — description ends mid-word","duration":1.1411170000000084,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — ellipsis is an accepted terminator","status":"passed","title":"PASS — ellipsis is an accepted terminator","duration":0.9453100000000063,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — CJK full stop 。 is an accepted terminator","status":"passed","title":"PASS — CJK full stop 。 is an accepted terminator","duration":0.6684420000000273,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (Brief ID)","status":"passed","title":"FAIL — admin leak (Brief ID)","duration":0.5419049999999856,"failureMessages":[],"location":{"line":233,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (Prepared by)","status":"passed","title":"FAIL — admin leak (Prepared by)","duration":0.6143999999999892,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (60-second read)","status":"passed","title":"FAIL — admin leak (60-second read)","duration":0.5724309999999946,"failureMessages":[],"location":{"line":251,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — generic filler","status":"passed","title":"FAIL — generic filler","duration":0.5675529999999753,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — 35-char German description is below floor","status":"passed","title":"FAIL — 35-char German description is below floor","duration":0.5887319999999931,"failureMessages":[],"location":{"line":271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — CJK tighter window catches 80-char Japanese title","status":"passed","title":"FAIL — CJK tighter window catches 80-char Japanese title","duration":0.687546999999995,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows PASS — 40-char Japanese title fits CJK window","status":"passed","title":"PASS — 40-char Japanese title fits CJK window","duration":0.6621499999999969,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — RTL tighter window catches 100-char Arabic title","status":"passed","title":"FAIL — RTL tighter window catches 100-char Arabic title","duration":0.6460389999999734,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus BANNED_TITLE_PHRASES covers §2.2 list","status":"passed","title":"BANNED_TITLE_PHRASES covers §2.2 list","duration":0.5937620000000265,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus BANNED_DESCRIPTION_PHRASES covers §3.1 list","status":"passed","title":"BANNED_DESCRIPTION_PHRASES covers §3.1 list","duration":0.7861420000000408,"failureMessages":[],"location":{"line":325,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus ISO_DATE_RE matches canonical forms","status":"passed","title":"ISO_DATE_RE matches canonical forms","duration":0.9189709999999991,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus TRAILING_BRAND_RE matches trailing \" — Riksdagsmonitor\"","status":"passed","title":"TRAILING_BRAND_RE matches trailing \" — Riksdagsmonitor\"","duration":0.6783110000000079,"failureMessages":[],"location":{"line":333,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus GENERIC_FILLER_RE matches contract-listed filler","status":"passed","title":"GENERIC_FILLER_RE matches contract-listed filler","duration":0.5632349999999633,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus SENTENCE_TERMINATOR_RE accepts each multi-script terminator","status":"passed","title":"SENTENCE_TERMINATOR_RE accepts each multi-script terminator","duration":0.7895680000000311,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape ok=true when no violations","status":"passed","title":"ok=true when no violations","duration":0.8247740000000476,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape ok=false iff violations.length > 0","status":"passed","title":"ok=false iff violations.length > 0","duration":0.7458359999999971,"failureMessages":[],"location":{"line":366,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape every violation has {code, field, message, value}","status":"passed","title":"every violation has {code, field, message, value}","duration":1.698178999999982,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]}],"startTime":1787953789986,"endTime":1787953790018.6982,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/contract-checker.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_politician_risk_levels.csv","status":"passed","title":"should have distribution_politician_risk_levels.csv","duration":3.8710179999999923,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_risk_by_party.csv","status":"passed","title":"should have distribution_risk_by_party.csv","duration":0.5642770000000041,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_risk_evolution_temporal.csv","status":"passed","title":"should have distribution_risk_evolution_temporal.csv","duration":0.42115899999998874,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_crisis_resilience.csv","status":"passed","title":"should have distribution_crisis_resilience.csv","duration":0.46229600000003757,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have percentile_voting_anomaly_detection.csv","status":"passed","title":"should have percentile_voting_anomaly_detection.csv","duration":0.3382230000000277,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_party_effectiveness_trends.csv","status":"passed","title":"should have distribution_party_effectiveness_trends.csv","duration":0.4349040000000173,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_party_momentum.csv","status":"passed","title":"should have distribution_party_momentum.csv","duration":0.35641700000002174,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_annual_committee_documents.csv","status":"passed","title":"should have distribution_annual_committee_documents.csv","duration":0.30551200000002154,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_committee_productivity_matrix.csv","status":"passed","title":"should have distribution_committee_productivity_matrix.csv","duration":0.5624429999999734,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_effectiveness.csv","status":"passed","title":"should have distribution_ministry_effectiveness.csv","duration":0.31880599999999504,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_decision_impact.csv","status":"passed","title":"should have distribution_ministry_decision_impact.csv","duration":0.35458399999998846,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_productivity_matrix.csv","status":"passed","title":"should have distribution_ministry_productivity_matrix.csv","duration":0.3374109999999746,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_risk_levels.csv","status":"passed","title":"should have distribution_ministry_risk_levels.csv","duration":0.27993299999997134,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_risk_quarterly.csv","status":"passed","title":"should have distribution_ministry_risk_quarterly.csv","duration":0.31534099999998944,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_person_status.csv","status":"passed","title":"should have distribution_person_status.csv","duration":0.47895600000003924,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_experience_levels.csv","status":"passed","title":"should have distribution_experience_levels.csv","duration":0.43832099999997354,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_experience_by_party.csv","status":"passed","title":"should have distribution_experience_by_party.csv","duration":0.44853999999997995,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have extraction_summary_report.csv","status":"passed","title":"should have extraction_summary_report.csv","duration":0.3714659999999981,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_politician_risk_levels.csv should not be empty or too small","status":"passed","title":"distribution_politician_risk_levels.csv should not be empty or too small","duration":0.6662580000000276,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_risk_by_party.csv should not be empty or too small","status":"passed","title":"distribution_risk_by_party.csv should not be empty or too small","duration":0.5359129999999936,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_risk_evolution_temporal.csv should not be empty or too small","status":"passed","title":"distribution_risk_evolution_temporal.csv should not be empty or too small","duration":0.4872530000000097,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_crisis_resilience.csv should not be empty or too small","status":"passed","title":"distribution_crisis_resilience.csv should not be empty or too small","duration":0.5251930000000016,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation percentile_voting_anomaly_detection.csv should not be empty or too small","status":"passed","title":"percentile_voting_anomaly_detection.csv should not be empty or too small","duration":0.45837899999997944,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_party_effectiveness_trends.csv should not be empty or too small","status":"passed","title":"distribution_party_effectiveness_trends.csv should not be empty or too small","duration":0.4967100000000073,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_party_momentum.csv should not be empty or too small","status":"passed","title":"distribution_party_momentum.csv should not be empty or too small","duration":0.4698900000000208,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_annual_committee_documents.csv should not be empty or too small","status":"passed","title":"distribution_annual_committee_documents.csv should not be empty or too small","duration":0.4833849999999984,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_committee_productivity_matrix.csv should not be empty or too small","status":"passed","title":"distribution_committee_productivity_matrix.csv should not be empty or too small","duration":0.49516700000003766,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_effectiveness.csv should not be empty or too small","status":"passed","title":"distribution_ministry_effectiveness.csv should not be empty or too small","duration":0.46988000000004604,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_decision_impact.csv should not be empty or too small","status":"passed","title":"distribution_ministry_decision_impact.csv should not be empty or too small","duration":0.44942200000002686,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_productivity_matrix.csv should not be empty or too small","status":"passed","title":"distribution_ministry_productivity_matrix.csv should not be empty or too small","duration":0.5209650000000465,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_risk_levels.csv should not be empty or too small","status":"passed","title":"distribution_ministry_risk_levels.csv should not be empty or too small","duration":0.6449980000000437,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_risk_quarterly.csv should not be empty or too small","status":"passed","title":"distribution_ministry_risk_quarterly.csv should not be empty or too small","duration":0.7723659999999768,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_person_status.csv should not be empty or too small","status":"passed","title":"distribution_person_status.csv should not be empty or too small","duration":0.5570119999999861,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_experience_levels.csv should not be empty or too small","status":"passed","title":"distribution_experience_levels.csv should not be empty or too small","duration":0.5136309999999753,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_experience_by_party.csv should not be empty or too small","status":"passed","title":"distribution_experience_by_party.csv should not be empty or too small","duration":0.5486779999999953,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation extraction_summary_report.csv should not be empty or too small","status":"passed","title":"extraction_summary_report.csv should not be empty or too small","duration":0.5166580000000067,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_politician_risk_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_politician_risk_levels.csv should have valid UTF-8 encoding","duration":0.8567639999999983,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_risk_by_party.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_risk_by_party.csv should have valid UTF-8 encoding","duration":0.6430139999999938,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_risk_evolution_temporal.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_risk_evolution_temporal.csv should have valid UTF-8 encoding","duration":0.6454289999999787,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_crisis_resilience.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_crisis_resilience.csv should have valid UTF-8 encoding","duration":0.579435999999987,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation percentile_voting_anomaly_detection.csv should have valid UTF-8 encoding","status":"passed","title":"percentile_voting_anomaly_detection.csv should have valid UTF-8 encoding","duration":0.6480830000000424,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_party_effectiveness_trends.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_party_effectiveness_trends.csv should have valid UTF-8 encoding","duration":0.8558929999999805,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_party_momentum.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_party_momentum.csv should have valid UTF-8 encoding","duration":0.7095590000000129,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_annual_committee_documents.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_annual_committee_documents.csv should have valid UTF-8 encoding","duration":0.7976340000000164,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_committee_productivity_matrix.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_committee_productivity_matrix.csv should have valid UTF-8 encoding","duration":0.8485180000000128,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_effectiveness.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_effectiveness.csv should have valid UTF-8 encoding","duration":0.7251279999999838,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_decision_impact.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_decision_impact.csv should have valid UTF-8 encoding","duration":0.7996070000000373,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_productivity_matrix.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have valid UTF-8 encoding","duration":0.7187660000000164,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_risk_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_risk_levels.csv should have valid UTF-8 encoding","duration":0.8750580000000241,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_risk_quarterly.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have valid UTF-8 encoding","duration":0.8248539999999593,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_person_status.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_person_status.csv should have valid UTF-8 encoding","duration":0.7819339999999784,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_experience_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_experience_levels.csv should have valid UTF-8 encoding","duration":0.7919630000000097,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_experience_by_party.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_experience_by_party.csv should have valid UTF-8 encoding","duration":6.173889999999972,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation extraction_summary_report.csv should have valid UTF-8 encoding","status":"passed","title":"extraction_summary_report.csv should have valid UTF-8 encoding","duration":0.7315490000000295,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_politician_risk_levels.csv should have proper CSV structure","status":"passed","title":"distribution_politician_risk_levels.csv should have proper CSV structure","duration":0.9320950000000039,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_politician_risk_levels.csv should have data rows","status":"passed","title":"distribution_politician_risk_levels.csv should have data rows","duration":0.7083659999999554,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_by_party.csv should have proper CSV structure","status":"passed","title":"distribution_risk_by_party.csv should have proper CSV structure","duration":0.7103500000000622,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_by_party.csv should have data rows","status":"passed","title":"distribution_risk_by_party.csv should have data rows","duration":0.9374450000000252,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_evolution_temporal.csv should have proper CSV structure","status":"passed","title":"distribution_risk_evolution_temporal.csv should have proper CSV structure","duration":1.0824159999999665,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_evolution_temporal.csv should have data rows","status":"passed","title":"distribution_risk_evolution_temporal.csv should have data rows","duration":0.6940989999999374,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_crisis_resilience.csv should have proper CSV structure","status":"passed","title":"distribution_crisis_resilience.csv should have proper CSV structure","duration":0.6727290000000039,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_crisis_resilience.csv should have data rows","status":"passed","title":"distribution_crisis_resilience.csv should have data rows","duration":0.6914040000000341,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation percentile_voting_anomaly_detection.csv should have proper CSV structure","status":"passed","title":"percentile_voting_anomaly_detection.csv should have proper CSV structure","duration":0.7259999999999991,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation percentile_voting_anomaly_detection.csv should have data rows","status":"passed","title":"percentile_voting_anomaly_detection.csv should have data rows","duration":0.6845610000000306,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_effectiveness_trends.csv should have proper CSV structure","status":"passed","title":"distribution_party_effectiveness_trends.csv should have proper CSV structure","duration":0.7502550000000383,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_effectiveness_trends.csv should have data rows","status":"passed","title":"distribution_party_effectiveness_trends.csv should have data rows","duration":0.7409770000000435,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_momentum.csv should have proper CSV structure","status":"passed","title":"distribution_party_momentum.csv should have proper CSV structure","duration":0.821749000000068,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_momentum.csv should have data rows","status":"passed","title":"distribution_party_momentum.csv should have data rows","duration":0.9089409999999134,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_annual_committee_documents.csv should have proper CSV structure","status":"passed","title":"distribution_annual_committee_documents.csv should have proper CSV structure","duration":1.0364210000000185,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_annual_committee_documents.csv should have data rows","status":"passed","title":"distribution_annual_committee_documents.csv should have data rows","duration":0.8401229999999487,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_committee_productivity_matrix.csv should have proper CSV structure","status":"passed","title":"distribution_committee_productivity_matrix.csv should have proper CSV structure","duration":0.8510629999999537,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_committee_productivity_matrix.csv should have data rows","status":"passed","title":"distribution_committee_productivity_matrix.csv should have data rows","duration":0.8053979999999683,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_effectiveness.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_effectiveness.csv should have proper CSV structure","duration":0.9363440000000764,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_effectiveness.csv should have data rows","status":"passed","title":"distribution_ministry_effectiveness.csv should have data rows","duration":0.8712909999999283,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_decision_impact.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_decision_impact.csv should have proper CSV structure","duration":0.9153840000000173,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_decision_impact.csv should have data rows","status":"passed","title":"distribution_ministry_decision_impact.csv should have data rows","duration":0.9091919999999618,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_productivity_matrix.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have proper CSV structure","duration":0.9805660000000671,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_productivity_matrix.csv should have data rows","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have data rows","duration":0.9442780000000539,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_levels.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_risk_levels.csv should have proper CSV structure","duration":1.1352759999999762,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_levels.csv should have data rows","status":"passed","title":"distribution_ministry_risk_levels.csv should have data rows","duration":1.1937560000000076,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_quarterly.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have proper CSV structure","duration":1.0724880000000212,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_quarterly.csv should have data rows","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have data rows","duration":1.6020800000000008,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_person_status.csv should have proper CSV structure","status":"passed","title":"distribution_person_status.csv should have proper CSV structure","duration":2.024000000000001,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_person_status.csv should have data rows","status":"passed","title":"distribution_person_status.csv should have data rows","duration":1.4485019999999622,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_levels.csv should have proper CSV structure","status":"passed","title":"distribution_experience_levels.csv should have proper CSV structure","duration":1.1116610000000264,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_levels.csv should have data rows","status":"passed","title":"distribution_experience_levels.csv should have data rows","duration":1.059172999999987,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_by_party.csv should have proper CSV structure","status":"passed","title":"distribution_experience_by_party.csv should have proper CSV structure","duration":1.097395000000006,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_by_party.csv should have data rows","status":"passed","title":"distribution_experience_by_party.csv should have data rows","duration":1.057570999999939,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation extraction_summary_report.csv should have proper CSV structure","status":"passed","title":"extraction_summary_report.csv should have proper CSV structure","duration":1.1122219999999743,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation extraction_summary_report.csv should have data rows","status":"passed","title":"extraction_summary_report.csv should have data rows","duration":1.1047379999999976,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.3934390000000576,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should have required columns","status":"passed","title":"should have required columns","duration":2.021223999999961,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":1.4512680000000273,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.2187020000000075,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should have required columns","status":"passed","title":"should have required columns","duration":1.4052410000000464,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":2.274519000000055,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.684423000000038,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should have required columns","status":"passed","title":"should have required columns","duration":1.9128420000000688,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":5.685165000000097,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":2.208344000000011,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should have required columns","status":"passed","title":"should have required columns","duration":3.0398119999999835,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":3.668309000000022,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":2.541488999999956,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should have required columns","status":"passed","title":"should have required columns","duration":2.2808009999999967,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":12.54633100000001,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_politician_risk_levels.csv should have consistent column counts","status":"passed","title":"distribution_politician_risk_levels.csv should have consistent column counts","duration":2.6686369999999897,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_risk_by_party.csv should have consistent column counts","status":"passed","title":"distribution_risk_by_party.csv should have consistent column counts","duration":2.2425589999999147,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_risk_evolution_temporal.csv should have consistent column counts","status":"passed","title":"distribution_risk_evolution_temporal.csv should have consistent column counts","duration":3.0915590000000748,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_crisis_resilience.csv should have consistent column counts","status":"passed","title":"distribution_crisis_resilience.csv should have consistent column counts","duration":2.265310999999997,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency percentile_voting_anomaly_detection.csv should have consistent column counts","status":"passed","title":"percentile_voting_anomaly_detection.csv should have consistent column counts","duration":1.9890850000000455,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_party_effectiveness_trends.csv should have consistent column counts","status":"passed","title":"distribution_party_effectiveness_trends.csv should have consistent column counts","duration":3.459206999999992,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_party_momentum.csv should have consistent column counts","status":"passed","title":"distribution_party_momentum.csv should have consistent column counts","duration":7.801216999999951,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_annual_committee_documents.csv should have consistent column counts","status":"passed","title":"distribution_annual_committee_documents.csv should have consistent column counts","duration":11.184652000000028,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_committee_productivity_matrix.csv should have consistent column counts","status":"passed","title":"distribution_committee_productivity_matrix.csv should have consistent column counts","duration":6.330152999999996,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_effectiveness.csv should have consistent column counts","status":"passed","title":"distribution_ministry_effectiveness.csv should have consistent column counts","duration":2.674147000000062,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_decision_impact.csv should have consistent column counts","status":"passed","title":"distribution_ministry_decision_impact.csv should have consistent column counts","duration":2.2525779999999713,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_productivity_matrix.csv should have consistent column counts","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have consistent column counts","duration":1.9710810000000265,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_risk_levels.csv should have consistent column counts","status":"passed","title":"distribution_ministry_risk_levels.csv should have consistent column counts","duration":1.6111069999999472,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_risk_quarterly.csv should have consistent column counts","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have consistent column counts","duration":1.761908999999946,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_person_status.csv should have consistent column counts","status":"passed","title":"distribution_person_status.csv should have consistent column counts","duration":3.872090999999955,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_experience_levels.csv should have consistent column counts","status":"passed","title":"distribution_experience_levels.csv should have consistent column counts","duration":1.6840430000000879,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_experience_by_party.csv should have consistent column counts","status":"passed","title":"distribution_experience_by_party.csv should have consistent column counts","duration":2.059476000000018,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency extraction_summary_report.csv should have consistent column counts","status":"passed","title":"extraction_summary_report.csv should have consistent column counts","duration":3.421196000000009,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Data Freshness"],"fullName":"CIA CSV Data Validation Data Freshness CSV files should not be older than 90 days (warns at 30 days)","status":"passed","title":"CSV files should not be older than 90 days (warns at 30 days)","duration":2.2340330000000677,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]}],"startTime":1787953813933,"endTime":1787953814120.2341,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/csv-validation.test.js"},{"assertionResults":[{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) dist/dashboards/ directory exists","status":"skipped","title":"dist/dashboards/ directory exists","failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) dist/cia-data/ directory exists","status":"skipped","title":"dist/cia-data/ directory exists","failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) all localized dashboard pages also have hashed bundles","status":"skipped","title":"all localized dashboard pages also have hashed bundles","failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) dashboard/index.html exists and ships a hashed cia-entry bundle","status":"skipped","title":"dashboard/index.html exists and ships a hashed cia-entry bundle","failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) cia-entry-*.js statically bundles Chart.js (registerables + auto)","status":"skipped","title":"cia-entry-*.js statically bundles Chart.js (registerables + auto)","failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) cia-entry-*.js bundle graph statically references the d3 chunk","status":"skipped","title":"cia-entry-*.js bundle graph statically references the d3 chunk","failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]}],"startTime":1787953656920,"endTime":1787953656920,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-bundle-integrity.test.ts"},{"assertionResults":[{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/stats-loader.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/stats-loader.ts should not contain relative cia-data/ string literals","duration":4.167622999999992,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/party-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/party-dashboard.ts should not contain relative cia-data/ string literals","duration":0.7229440000000409,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/election-cycle.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/election-cycle.ts should not contain relative cia-data/ string literals","duration":0.5661499999999933,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/committees-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/committees-dashboard.ts should not contain relative cia-data/ string literals","duration":0.492621999999983,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/coalition-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/coalition-dashboard.ts should not contain relative cia-data/ string literals","duration":0.6088599999999929,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/seasonal-patterns.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/seasonal-patterns.ts should not contain relative cia-data/ string literals","duration":0.5966669999999681,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/pre-election.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/pre-election.ts should not contain relative cia-data/ string literals","duration":0.5828309999999988,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/anomaly-detection.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/anomaly-detection.ts should not contain relative cia-data/ string literals","duration":0.44594500000005155,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/ministry-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/ministry-dashboard.ts should not contain relative cia-data/ string literals","duration":0.7131750000000352,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/risk-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/risk-dashboard.ts should not contain relative cia-data/ string literals","duration":0.5447200000000407,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/politician-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/politician-dashboard.ts should not contain relative cia-data/ string literals","duration":0.48422600000003513,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/cia/data-loader.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/cia/data-loader.ts should not contain relative cia-data/ string literals","duration":0.3367709999999988,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]}],"startTime":1787953920266,"endTime":1787953920276.3367,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-cia-data-absolute-paths.test.ts"},{"assertionResults":[{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","stats-loader"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist stats-loader should have extraction_summary_report.csv","status":"passed","title":"should have extraction_summary_report.csv","duration":5.599212999999963,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_performance.csv","status":"passed","title":"should have party/distribution_party_performance.csv","duration":0.6956920000000082,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_effectiveness_trends.csv","status":"passed","title":"should have party/distribution_party_effectiveness_trends.csv","duration":0.5473949999999377,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_momentum.csv","status":"passed","title":"should have party/distribution_party_momentum.csv","duration":0.5372660000000451,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.4923720000000458,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_annual_party_members.csv","status":"passed","title":"should have party/distribution_annual_party_members.csv","duration":0.630410999999981,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_annual_party_votes.csv","status":"passed","title":"should have party/distribution_annual_party_votes.csv","duration":0.47763399999996636,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_comparative_analysis_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_comparative_analysis_sample.csv","duration":0.5038030000000617,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_decision_intelligence_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_decision_intelligence_sample.csv","duration":0.6714769999999817,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_predictive_intelligence_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_predictive_intelligence_sample.csv","duration":0.45960999999999785,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_temporal_trends_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_temporal_trends_sample.csv","duration":0.579072999999994,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have distribution_committee_productivity_matrix.csv","status":"passed","title":"should have distribution_committee_productivity_matrix.csv","duration":0.4751499999999851,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have view_riksdagen_committee_decisions.csv","status":"passed","title":"should have view_riksdagen_committee_decisions.csv","duration":0.5318260000000237,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have distribution_annual_committee_documents.csv","status":"passed","title":"should have distribution_annual_committee_documents.csv","duration":0.5498000000000047,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have view_riksdagen_committee_ballot_decision_party_summary.csv","status":"passed","title":"should have view_riksdagen_committee_ballot_decision_party_summary.csv","duration":0.6029690000000301,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have percentile_seasonal_activity_patterns.csv","status":"passed","title":"should have percentile_seasonal_activity_patterns.csv","duration":0.6201710000000276,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.4959689999999455,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have parties/distribution_behavioral_patterns_by_party.csv","status":"passed","title":"should have parties/distribution_behavioral_patterns_by_party.csv","duration":0.5214160000000447,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have parties/distribution_decision_patterns_by_party.csv","status":"passed","title":"should have parties/distribution_decision_patterns_by_party.csv","duration":0.5136919999999918,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have anomaly/distribution_anomaly_by_party.csv","status":"passed","title":"should have anomaly/distribution_anomaly_by_party.csv","duration":0.5611809999999195,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have voting/distribution_annual_party_votes.csv","status":"passed","title":"should have voting/distribution_annual_party_votes.csv","duration":0.6086090000000013,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have voting/distribution_decision_trends.csv","status":"passed","title":"should have voting/distribution_decision_trends.csv","duration":0.6502369999999473,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have distribution_party_momentum.csv","status":"passed","title":"should have distribution_party_momentum.csv","duration":0.7288549999999532,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist seasonal-patterns should have seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv","status":"passed","title":"should have seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv","duration":0.6068559999999934,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist pre-election should have pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv","status":"passed","title":"should have pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv","duration":0.6383150000000342,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist pre-election should have pre-election/view_riksdagen_q4_election_year_comparison_sample.csv","status":"passed","title":"should have pre-election/view_riksdagen_q4_election_year_comparison_sample.csv","duration":0.680072999999993,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist anomaly-detection should have seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv","status":"passed","title":"should have seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv","duration":0.6683819999999514,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_risk_levels.csv","status":"passed","title":"should have ministry/distribution_ministry_risk_levels.csv","duration":0.7412980000000289,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_productivity_matrix.csv","status":"passed","title":"should have ministry/distribution_ministry_productivity_matrix.csv","duration":0.6567389999999023,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_decision_impact.csv","status":"passed","title":"should have ministry/distribution_ministry_decision_impact.csv","duration":0.7150990000000093,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_effectiveness.csv","status":"passed","title":"should have ministry/distribution_ministry_effectiveness.csv","duration":1.0243679999999813,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_risk_quarterly.csv","status":"passed","title":"should have ministry/distribution_ministry_risk_quarterly.csv","duration":1.049955999999952,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist risk-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":0.7811030000000301,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":0.8979810000000725,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_riksdagen_politician_influence_metrics_sample.csv","status":"passed","title":"should have politician/view_riksdagen_politician_influence_metrics_sample.csv","duration":0.9584439999999859,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_politician_behavioral_trends_sample.csv","status":"passed","title":"should have politician/view_politician_behavioral_trends_sample.csv","duration":0.8222799999999779,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_experience_levels.csv","status":"passed","title":"should have politician/distribution_experience_levels.csv","duration":0.7723059999999577,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_influence_buckets.csv","status":"passed","title":"should have politician/distribution_influence_buckets.csv","duration":0.8230109999999513,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_assignment_roles.csv","status":"passed","title":"should have politician/distribution_assignment_roles.csv","duration":0.8747270000000071,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_person_status.csv","status":"passed","title":"should have distribution_person_status.csv","duration":0.9377259999999978,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_risk_by_party.csv","status":"passed","title":"should have distribution_risk_by_party.csv","duration":1.0357989999999972,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_politician_risk_levels.csv","status":"passed","title":"should have distribution_politician_risk_levels.csv","duration":1.0904620000000023,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_annual_ballots.csv","status":"passed","title":"should have voting/distribution_annual_ballots.csv","duration":0.9551079999999956,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have risk/distribution_crisis_resilience.csv","status":"passed","title":"should have risk/distribution_crisis_resilience.csv","duration":0.9137200000000121,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_performance.csv","status":"passed","title":"should have party/distribution_party_performance.csv","duration":0.9813669999999775,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/view_party_performance_metrics_sample.csv","status":"passed","title":"should have party/view_party_performance_metrics_sample.csv","duration":0.9355219999999917,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_momentum.csv","status":"passed","title":"should have party/distribution_party_momentum.csv","duration":1.0406279999999697,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_annual_party_members.csv","status":"passed","title":"should have party/distribution_annual_party_members.csv","duration":0.9494979999999487,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have politician/view_riksdagen_politician_influence_metrics_sample.csv","status":"passed","title":"should have politician/view_riksdagen_politician_influence_metrics_sample.csv","duration":1.0923050000000103,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":1.0139580000000024,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have committee/distribution_committee_productivity.csv","status":"passed","title":"should have committee/distribution_committee_productivity.csv","duration":1.060895999999957,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have committee/distribution_committee_activity.csv","status":"passed","title":"should have committee/distribution_committee_activity.csv","duration":1.0131069999999909,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_effectiveness_trends.csv","status":"passed","title":"should have party/distribution_party_effectiveness_trends.csv","duration":1.052930999999944,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/election_forecast.csv","status":"passed","title":"should have election/election_forecast.csv","duration":10.53108599999996,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/coalition_scenarios.csv","status":"passed","title":"should have election/coalition_scenarios.csv","duration":1.6754869999999755,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.869638000000009,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_gender_by_party.csv","status":"passed","title":"should have party/distribution_gender_by_party.csv","duration":0.6466709999999694,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_experience_by_party.csv","status":"passed","title":"should have party/distribution_experience_by_party.csv","duration":0.7506050000000641,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have ministry/distribution_ministry_effectiveness.csv","status":"passed","title":"should have ministry/distribution_ministry_effectiveness.csv","duration":0.7803409999999076,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_annual_document_types.csv","status":"passed","title":"should have voting/distribution_annual_document_types.csv","duration":0.7458370000000514,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_decision_trends.csv","status":"passed","title":"should have voting/distribution_decision_trends.csv","duration":0.6907429999999977,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/distribution_election_regions.csv","status":"passed","title":"should have election/distribution_election_regions.csv","duration":0.8227299999999786,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have view_riksdagen_goverment_role_member_sample.csv","status":"passed","title":"should have view_riksdagen_goverment_role_member_sample.csv","duration":0.7394350000000713,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_risk_evolution_temporal.csv","status":"passed","title":"should have distribution_risk_evolution_temporal.csv","duration":0.958295000000021,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_behavioral_patterns_by_party.csv","status":"passed","title":"should have party/distribution_behavioral_patterns_by_party.csv","duration":0.8838749999999891,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","stats-loader"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) stats-loader extraction_summary_report.csv should have at least 1 data row","status":"passed","title":"extraction_summary_report.csv should have at least 1 data row","duration":1.1547109999999066,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_performance.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_performance.csv should have at least 1 data row","duration":0.8419360000000324,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_effectiveness_trends.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_effectiveness_trends.csv should have at least 1 data row","duration":0.8966589999999997,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_momentum.csv should have at least 1 data row","duration":1.1760810000000674,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":0.914421999999945,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_annual_party_members.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_members.csv should have at least 1 data row","duration":0.912488000000053,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_annual_party_votes.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_votes.csv should have at least 1 data row","duration":0.9587849999999207,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_comparative_analysis_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_comparative_analysis_sample.csv should have at least 1 data row","duration":0.9780809999999747,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_decision_intelligence_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_decision_intelligence_sample.csv should have at least 1 data row","duration":0.992678000000069,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_predictive_intelligence_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_predictive_intelligence_sample.csv should have at least 1 data row","duration":0.9686440000000403,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_temporal_trends_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_temporal_trends_sample.csv should have at least 1 data row","duration":0.9995710000000599,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard distribution_committee_productivity_matrix.csv should have at least 1 data row","status":"passed","title":"distribution_committee_productivity_matrix.csv should have at least 1 data row","duration":1.0329739999999674,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard view_riksdagen_committee_decisions.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_committee_decisions.csv should have at least 1 data row","duration":37.17560900000001,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard distribution_annual_committee_documents.csv should have at least 1 data row","status":"passed","title":"distribution_annual_committee_documents.csv should have at least 1 data row","duration":1.9775220000000218,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard view_riksdagen_committee_ballot_decision_party_summary.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_committee_ballot_decision_party_summary.csv should have at least 1 data row","duration":41.16138000000001,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard percentile_seasonal_activity_patterns.csv should have at least 1 data row","status":"passed","title":"percentile_seasonal_activity_patterns.csv should have at least 1 data row","duration":1.7485940000000255,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":1.2380970000000389,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard parties/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"parties/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","duration":1.7507880000000569,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard parties/distribution_decision_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"parties/distribution_decision_patterns_by_party.csv should have at least 1 data row","duration":1.5090250000000651,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard anomaly/distribution_anomaly_by_party.csv should have at least 1 data row","status":"passed","title":"anomaly/distribution_anomaly_by_party.csv should have at least 1 data row","duration":1.2337390000000141,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard voting/distribution_annual_party_votes.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_party_votes.csv should have at least 1 data row","duration":1.2382989999999836,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard voting/distribution_decision_trends.csv should have at least 1 data row","status":"passed","title":"voting/distribution_decision_trends.csv should have at least 1 data row","duration":1.2425369999999702,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"distribution_party_momentum.csv should have at least 1 data row","duration":1.2430970000000343,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) seasonal-patterns seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv should have at least 1 data row","status":"passed","title":"seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv should have at least 1 data row","duration":1.2833119999999099,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) pre-election pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv should have at least 1 data row","status":"passed","title":"pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv should have at least 1 data row","duration":1.3224860000000263,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) pre-election pre-election/view_riksdagen_q4_election_year_comparison_sample.csv should have at least 1 data row","status":"passed","title":"pre-election/view_riksdagen_q4_election_year_comparison_sample.csv should have at least 1 data row","duration":1.268624999999929,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) anomaly-detection seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv should have at least 1 data row","status":"passed","title":"seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv should have at least 1 data row","duration":1.3180869999999913,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_risk_levels.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_risk_levels.csv should have at least 1 data row","duration":1.3708870000000388,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_productivity_matrix.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_productivity_matrix.csv should have at least 1 data row","duration":1.4474700000000666,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_decision_impact.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_decision_impact.csv should have at least 1 data row","duration":1.3610479999999825,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","duration":1.3402399999999943,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_risk_quarterly.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_risk_quarterly.csv should have at least 1 data row","duration":1.4210610000000088,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) risk-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.5765010000000075,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.5276799999999184,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","duration":1.4836480000000165,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_politician_behavioral_trends_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_behavioral_trends_sample.csv should have at least 1 data row","duration":1.5893049999999675,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_experience_levels.csv should have at least 1 data row","status":"passed","title":"politician/distribution_experience_levels.csv should have at least 1 data row","duration":1.6629330000000664,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_influence_buckets.csv should have at least 1 data row","status":"passed","title":"politician/distribution_influence_buckets.csv should have at least 1 data row","duration":1.625583000000006,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_assignment_roles.csv should have at least 1 data row","status":"passed","title":"politician/distribution_assignment_roles.csv should have at least 1 data row","duration":1.8617859999999382,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_person_status.csv should have at least 1 data row","status":"passed","title":"distribution_person_status.csv should have at least 1 data row","duration":1.5738470000000007,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_risk_by_party.csv should have at least 1 data row","status":"passed","title":"distribution_risk_by_party.csv should have at least 1 data row","duration":1.5334020000000237,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_politician_risk_levels.csv should have at least 1 data row","status":"passed","title":"distribution_politician_risk_levels.csv should have at least 1 data row","duration":1.5451219999999921,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_annual_ballots.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_ballots.csv should have at least 1 data row","duration":1.5782749999999623,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard risk/distribution_crisis_resilience.csv should have at least 1 data row","status":"passed","title":"risk/distribution_crisis_resilience.csv should have at least 1 data row","duration":1.5978020000000015,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_performance.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_performance.csv should have at least 1 data row","duration":1.649989000000005,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/view_party_performance_metrics_sample.csv should have at least 1 data row","status":"passed","title":"party/view_party_performance_metrics_sample.csv should have at least 1 data row","duration":1.6236289999999372,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_momentum.csv should have at least 1 data row","duration":1.6651669999999967,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_annual_party_members.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_members.csv should have at least 1 data row","duration":1.7462889999999334,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","duration":1.7240980000000263,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.7549850000000333,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard committee/distribution_committee_productivity.csv should have at least 1 data row","status":"passed","title":"committee/distribution_committee_productivity.csv should have at least 1 data row","duration":1.754905000000008,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard committee/distribution_committee_activity.csv should have at least 1 data row","status":"passed","title":"committee/distribution_committee_activity.csv should have at least 1 data row","duration":2.016905999999949,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_effectiveness_trends.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_effectiveness_trends.csv should have at least 1 data row","duration":2.2165699999999333,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/election_forecast.csv should have at least 1 data row","status":"passed","title":"election/election_forecast.csv should have at least 1 data row","duration":3.034730999999965,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/coalition_scenarios.csv should have at least 1 data row","status":"passed","title":"election/coalition_scenarios.csv should have at least 1 data row","duration":2.931838999999968,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":2.992082000000096,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_gender_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_gender_by_party.csv should have at least 1 data row","duration":3.0278279999999995,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_experience_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_experience_by_party.csv should have at least 1 data row","duration":3.0259750000000167,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","duration":2.579168999999979,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_annual_document_types.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_document_types.csv should have at least 1 data row","duration":1.951133000000027,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_decision_trends.csv should have at least 1 data row","status":"passed","title":"voting/distribution_decision_trends.csv should have at least 1 data row","duration":1.9735449999999446,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/distribution_election_regions.csv should have at least 1 data row","status":"passed","title":"election/distribution_election_regions.csv should have at least 1 data row","duration":2.231518000000051,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard view_riksdagen_goverment_role_member_sample.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_goverment_role_member_sample.csv should have at least 1 data row","duration":2.0242600000000266,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_risk_evolution_temporal.csv should have at least 1 data row","status":"passed","title":"distribution_risk_evolution_temporal.csv should have at least 1 data row","duration":1.9768109999999979,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","duration":1.953467000000046,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist stats-loader module should exist at src/browser/dashboards/stats-loader.ts","status":"passed","title":"stats-loader module should exist at src/browser/dashboards/stats-loader.ts","duration":2.0947720000000345,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist party-dashboard module should exist at src/browser/dashboards/party-dashboard.ts","status":"passed","title":"party-dashboard module should exist at src/browser/dashboards/party-dashboard.ts","duration":2.8252599999999575,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist election-cycle module should exist at src/browser/dashboards/election-cycle.ts","status":"passed","title":"election-cycle module should exist at src/browser/dashboards/election-cycle.ts","duration":1.9618030000000317,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist committees-dashboard module should exist at src/browser/dashboards/committees-dashboard.ts","status":"passed","title":"committees-dashboard module should exist at src/browser/dashboards/committees-dashboard.ts","duration":2.045178999999962,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist coalition-dashboard module should exist at src/browser/dashboards/coalition-dashboard.ts","status":"passed","title":"coalition-dashboard module should exist at src/browser/dashboards/coalition-dashboard.ts","duration":1.9862880000000587,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist seasonal-patterns module should exist at src/browser/dashboards/seasonal-patterns.ts","status":"passed","title":"seasonal-patterns module should exist at src/browser/dashboards/seasonal-patterns.ts","duration":2.10187499999995,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist pre-election module should exist at src/browser/dashboards/pre-election.ts","status":"passed","title":"pre-election module should exist at src/browser/dashboards/pre-election.ts","duration":2.786016000000018,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist anomaly-detection module should exist at src/browser/dashboards/anomaly-detection.ts","status":"passed","title":"anomaly-detection module should exist at src/browser/dashboards/anomaly-detection.ts","duration":2.321446000000037,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist ministry-dashboard module should exist at src/browser/dashboards/ministry-dashboard.ts","status":"passed","title":"ministry-dashboard module should exist at src/browser/dashboards/ministry-dashboard.ts","duration":2.0904339999999593,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist risk-dashboard module should exist at src/browser/dashboards/risk-dashboard.ts","status":"passed","title":"risk-dashboard module should exist at src/browser/dashboards/risk-dashboard.ts","duration":2.0866060000000743,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist politician-dashboard module should exist at src/browser/dashboards/politician-dashboard.ts","status":"passed","title":"politician-dashboard module should exist at src/browser/dashboards/politician-dashboard.ts","duration":2.144935999999916,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist cia-dashboard module should exist at src/browser/cia/data-loader.ts","status":"passed","title":"cia-dashboard module should exist at src/browser/cia/data-loader.ts","duration":2.0981879999999364,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/parties.html should have container #party-dashboard","status":"passed","title":"dashboards/parties.html should have container #party-dashboard","duration":2.4655050000000074,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/election-cycle.html should have container #election-cycle-dashboard","status":"passed","title":"dashboards/election-cycle.html should have container #election-cycle-dashboard","duration":2.206099999999992,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/committees.html should have container #committee-dashboard","status":"passed","title":"dashboards/committees.html should have container #committee-dashboard","duration":2.232138999999961,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/coalitions.html should have container #coalition-dashboard","status":"passed","title":"dashboards/coalitions.html should have container #coalition-dashboard","duration":2.224815000000035,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/seasonal-patterns.html should have container #seasonal-patterns-dashboard","status":"passed","title":"dashboards/seasonal-patterns.html should have container #seasonal-patterns-dashboard","duration":2.2563149999999723,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/pre-election.html should have container #pre-election-dashboard","status":"passed","title":"dashboards/pre-election.html should have container #pre-election-dashboard","duration":2.268387000000075,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/anomaly-detection.html should have container #anomaly-detection-dashboard","status":"passed","title":"dashboards/anomaly-detection.html should have container #anomaly-detection-dashboard","duration":2.3275580000000673,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/ministers.html should have container #ministry-dashboard","status":"passed","title":"dashboards/ministers.html should have container #ministry-dashboard","duration":2.3131309999999985,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/risk.html should have container #risk-dashboard","status":"passed","title":"dashboards/risk.html should have container #risk-dashboard","duration":2.3287599999999884,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) index.html should expose a hub linking to every specialised dashboard","status":"passed","title":"index.html should expose a hub linking to every specialised dashboard","duration":2.8866140000000087,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties.html","status":"passed","title":"should have dashboards/parties.html","duration":2.542780999999991,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ar.html","status":"passed","title":"should have dashboards/parties_ar.html","duration":2.3798550000000205,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_da.html","status":"passed","title":"should have dashboards/parties_da.html","duration":2.6971999999999525,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_de.html","status":"passed","title":"should have dashboards/parties_de.html","duration":2.8006829999999354,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_es.html","status":"passed","title":"should have dashboards/parties_es.html","duration":2.7939409999999043,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_fi.html","status":"passed","title":"should have dashboards/parties_fi.html","duration":2.757863999999927,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_fr.html","status":"passed","title":"should have dashboards/parties_fr.html","duration":3.218766999999957,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_he.html","status":"passed","title":"should have dashboards/parties_he.html","duration":3.6370090000000346,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ja.html","status":"passed","title":"should have dashboards/parties_ja.html","duration":2.895972000000029,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ko.html","status":"passed","title":"should have dashboards/parties_ko.html","duration":2.81570099999999,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_nl.html","status":"passed","title":"should have dashboards/parties_nl.html","duration":2.8666170000000193,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_no.html","status":"passed","title":"should have dashboards/parties_no.html","duration":3.3694080000000213,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_sv.html","status":"passed","title":"should have dashboards/parties_sv.html","duration":2.9132339999999886,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_zh.html","status":"passed","title":"should have dashboards/parties_zh.html","duration":2.981612000000041,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle.html","status":"passed","title":"should have dashboards/election-cycle.html","duration":2.921880999999985,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ar.html","status":"passed","title":"should have dashboards/election-cycle_ar.html","duration":2.9582580000000007,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_da.html","status":"passed","title":"should have dashboards/election-cycle_da.html","duration":2.986340999999925,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_de.html","status":"passed","title":"should have dashboards/election-cycle_de.html","duration":3.0245929999999817,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_es.html","status":"passed","title":"should have dashboards/election-cycle_es.html","duration":3.0031529999999975,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_fi.html","status":"passed","title":"should have dashboards/election-cycle_fi.html","duration":3.113609999999994,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_fr.html","status":"passed","title":"should have dashboards/election-cycle_fr.html","duration":3.1253510000000233,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_he.html","status":"passed","title":"should have dashboards/election-cycle_he.html","duration":3.0500599999999167,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ja.html","status":"passed","title":"should have dashboards/election-cycle_ja.html","duration":3.1601669999998876,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ko.html","status":"passed","title":"should have dashboards/election-cycle_ko.html","duration":3.185504000000037,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_nl.html","status":"passed","title":"should have dashboards/election-cycle_nl.html","duration":3.2113319999998566,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_no.html","status":"passed","title":"should have dashboards/election-cycle_no.html","duration":3.188218000000006,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_sv.html","status":"passed","title":"should have dashboards/election-cycle_sv.html","duration":3.233793999999989,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_zh.html","status":"passed","title":"should have dashboards/election-cycle_zh.html","duration":3.245335999999952,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees.html","status":"passed","title":"should have dashboards/committees.html","duration":3.192145999999866,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ar.html","status":"passed","title":"should have dashboards/committees_ar.html","duration":4.407651999999871,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_da.html","status":"passed","title":"should have dashboards/committees_da.html","duration":3.7056569999999738,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_de.html","status":"passed","title":"should have dashboards/committees_de.html","duration":3.5906320000001415,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_es.html","status":"passed","title":"should have dashboards/committees_es.html","duration":3.356924999999819,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_fi.html","status":"passed","title":"should have dashboards/committees_fi.html","duration":3.4020889999999326,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_fr.html","status":"passed","title":"should have dashboards/committees_fr.html","duration":4.975676000000021,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_he.html","status":"passed","title":"should have dashboards/committees_he.html","duration":3.1892599999998765,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ja.html","status":"passed","title":"should have dashboards/committees_ja.html","duration":3.1212530000000243,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ko.html","status":"passed","title":"should have dashboards/committees_ko.html","duration":4.060301999999865,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_nl.html","status":"passed","title":"should have dashboards/committees_nl.html","duration":3.3645289999999477,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_no.html","status":"passed","title":"should have dashboards/committees_no.html","duration":3.126022000000148,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_sv.html","status":"passed","title":"should have dashboards/committees_sv.html","duration":3.0949439999999413,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_zh.html","status":"passed","title":"should have dashboards/committees_zh.html","duration":3.1771179999998367,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions.html","status":"passed","title":"should have dashboards/coalitions.html","duration":3.147502999999915,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ar.html","status":"passed","title":"should have dashboards/coalitions_ar.html","duration":3.188840999999911,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_da.html","status":"passed","title":"should have dashboards/coalitions_da.html","duration":3.2002919999999904,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_de.html","status":"passed","title":"should have dashboards/coalitions_de.html","duration":3.419502000000193,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_es.html","status":"passed","title":"should have dashboards/coalitions_es.html","duration":3.2685599999999795,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_fi.html","status":"passed","title":"should have dashboards/coalitions_fi.html","duration":3.4704269999999724,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_fr.html","status":"passed","title":"should have dashboards/coalitions_fr.html","duration":3.3555730000000494,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_he.html","status":"passed","title":"should have dashboards/coalitions_he.html","duration":3.3230610000000524,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ja.html","status":"passed","title":"should have dashboards/coalitions_ja.html","duration":3.262678000000051,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ko.html","status":"passed","title":"should have dashboards/coalitions_ko.html","duration":3.264652000000069,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_nl.html","status":"passed","title":"should have dashboards/coalitions_nl.html","duration":3.2768650000000434,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_no.html","status":"passed","title":"should have dashboards/coalitions_no.html","duration":3.7022309999999834,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_sv.html","status":"passed","title":"should have dashboards/coalitions_sv.html","duration":3.3327690000000985,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_zh.html","status":"passed","title":"should have dashboards/coalitions_zh.html","duration":3.3813199999999597,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns.html","status":"passed","title":"should have dashboards/seasonal-patterns.html","duration":3.4339380000001256,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ar.html","status":"passed","title":"should have dashboards/seasonal-patterns_ar.html","duration":3.3861490000001595,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_da.html","status":"passed","title":"should have dashboards/seasonal-patterns_da.html","duration":3.4364129999999022,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_de.html","status":"passed","title":"should have dashboards/seasonal-patterns_de.html","duration":3.4388080000001082,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_es.html","status":"passed","title":"should have dashboards/seasonal-patterns_es.html","duration":3.464465999999902,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_fi.html","status":"passed","title":"should have dashboards/seasonal-patterns_fi.html","duration":3.6116309999999885,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_fr.html","status":"passed","title":"should have dashboards/seasonal-patterns_fr.html","duration":3.8404900000000453,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_he.html","status":"passed","title":"should have dashboards/seasonal-patterns_he.html","duration":3.6819440000001578,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ja.html","status":"passed","title":"should have dashboards/seasonal-patterns_ja.html","duration":3.6913899999999558,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ko.html","status":"passed","title":"should have dashboards/seasonal-patterns_ko.html","duration":3.8546269999999367,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_nl.html","status":"passed","title":"should have dashboards/seasonal-patterns_nl.html","duration":3.958421000000044,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_no.html","status":"passed","title":"should have dashboards/seasonal-patterns_no.html","duration":6.928883000000042,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_sv.html","status":"passed","title":"should have dashboards/seasonal-patterns_sv.html","duration":5.642364000000043,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_zh.html","status":"passed","title":"should have dashboards/seasonal-patterns_zh.html","duration":3.811805999999933,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election.html","status":"passed","title":"should have dashboards/pre-election.html","duration":3.7086629999998877,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ar.html","status":"passed","title":"should have dashboards/pre-election_ar.html","duration":3.9932960000001003,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_da.html","status":"passed","title":"should have dashboards/pre-election_da.html","duration":3.7344009999999344,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_de.html","status":"passed","title":"should have dashboards/pre-election_de.html","duration":3.736855999999989,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_es.html","status":"passed","title":"should have dashboards/pre-election_es.html","duration":3.713412000000062,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_fi.html","status":"passed","title":"should have dashboards/pre-election_fi.html","duration":3.7209069999998974,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_fr.html","status":"passed","title":"should have dashboards/pre-election_fr.html","duration":3.7625040000000354,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_he.html","status":"passed","title":"should have dashboards/pre-election_he.html","duration":3.843847000000096,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ja.html","status":"passed","title":"should have dashboards/pre-election_ja.html","duration":3.938323000000082,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ko.html","status":"passed","title":"should have dashboards/pre-election_ko.html","duration":4.94437599999992,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_nl.html","status":"passed","title":"should have dashboards/pre-election_nl.html","duration":3.9819350000000213,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_no.html","status":"passed","title":"should have dashboards/pre-election_no.html","duration":3.8789520000000266,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_sv.html","status":"passed","title":"should have dashboards/pre-election_sv.html","duration":3.8948120000000017,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_zh.html","status":"passed","title":"should have dashboards/pre-election_zh.html","duration":3.8387259999999515,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection.html","status":"passed","title":"should have dashboards/anomaly-detection.html","duration":3.8756459999999606,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ar.html","status":"passed","title":"should have dashboards/anomaly-detection_ar.html","duration":3.9745909999999185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_da.html","status":"passed","title":"should have dashboards/anomaly-detection_da.html","duration":3.9285440000001017,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_de.html","status":"passed","title":"should have dashboards/anomaly-detection_de.html","duration":3.999427000000196,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_es.html","status":"passed","title":"should have dashboards/anomaly-detection_es.html","duration":3.9365190000000894,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_fi.html","status":"passed","title":"should have dashboards/anomaly-detection_fi.html","duration":3.991703000000143,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_fr.html","status":"passed","title":"should have dashboards/anomaly-detection_fr.html","duration":4.039143000000195,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_he.html","status":"passed","title":"should have dashboards/anomaly-detection_he.html","duration":4.695570999999973,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ja.html","status":"passed","title":"should have dashboards/anomaly-detection_ja.html","duration":7.2826440000001185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ko.html","status":"passed","title":"should have dashboards/anomaly-detection_ko.html","duration":5.03227099999981,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_nl.html","status":"passed","title":"should have dashboards/anomaly-detection_nl.html","duration":4.163994999999886,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_no.html","status":"passed","title":"should have dashboards/anomaly-detection_no.html","duration":4.195795000000089,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_sv.html","status":"passed","title":"should have dashboards/anomaly-detection_sv.html","duration":4.129411000000118,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_zh.html","status":"passed","title":"should have dashboards/anomaly-detection_zh.html","duration":4.183881999999812,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers.html","status":"passed","title":"should have dashboards/ministers.html","duration":4.204661999999871,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ar.html","status":"passed","title":"should have dashboards/ministers_ar.html","duration":4.292445999999927,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_da.html","status":"passed","title":"should have dashboards/ministers_da.html","duration":4.641950000000179,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_de.html","status":"passed","title":"should have dashboards/ministers_de.html","duration":4.3154490000001715,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_es.html","status":"passed","title":"should have dashboards/ministers_es.html","duration":4.337660999999798,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_fi.html","status":"passed","title":"should have dashboards/ministers_fi.html","duration":4.249745999999959,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_fr.html","status":"passed","title":"should have dashboards/ministers_fr.html","duration":4.406048999999939,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_he.html","status":"passed","title":"should have dashboards/ministers_he.html","duration":4.357868000000053,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ja.html","status":"passed","title":"should have dashboards/ministers_ja.html","duration":4.312364000000116,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ko.html","status":"passed","title":"should have dashboards/ministers_ko.html","duration":4.332540999999992,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_nl.html","status":"passed","title":"should have dashboards/ministers_nl.html","duration":4.356326000000081,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_no.html","status":"passed","title":"should have dashboards/ministers_no.html","duration":5.867966000000024,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_sv.html","status":"passed","title":"should have dashboards/ministers_sv.html","duration":4.362437,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_zh.html","status":"passed","title":"should have dashboards/ministers_zh.html","duration":4.349993999999924,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk.html","status":"passed","title":"should have dashboards/risk.html","duration":4.367095999999947,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ar.html","status":"passed","title":"should have dashboards/risk_ar.html","duration":5.496751000000131,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_da.html","status":"passed","title":"should have dashboards/risk_da.html","duration":7.40843000000018,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_de.html","status":"passed","title":"should have dashboards/risk_de.html","duration":4.321300000000065,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_es.html","status":"passed","title":"should have dashboards/risk_es.html","duration":4.387152999999898,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_fi.html","status":"passed","title":"should have dashboards/risk_fi.html","duration":4.537374999999884,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_fr.html","status":"passed","title":"should have dashboards/risk_fr.html","duration":5.620722999999998,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_he.html","status":"passed","title":"should have dashboards/risk_he.html","duration":4.461121999999932,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ja.html","status":"passed","title":"should have dashboards/risk_ja.html","duration":4.569584999999961,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ko.html","status":"passed","title":"should have dashboards/risk_ko.html","duration":4.605983000000151,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_nl.html","status":"passed","title":"should have dashboards/risk_nl.html","duration":4.6277339999999185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_no.html","status":"passed","title":"should have dashboards/risk_no.html","duration":4.680482999999867,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_sv.html","status":"passed","title":"should have dashboards/risk_sv.html","duration":4.704177000000072,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_zh.html","status":"passed","title":"should have dashboards/risk_zh.html","duration":4.841773999999987,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index.html","status":"passed","title":"should have dashboard/index.html","duration":5.2398809999999685,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ar.html","status":"passed","title":"should have dashboard/index_ar.html","duration":4.876369000000068,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_da.html","status":"passed","title":"should have dashboard/index_da.html","duration":4.757697000000007,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_de.html","status":"passed","title":"should have dashboard/index_de.html","duration":4.752216999999973,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_es.html","status":"passed","title":"should have dashboard/index_es.html","duration":4.8059079999998175,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_fi.html","status":"passed","title":"should have dashboard/index_fi.html","duration":5.067397000000028,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_fr.html","status":"passed","title":"should have dashboard/index_fr.html","duration":4.869497000000138,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_he.html","status":"passed","title":"should have dashboard/index_he.html","duration":4.786761999999953,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ja.html","status":"passed","title":"should have dashboard/index_ja.html","duration":6.147860000000037,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ko.html","status":"passed","title":"should have dashboard/index_ko.html","duration":7.8623099999999795,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_nl.html","status":"passed","title":"should have dashboard/index_nl.html","duration":7.992463000000043,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_no.html","status":"passed","title":"should have dashboard/index_no.html","duration":6.113565999999992,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_sv.html","status":"passed","title":"should have dashboard/index_sv.html","duration":4.783124999999927,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_zh.html","status":"passed","title":"should have dashboard/index_zh.html","duration":4.85718299999985,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index.html","status":"passed","title":"should have index.html","duration":4.951189999999997,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ar.html","status":"passed","title":"should have index_ar.html","duration":4.872270999999955,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_da.html","status":"passed","title":"should have index_da.html","duration":4.890415999999959,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_de.html","status":"passed","title":"should have index_de.html","duration":4.914620999999897,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_es.html","status":"passed","title":"should have index_es.html","duration":4.975083999999924,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_fi.html","status":"passed","title":"should have index_fi.html","duration":5.9094239999999445,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_fr.html","status":"passed","title":"should have index_fr.html","duration":5.428592999999864,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_he.html","status":"passed","title":"should have index_he.html","duration":5.049984999999879,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ja.html","status":"passed","title":"should have index_ja.html","duration":5.384671000000026,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ko.html","status":"passed","title":"should have index_ko.html","duration":5.134763000000021,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_nl.html","status":"passed","title":"should have index_nl.html","duration":5.0388940000000275,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_no.html","status":"passed","title":"should have index_no.html","duration":5.03053900000009,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_sv.html","status":"passed","title":"should have index_sv.html","duration":6.335581000000047,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_zh.html","status":"passed","title":"should have index_zh.html","duration":5.565860000000157,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for en (default)","status":"passed","title":"should have politician dashboard for en (default)","duration":5.224250999999867,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ar","status":"passed","title":"should have politician dashboard for ar","duration":5.201207999999951,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for da","status":"passed","title":"should have politician dashboard for da","duration":5.139942999999903,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for de","status":"passed","title":"should have politician dashboard for de","duration":5.458919999999807,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for es","status":"passed","title":"should have politician dashboard for es","duration":5.127550000000156,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for fi","status":"passed","title":"should have politician dashboard for fi","duration":5.149812000000111,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for fr","status":"passed","title":"should have politician dashboard for fr","duration":5.179576999999881,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for he","status":"passed","title":"should have politician dashboard for he","duration":5.190237000000025,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ja","status":"passed","title":"should have politician dashboard for ja","duration":5.179787999999917,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ko","status":"passed","title":"should have politician dashboard for ko","duration":5.349294999999984,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for nl","status":"passed","title":"should have politician dashboard for nl","duration":5.411611999999877,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for no","status":"passed","title":"should have politician dashboard for no","duration":5.3193389999999,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for sv","status":"passed","title":"should have politician dashboard for sv","duration":5.830726000000141,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for zh","status":"passed","title":"should have politician dashboard for zh","duration":5.344625999999835,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for en (default)","status":"passed","title":"should have political intelligence for en (default)","duration":5.377036000000089,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ar","status":"passed","title":"should have political intelligence for ar","duration":5.529381000000058,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for da","status":"passed","title":"should have political intelligence for da","duration":5.361327000000074,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for de","status":"passed","title":"should have political intelligence for de","duration":5.5581459999998515,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for es","status":"passed","title":"should have political intelligence for es","duration":8.511514999999918,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for fi","status":"passed","title":"should have political intelligence for fi","duration":5.6767979999999625,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for fr","status":"passed","title":"should have political intelligence for fr","duration":5.516658000000007,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for he","status":"passed","title":"should have political intelligence for he","duration":5.3816249999999854,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ja","status":"passed","title":"should have political intelligence for ja","duration":5.549710000000005,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ko","status":"passed","title":"should have political intelligence for ko","duration":5.412943999999925,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for nl","status":"passed","title":"should have political intelligence for nl","duration":5.462737999999945,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for no","status":"passed","title":"should have political intelligence for no","duration":5.489045999999917,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for sv","status":"passed","title":"should have political intelligence for sv","duration":5.604763000000048,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for zh","status":"passed","title":"should have political intelligence for zh","duration":5.615072000000055,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index.html","status":"passed","title":"should promote Political Intelligence on index.html","duration":7.106044000000111,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index.html","duration":6.595276999999896,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ar.html","status":"passed","title":"should promote Political Intelligence on index_ar.html","duration":5.876492000000098,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ar.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ar.html","duration":5.8984629999999925,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_da.html","status":"passed","title":"should promote Political Intelligence on index_da.html","duration":5.946803999999929,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_da.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_da.html","duration":6.277471999999989,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_de.html","status":"passed","title":"should promote Political Intelligence on index_de.html","duration":6.579126999999971,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_de.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_de.html","duration":7.164663000000019,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_es.html","status":"passed","title":"should promote Political Intelligence on index_es.html","duration":5.963223999999855,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_es.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_es.html","duration":5.772607999999991,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_fi.html","status":"passed","title":"should promote Political Intelligence on index_fi.html","duration":5.589024000000109,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_fi.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_fi.html","duration":5.902659999999969,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_fr.html","status":"passed","title":"should promote Political Intelligence on index_fr.html","duration":6.1807410000001255,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_fr.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_fr.html","duration":6.01575200000002,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_he.html","status":"passed","title":"should promote Political Intelligence on index_he.html","duration":5.897420999999895,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_he.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_he.html","duration":5.748241999999891,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ja.html","status":"passed","title":"should promote Political Intelligence on index_ja.html","duration":5.824804999999969,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ja.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ja.html","duration":6.546196000000009,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ko.html","status":"passed","title":"should promote Political Intelligence on index_ko.html","duration":7.142381999999998,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ko.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ko.html","duration":7.100973999999951,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_nl.html","status":"passed","title":"should promote Political Intelligence on index_nl.html","duration":6.2275690000001305,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_nl.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_nl.html","duration":6.089079000000083,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_no.html","status":"passed","title":"should promote Political Intelligence on index_no.html","duration":6.0302399999998215,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_no.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_no.html","duration":6.769583999999895,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_sv.html","status":"passed","title":"should promote Political Intelligence on index_sv.html","duration":6.037814000000026,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_sv.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_sv.html","duration":7.133726000000024,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_zh.html","status":"passed","title":"should promote Political Intelligence on index_zh.html","duration":6.9788059999998495,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_zh.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_zh.html","duration":6.369434999999839,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"object_name\" in at least one CSV","status":"passed","title":"should have column \"object_name\" in at least one CSV","duration":6.324971999999889,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"row_count\" in at least one CSV","status":"passed","title":"should have column \"row_count\" in at least one CSV","duration":6.066266999999925,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"status\" in at least one CSV","status":"passed","title":"should have column \"status\" in at least one CSV","duration":6.101924000000054,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.653054999999995,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.917079999999942,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"momentum\" in at least one CSV","status":"passed","title":"should have column \"momentum\" in at least one CSV","duration":6.867897999999968,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.645060000000058,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party1\" in at least one CSV","status":"passed","title":"should have column \"party1\" in at least one CSV","duration":6.319651000000022,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party2\" in at least one CSV","status":"passed","title":"should have column \"party2\" in at least one CSV","duration":6.076215999999931,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"election_cycle_id\" in at least one CSV","status":"passed","title":"should have column \"election_cycle_id\" in at least one CSV","duration":5.9924899999998615,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.455355999999938,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"cycle_year\" in at least one CSV","status":"passed","title":"should have column \"cycle_year\" in at least one CSV","duration":6.669415999999956,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"overall_performance_score\" in at least one CSV","status":"passed","title":"should have column \"overall_performance_score\" in at least one CSV","duration":6.026382000000012,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"avg_approval_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_approval_rate\" in at least one CSV","duration":6.179578999999876,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"forecast_confidence\" in at least one CSV","status":"passed","title":"should have column \"forecast_confidence\" in at least one CSV","duration":6.123884999999973,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"semester\" in at least one CSV","status":"passed","title":"should have column \"semester\" in at least one CSV","duration":6.174479999999903,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.505288999999948,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"is_pre_election_semester\" in at least one CSV","status":"passed","title":"should have column \"is_pre_election_semester\" in at least one CSV","duration":6.586680999999999,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.650151000000051,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"committee\" in at least one CSV","status":"passed","title":"should have column \"committee\" in at least one CSV","duration":6.970389999999725,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"committee_code\" in at least one CSV","status":"passed","title":"should have column \"committee_code\" in at least one CSV","duration":6.703499999999622,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"productivity_level\" in at least one CSV","status":"passed","title":"should have column \"productivity_level\" in at least one CSV","duration":6.492816000000403,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":6.704643000000033,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.758522999999968,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party1\" in at least one CSV","status":"passed","title":"should have column \"party1\" in at least one CSV","duration":7.589477999999872,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party2\" in at least one CSV","status":"passed","title":"should have column \"party2\" in at least one CSV","duration":6.422533999999814,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.458662000000004,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"behavioral_assessment\" in at least one CSV","status":"passed","title":"should have column \"behavioral_assessment\" in at least one CSV","duration":9.357338000000254,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"anomaly_classification\" in at least one CSV","status":"passed","title":"should have column \"anomaly_classification\" in at least one CSV","duration":6.416983000000073,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"avg_rebellions\" in at least one CSV","status":"passed","title":"should have column \"avg_rebellions\" in at least one CSV","duration":6.329269999999724,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":6.238329000000249,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"vote_count\" in at least one CSV","status":"passed","title":"should have column \"vote_count\" in at least one CSV","duration":6.236986999999772,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.477606999999807,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":6.530967000000146,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.318087999999989,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"attendance_rate\" in at least one CSV","status":"passed","title":"should have column \"attendance_rate\" in at least one CSV","duration":6.457629999999881,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"documents_produced\" in at least one CSV","status":"passed","title":"should have column \"documents_produced\" in at least one CSV","duration":6.385203999999703,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"ballot_z_score\" in at least one CSV","status":"passed","title":"should have column \"ballot_z_score\" in at least one CSV","duration":6.316165000000183,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"doc_z_score\" in at least one CSV","status":"passed","title":"should have column \"doc_z_score\" in at least one CSV","duration":6.4097099999999045,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.392957999999908,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"is_election_year\" in at least one CSV","status":"passed","title":"should have column \"is_election_year\" in at least one CSV","duration":6.402927999999974,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"seasonal_pattern_classification\" in at least one CSV","status":"passed","title":"should have column \"seasonal_pattern_classification\" in at least one CSV","duration":6.994716000000153,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":8.026988000000074,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.9632769999998345,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"total_documents\" in at least one CSV","status":"passed","title":"should have column \"total_documents\" in at least one CSV","duration":6.693741999999929,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"is_election_year\" in at least one CSV","status":"passed","title":"should have column \"is_election_year\" in at least one CSV","duration":6.657605000000331,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"avg_party_win_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_party_win_rate\" in at least one CSV","duration":6.48194599999988,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"avg_party_absence_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_party_absence_rate\" in at least one CSV","duration":6.471495999999661,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":7.975612000000183,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":8.396318999999949,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"anomaly_severity\" in at least one CSV","status":"passed","title":"should have column \"anomaly_severity\" in at least one CSV","duration":6.980407999999898,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"anomaly_type\" in at least one CSV","status":"passed","title":"should have column \"anomaly_type\" in at least one CSV","duration":7.601652000000286,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"max_z_score\" in at least one CSV","status":"passed","title":"should have column \"max_z_score\" in at least one CSV","duration":6.7860340000002,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"ministry_name\" in at least one CSV","status":"passed","title":"should have column \"ministry_name\" in at least one CSV","duration":6.611748999999691,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"documents_produced\" in at least one CSV","status":"passed","title":"should have column \"documents_produced\" in at least one CSV","duration":6.775744999999915,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.620473999999831,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.928522000000157,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"ministry_code\" in at least one CSV","status":"passed","title":"should have column \"ministry_code\" in at least one CSV","duration":7.340773000000354,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"committee\" in at least one CSV","status":"passed","title":"should have column \"committee\" in at least one CSV","duration":6.805209999999988,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"approval_rate\" in at least one CSV","status":"passed","title":"should have column \"approval_rate\" in at least one CSV","duration":7.643630999999914,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"total_proposals\" in at least one CSV","status":"passed","title":"should have column \"total_proposals\" in at least one CSV","duration":6.891933000000336,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation risk-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.791274000000158,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"person_id\" in at least one CSV","status":"passed","title":"should have column \"person_id\" in at least one CSV","duration":6.753603999999996,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"first_name\" in at least one CSV","status":"passed","title":"should have column \"first_name\" in at least one CSV","duration":6.860855000000356,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"last_name\" in at least one CSV","status":"passed","title":"should have column \"last_name\" in at least one CSV","duration":7.0119380000001,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.741913000000295,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"risk_score\" in at least one CSV","status":"passed","title":"should have column \"risk_score\" in at least one CSV","duration":6.891442000000097,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"experience_level\" in at least one CSV","status":"passed","title":"should have column \"experience_level\" in at least one CSV","duration":7.157199999999648,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":6.962225000000217,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"influence_classification\" in at least one CSV","status":"passed","title":"should have column \"influence_classification\" in at least one CSV","duration":6.854021999999986,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.893285999999989,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":7.570553000000018,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.978935999999976,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":7.973789000000124,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"status\" in at least one CSV","status":"passed","title":"should have column \"status\" in at least one CSV","duration":6.966973000000053,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.9802480000003015,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"ministry_name\" in at least one CSV","status":"passed","title":"should have column \"ministry_name\" in at least one CSV","duration":7.024621000000025,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"effectiveness_assessment\" in at least one CSV","status":"passed","title":"should have column \"effectiveness_assessment\" in at least one CSV","duration":7.045300000000225,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation extraction_summary_report.csv should have at least 100 rows","status":"passed","title":"extraction_summary_report.csv should have at least 100 rows","duration":7.230005999999776,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation should contain view entries matching dashboard source views","status":"passed","title":"should contain view entries matching dashboard source views","duration":7.585802000000058,"failureMessages":[],"location":{"line":433,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation all source views should have success status","status":"passed","title":"all source views should have success status","duration":7.767111000000114,"failureMessages":[],"location":{"line":458,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CSV data quality summary"],"fullName":"Dashboard-CSV Data Integrity CSV data quality summary should report all empty/header-only CSV files in cia-data","status":"passed","title":"should report all empty/header-only CSV files in cia-data","duration":159.87970300000006,"failureMessages":[],"location":{"line":488,"column":5},"meta":{},"tags":[]}],"startTime":1787953676247,"endTime":1787953678224.8796,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-csv-integrity.test.js"},{"assertionResults":[{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant file exists","status":"passed","title":"file exists","duration":5.584515999999894,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.9091519999999491,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":0.7889569999999821,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.6176759999998467,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.7056410000000142,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.4060320000000956,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.9796739999999318,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.079042999999956,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.6419619999999213,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.7015939999998864,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.1348449999998138,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.6837800000000698,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.1827740000001086,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant file exists","status":"passed","title":"file exists","duration":0.7175640000000385,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5526449999999841,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":0.5456309999999576,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5343809999999394,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.4841670000000704,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.9062870000000203,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6310419999999795,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.860251000000062,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.48505699999986973,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.4790469999998095,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.0148099999998976,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.5541279999999915,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.7488319999999931,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant file exists","status":"passed","title":"file exists","duration":0.687246999999843,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5627130000000307,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":0.6950810000000729,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5455919999999423,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.4652009999999791,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.6646040000000539,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6292080000000624,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.6525019999999131,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.4649410000001808,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.39566100000001825,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.8879930000000513,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.4352850000000217,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.6662069999999858,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant file exists","status":"passed","title":"file exists","duration":0.6233670000001439,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.6256809999999859,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":0.6081380000000536,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.46696399999996174,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.44561399999997775,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.7585400000000391,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.9077990000000682,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.6585930000001099,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.55217400000015,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.6992099999999937,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.7199980000000323,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.5457709999998315,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.7029569999999694,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant file exists","status":"passed","title":"file exists","duration":0.6372730000000502,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5901449999998931,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":0.6571199999998498,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5612409999998818,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.6168949999998858,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.8702800000000934,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6667180000001736,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.8095550000000458,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.6625500000000102,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.6478730000001178,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.9098730000000614,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.733743000000004,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.8449120000000221,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant file exists","status":"passed","title":"file exists","duration":0.8757689999999911,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.8308959999999388,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":0.907369000000017,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.9241709999998875,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.7831869999999981,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.0355289999999968,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.958515000000034,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.3211929999999938,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":5.197721999999885,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.2743169999998827,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.2525559999999132,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.0166739999999663,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.5608620000000428,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant file exists","status":"passed","title":"file exists","duration":1.6466319999999541,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.4956199999999171,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":1.577203000000054,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.4079659999999876,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.5975510000000668,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.5343330000000606,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.6445690000000468,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.9007790000000568,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.6141419999999016,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.5167089999999916,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.0299609999999575,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.6659590000001572,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.8588709999999082,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant file exists","status":"passed","title":"file exists","duration":1.863788999999997,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.709831000000122,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":1.7675460000000385,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.9644069999999374,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.0703370000001087,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.2393070000000534,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.5188730000002124,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.7247889999998733,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.3906939999999395,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.4630389999999807,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.2190550000000258,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.965951000000132,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.4072570000000724,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant file exists","status":"passed","title":"file exists","duration":1.6230490000000373,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.411051999999927,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":1.5268490000000838,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.48824599999989,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.5532080000000406,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.7222649999998794,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.5111090000000331,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.9246239999999943,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.6657290000000557,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.5424579999998969,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.8620060000000649,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.60564700000009,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.8438120000000708,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant file exists","status":"passed","title":"file exists","duration":1.9791760000000522,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.0815979999999854,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":2.0231280000000424,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":1.8660239999999249,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.6718610000000353,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.987280999999939,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.8535099999999147,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.0066770000000815,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.892042000000174,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.9059790000001158,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.250874000000067,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.8891370000001189,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.0288980000000265,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant file exists","status":"passed","title":"file exists","duration":2.1370210000000043,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.587795000000142,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":2.219184000000041,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":3.711319000000003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.1509970000001886,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.3849250000000666,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.9832949999999983,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.3095240000000103,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.0584250000001703,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.065746999999874,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.2354659999998603,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.0185089999999946,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.237468999999919,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant file exists","status":"passed","title":"file exists","duration":4.1929499999998825,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.198059999999941,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":3.9671270000001186,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.7713750000000346,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.467139999999972,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.5235650000001897,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.1899000000000797,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.63394100000005,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.2285430000001725,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.1739500000001044,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.383192000000008,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.223273000000063,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.330112000000099,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant file exists","status":"passed","title":"file exists","duration":2.3968979999999647,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.293354000000136,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":2.3720210000001316,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.2835359999999127,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.305717000000186,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.481375000000071,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.42470000000003,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.5469080000000304,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.4545960000000377,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.4119160000000193,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.64716599999997,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.518555000000106,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.619004000000132,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant file exists","status":"passed","title":"file exists","duration":2.5988559999998415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.5828859999999167,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":2.6590989999999692,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.646695000000136,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.555114000000003,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.7440469999999095,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.5567369999998846,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.7050140000001193,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.6971300000000156,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.627420000000029,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.811914999999999,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.688574000000017,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.0383690000001025,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant file exists","status":"passed","title":"file exists","duration":6.1697619999999915,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.856062000000065,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":3.6150780000000395,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.735612000000174,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.748886999999968,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.9856700000000274,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.831863000000112,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.9384419999998954,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":2.820271000000048,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.8572589999998854,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.1161349999999857,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.9369890000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.309989999999971,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant file exists","status":"passed","title":"file exists","duration":3.1643349999999373,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.988534999999956,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":2.9808909999999287,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.0126910000001317,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.9784060000001773,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":3.1913549999999304,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.172840999999835,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.188178999999991,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.104863999999907,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.1057250000001204,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.7255250000000615,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.519068999999945,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.2502759999999853,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant file exists","status":"passed","title":"file exists","duration":3.3371279999998933,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.1732419999998456,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":3.1599160000000666,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.1750540000000456,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.067395000000033,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.231818000000203,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.189476999999897,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.3880730000000767,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.9997880000000805,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.100807000000032,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.5343869999999242,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.3607220000001234,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.494331999999986,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant file exists","status":"passed","title":"file exists","duration":3.495445000000018,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.422888000000057,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":3.4940220000000863,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.43507099999988,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.405715999999984,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":3.689728000000059,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.5069260000000213,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.639944999999898,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.4942819999998846,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.509409999999889,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.802169000000049,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.544685999999956,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.661254999999983,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant file exists","status":"passed","title":"file exists","duration":3.693504999999959,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.598207000000002,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":4.7521979999999076,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.8033009999999194,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.9236960000000636,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.8920640000001185,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.961188999999877,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.8758960000000116,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.808631000000105,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.7929810000000543,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.004989000000023,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.7857380000000376,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.9308599999999387,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant file exists","status":"passed","title":"file exists","duration":3.9425920000001042,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.8409010000000308,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":3.875827000000072,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.01876500000003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.8963350000001356,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.057117000000062,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.86855300000002,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.056415000000015,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.04624600000011,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.925028999999995,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.200033000000076,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.9785890000000563,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.1703379999999015,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant file exists","status":"passed","title":"file exists","duration":4.179826000000048,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.06552099999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":4.031789000000117,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.117451000000074,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.298344999999927,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.310009000000036,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.186909000000014,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.283400000000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.242512999999917,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.379991000000018,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.361054999999851,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.179084999999986,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.331549999999879,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant file exists","status":"passed","title":"file exists","duration":5.54738599999996,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.296573999999964,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":4.28372000000013,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.2866760000001705,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.339384999999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.5735930000000735,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.382344999999987,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.575818000000027,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.416268999999829,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.400059000000056,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.632652999999891,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.500144999999975,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.813043999999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant file exists","status":"passed","title":"file exists","duration":7.376330000000053,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.560087999999951,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":4.665906000000177,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.531684000000041,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.566641000000118,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.773867999999993,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.583251000000018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.723543999999947,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.761403999999857,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.9264630000000125,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.92081300000018,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.731839000000036,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.821537000000035,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant file exists","status":"passed","title":"file exists","duration":4.843478000000005,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.891939000000093,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":5.147407999999814,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":4.968372000000045,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.907306999999946,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.018526000000065,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.116172000000006,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.321099999999888,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.867684000000054,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.7816519999998945,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.00396899999987,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.837327000000187,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.985443999999916,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant file exists","status":"passed","title":"file exists","duration":5.2359939999998915,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.945770000000039,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":4.93500999999992,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":5.010060999999951,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.036128999999846,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.2056760000000395,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.014828999999963,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.120216999999911,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.017112999999881,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.041789999999992,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.2047039999999924,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.061476999999968,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.215515000000096,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant file exists","status":"passed","title":"file exists","duration":5.853388999999879,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.1246849999999995,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":5.384180999999899,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.404479999999921,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.172614999999951,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.3258710000000065,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.17506000000003,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.281388000000106,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.188503999999966,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.175761000000193,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.362843000000112,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.316193999999996,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.376856000000089,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant file exists","status":"passed","title":"file exists","duration":5.400400999999874,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.345829000000094,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":5.308369000000312,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.395572999999786,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.343283999999585,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.628038000000288,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.940813000000162,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.598461999999927,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.42890400000033,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.455815000000257,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.611816999999974,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.435055999999804,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.6029209999996965,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant file exists","status":"passed","title":"file exists","duration":5.601848999999675,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.5297129999999015,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":5.551343999999972,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.494436999999834,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.545774000000165,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.811600999999882,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.59413399999994,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.762399000000187,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.70493099999976,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.622036000000207,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.950130999999601,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.703671000000213,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.782208000000082,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant file exists","status":"passed","title":"file exists","duration":6.069183000000066,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.753322000000026,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":5.766135999999733,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.756929000000127,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.801832999999988,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.007317999999941,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.831869000000097,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.9373860000000604,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.1128749999998035,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.818903999999748,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.6895470000004025,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.475178000000142,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.015968000000157,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant file exists","status":"passed","title":"file exists","duration":8.014966999999615,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.315517,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":6.617189000000053,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.482057000000168,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.088940000000093,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.188216000000011,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.122323000000051,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":6.219554000000244,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.068751999999677,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.117804999999862,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.506300999999894,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.234643000000233,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.292723999999907,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant file exists","status":"passed","title":"file exists","duration":6.420832000000246,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.218263000000206,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":6.512232999999924,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.454056000000037,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.929583999999977,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.694282999999814,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.334299999999985,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":6.489149999999881,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.395935000000009,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.557436999999936,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.081970000000183,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.924854999999752,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.645172000000002,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant file exists","status":"passed","title":"file exists","duration":6.954040000000077,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.468951999999717,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":6.574528999999984,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.995701000000281,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.322961000000305,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.737246000000141,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.9294959999997445,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.5501359999998385,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.810060000000249,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.878810000000158,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.441835999999967,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.296360999999706,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.814728999999716,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant file exists","status":"passed","title":"file exists","duration":6.751119999999901,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.612169999999878,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":6.566824999999881,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.561114000000089,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.795473000000129,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.714310999999725,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.82598999999982,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":9.266830000000027,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.661321999999927,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.620796000000155,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.808358000000226,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.7354999999997744,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.10097500000029,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant file exists","status":"passed","title":"file exists","duration":7.2188960000003135,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.933620999999675,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":6.8925649999996494,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.840748000000076,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.842711000000236,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.017607999999655,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.9079139999998915,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.03727600000002,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.75532499999963,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.3144470000002,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.337568000000374,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.110803999999916,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.17682700000023,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant file exists","status":"passed","title":"file exists","duration":7.18872999999985,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.0747660000001815,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":7.069275999999718,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.969309000000067,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.0407319999999345,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.2100089999999,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.130350000000362,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.482809999999972,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":7.1417710000000625,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.585727000000134,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.630299000000377,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.28823599999987,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.31832200000008,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant file exists","status":"passed","title":"file exists","duration":7.449497000000065,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.7948340000002645,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":7.250845000000027,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":8.503551000000243,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.993026999999984,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.609336999999869,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.295950000000175,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.521671999999853,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":7.35062199999993,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.289262000000235,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":9.811940999999933,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.597013999999945,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.61452700000018,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant file exists","status":"passed","title":"file exists","duration":7.563602000000174,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.739510000000337,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":7.806826999999885,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.636897999999746,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.577898000000005,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.91789400000016,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.57314899999983,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.75420800000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.52710500000012,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.761406000000079,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":9.224872000000232,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.132416999999805,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":9.08001000000013,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant file exists","status":"passed","title":"file exists","duration":8.186227000000144,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.196695999999974,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":7.979580000000169,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":7.777141000000029,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.9477609999999,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.30284599999959,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":8.629566999999952,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.595233000000007,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.636920999999802,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.220330000000104,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.491157000000385,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.192348000000038,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.267648999999892,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant file exists","status":"passed","title":"file exists","duration":8.872410999999829,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.67631399999982,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":8.70577000000003,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":9.106009000000086,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.848035999999865,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.963541999999961,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.980275999999776,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.126980999999887,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.45061399999986,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.017382999999882,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.71481700000004,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.079748000000109,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.152283000000352,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant file exists","status":"passed","title":"file exists","duration":8.153706000000057,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.009846999999809,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":8.085528000000068,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":8.143716999999924,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.704538000000412,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.50760900000023,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.709711999999854,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.48483699999997,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.310910000000149,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.517125999999735,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.506937000000107,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.615741000000071,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.456023000000187,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant file exists","status":"passed","title":"file exists","duration":9.655097000000296,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.116979999999785,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":9.945020000000113,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":9.270878000000266,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.421530000000075,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.73567200000025,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.279195999999956,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.047982999999931,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.182532000000265,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.912676999999803,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.974742999999762,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.649073999999928,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":9.640359999999873,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant file exists","status":"passed","title":"file exists","duration":10.07575399999996,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.112313000000086,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":10.899286999999731,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.153961999999865,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.657862000000023,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.735406999999668,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.323941999999988,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.919423999999708,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":11.380667999999787,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.833494999999857,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.89388800000006,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.335683999999674,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.514713999999913,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant file exists","status":"passed","title":"file exists","duration":11.682032000000163,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.34841200000028,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":12.61193299999968,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.338290000000143,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.490268000000015,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.066815000000133,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.645178000000215,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.710493999999926,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.395900999999867,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.3042989999999,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.808103000000301,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.02184299999999,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.599981000000298,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant file exists","status":"passed","title":"file exists","duration":13.874397000000044,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.191873000000214,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":13.425686999999925,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":14.075313000000278,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.16235400000005,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.681641000000127,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.041519999999764,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":9.934389999999894,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":9.8189339999999,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.393327000000227,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.132254999999986,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.547218999999586,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.427994000000126,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant file exists","status":"passed","title":"file exists","duration":9.745134999999664,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.36461300000019,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":9.787505000000237,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.385377000000062,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.599211999999625,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.685743999999886,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.154982000000018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.446986999999808,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.956941999999799,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.257564000000002,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.21516500000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.869458000000122,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.229580000000169,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant file exists","status":"passed","title":"file exists","duration":12.700448999999935,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.703392000000349,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":12.926271999999699,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.718848999999864,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.789588000000549,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.96118000000024,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.778832999999395,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.434000000000196,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.340583000000152,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.78341999999975,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.080485000000408,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.400870000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.243209999999635,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant file exists","status":"passed","title":"file exists","duration":10.196030000000064,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.95848500000011,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":10.095711999999367,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.187083000000712,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.908722999999554,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.821136999999908,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.714759000000413,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.413027000000511,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.99810400000024,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.062299000000166,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":10.614392999999836,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.708340999999564,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.543711000000258,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant file exists","status":"passed","title":"file exists","duration":10.27955699999984,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.195408000000498,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":11.15870300000006,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.233764999999948,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.851740000000063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.90712799999983,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.157635999999911,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.678162000000157,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":12.704506999999467,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.746032000000014,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.183288999999604,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":10.627747999999883,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.10738399999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant file exists","status":"passed","title":"file exists","duration":11.969350000000304,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.552539000000252,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":10.191541000000143,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.245662000000266,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":10.313610000000153,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":10.271882000000005,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.98178900000039,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.116862000000765,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":10.06840100000045,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.301548000000366,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.438458000000537,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.005678000000444,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.176249999999527,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant file exists","status":"passed","title":"file exists","duration":14.133712999999261,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.59212000000025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":14.234581000000617,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":14.662030999999843,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":16.16233100000045,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.70425300000079,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.73728200000005,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.793157000000065,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":14.733675999999832,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.7003509999995,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.171969999999419,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.542271000000255,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.977466999999706,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant file exists","status":"passed","title":"file exists","duration":11.372472999999445,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.723006000000169,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":11.457070999999814,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.14218399999936,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.000696000000062,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":12.434911999999713,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.342059000000518,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":11.003061000000343,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.098904999999831,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.933013999999275,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.5802020000001,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.167569000000185,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.18873799999983,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant file exists","status":"passed","title":"file exists","duration":11.212251999999353,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.304234000000179,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":12.396338999999898,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":11.773823999999877,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.85393600000043,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.715564999999515,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.87887099999989,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.209350000000086,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":12.462743000000046,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.72315400000025,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.840634999999565,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.433431000000382,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.508826000000226,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant file exists","status":"passed","title":"file exists","duration":16.85868400000072,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.016042000000198,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":12.76089199999933,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":14.070784000000458,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.888224999999693,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":12.387773999999808,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.547249000000193,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.642039000000295,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.048625999999786,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.224906000000374,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.536420000000362,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.516665000000103,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.695356999999603,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant file exists","status":"passed","title":"file exists","duration":11.426413999999568,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.061091999999917,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":14.529082000000017,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.920427999999447,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.19948899999963,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.578968999999233,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.454838999999993,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.773568000000523,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":16.707781000000068,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.69528799999989,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.050365000000056,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.38029000000006,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":16.248281000000134,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant file exists","status":"passed","title":"file exists","duration":14.140636000000086,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.812442999999803,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":16.101427000000513,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.418100999999297,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":18.431219000000056,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.524145999999746,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.474395999999615,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.14625100000012,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.788601999999628,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.818657999999232,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.379417999999532,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.648791999999958,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.27749700000004,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant file exists","status":"passed","title":"file exists","duration":13.262171000000308,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.872701000000234,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":12.361304000000018,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.537390999999843,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.660805000000437,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.391773000000285,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.24231299999974,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.156882999999652,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.94116699999995,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.874284000000443,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.811627000000044,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.126152999999249,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.018541999999798,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant file exists","status":"passed","title":"file exists","duration":12.607445000000553,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.774501999999302,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":13.484857999999804,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.693445999999312,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.656928000000335,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.89611799999966,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.509756999999809,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.341765000000123,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.61265899999944,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.654386999999588,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":16.26451199999974,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":16.426744999999755,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":14.548408999999992,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant file exists","status":"passed","title":"file exists","duration":13.668580999999904,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.9113440000001,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":14.09519999999975,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.454642000000604,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.67912999999953,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.24789299999975,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.910737000000154,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.887521000000561,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":12.735133999999562,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.770950000000084,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.946367000000464,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.186902000000373,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.664040999999997,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant file exists","status":"passed","title":"file exists","duration":12.55505599999924,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.24750099999983,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":12.121463999999833,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":13.380872999999156,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.18670099999963,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.444424999999683,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.801339999999982,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.164840999999797,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.307705000000169,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.66010599999936,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.718680000000859,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.347671000000446,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.06613500000003,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant file exists","status":"passed","title":"file exists","duration":16.58659499999976,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.424696999999469,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":15.103106999999909,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.760737999999947,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.048123999999916,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.4811380000001,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.98764300000039,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.007215000000542,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.22141399999964,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.817508000000089,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.39966800000002,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.719716999999946,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.594548000000032,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant file exists","status":"passed","title":"file exists","duration":15.36001800000031,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":17.55666100000053,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":17.043009999999413,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.380263000000014,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.314447000000655,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.499544000000242,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.286826000000474,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":16.552942000000257,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":16.5274330000002,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.54388999999992,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.899706000000151,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.32449699999961,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.412443000000167,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant file exists","status":"passed","title":"file exists","duration":14.577061999999387,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.440844999999172,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":13.442508000000089,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.047787999999855,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.82860299999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.05269799999951,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.400614000000132,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.899633999999423,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.02502800000002,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.152554999999666,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.94931700000052,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.67161699999997,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":14.105219000000034,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant file exists","status":"passed","title":"file exists","duration":17.323975999999675,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.40972099999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":14.341310999999223,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.956605000000309,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.718998000000283,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.75144900000032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.60725100000036,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.312799999999697,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":16.69140100000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.976229000000785,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.858420999999908,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.548045000000457,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":17.179565999999795,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant file exists","status":"passed","title":"file exists","duration":22.77232600000025,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.684590000000753,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":22.196859000000586,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.58010700000068,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":16.32166799999959,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.71050699999978,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.348305999999866,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":17.165608999999677,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":21.453377000000728,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.33126799999991,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.897957000000133,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.023019000000204,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.270641000000069,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant file exists","status":"passed","title":"file exists","duration":18.129633999999896,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.701399000000492,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":20.32504499999959,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":21.264814000000115,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":19.128454000000602,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.452164999999695,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.958706999999777,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.980016999999862,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":19.483518000000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.76143200000024,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.76734900000065,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":16.825260999999955,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.464390999999523,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant file exists","status":"passed","title":"file exists","duration":14.808125000000473,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.466447999999218,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":14.208211999999548,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":13.889114000000518,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.629979000000276,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.267243999999664,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.32978699999967,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.336323999999877,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.778900000000249,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.404763999999886,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.21525500000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.751698000000033,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.647461999999905,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant file exists","status":"passed","title":"file exists","duration":16.58210599999984,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.98401399999966,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":20.291040999999495,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":15.985139000000345,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.543679999999767,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.141647000000376,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.749371999999312,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.201830000000882,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.788935999999921,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":15.505850999999893,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.122512000000825,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.692027000000053,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.97417299999961,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant file exists","status":"passed","title":"file exists","duration":14.053191999999399,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.935410999999476,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":13.649506000000656,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":13.871851999999308,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.103729000000385,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.735219000000143,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.113524999998845,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.61449200000061,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.439865999998801,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":17.84141500000078,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.761916999999812,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.478046000000177,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":20.09809899999891,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant file exists","status":"passed","title":"file exists","duration":18.572532999998657,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.355219999999463,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":15.115780999998606,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.904372000000876,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.168440999999802,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":22.29414100000031,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.94550799999888,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":22.200474999999642,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":22.115676999999778,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.836090999999215,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.839152000000468,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":21.783955999999307,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.59777000000031,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant file exists","status":"passed","title":"file exists","duration":23.77030399999967,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.434729000000516,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":18.10149099999944,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.158035000000382,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.729570000001331,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.273616000000402,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":18.927057000000787,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.57621400000062,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":23.02700299999924,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.071586000000025,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.22853600000053,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.447925000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.924122000000352,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant file exists","status":"passed","title":"file exists","duration":17.00834500000019,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.950002999999924,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":15.834146000001056,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.217842000000019,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.379585000000588,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":18.3765970000004,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.080109000000448,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.224435999998605,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.444064000001163,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":22.00010999999904,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":23.914795999999114,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.83068699999967,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":19.65678300000036,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant file exists","status":"passed","title":"file exists","duration":18.235421999999744,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":17.832236999998713,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":21.01561700000093,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.55096500000036,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.017594999999346,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.668163000000277,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.885991999999533,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.020680999999968,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":21.249635000000126,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.96613399999842,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.355406000000585,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.011011999999027,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.22243900000103,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant file exists","status":"passed","title":"file exists","duration":21.14426800000001,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.37198200000057,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":23.85446299999967,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":21.163753999999244,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.256097999999838,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.241769000000204,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":16.769937999999456,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":17.42348200000015,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":16.48862100000042,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":18.864921000000322,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.644044999999096,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.725619000000734,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.206826999999976,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant file exists","status":"passed","title":"file exists","duration":24.407076999999845,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":24.667765000000145,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":25.15258300000096,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.687527999998565,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":19.057259999999587,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.532664000000295,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.348641999999018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.07331299999896,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":16.955464999999094,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.230427999998938,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.05750799999987,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.699268000000302,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":21.84271600000102,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant file exists","status":"passed","title":"file exists","duration":19.29412400000001,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.972858999999517,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":26.63589900000079,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":31.066375000000335,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.645770000000994,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.1991450000005,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.64671499999895,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":25.68474900000001,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":26.44200699999965,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.601634999999078,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.24454499999956,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.428466999999728,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.742737999999008,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant file exists","status":"passed","title":"file exists","duration":23.819375999999465,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.624377999998615,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":21.323131999999532,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.235381000000416,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.8972700000013,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":24.63527400000021,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.07497400000102,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.768659999999727,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":23.828961999999592,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.334987999998702,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.96236499999941,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.757102999999915,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.778073999999833,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant file exists","status":"passed","title":"file exists","duration":23.88058899999851,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":24.37721000000056,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":24.711155000000872,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.702022999999826,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.66153900000063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.1053780000002,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.89282699999967,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.049589000000196,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":20.087657000000036,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.024319999998625,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.750631000000794,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.150299999999334,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":21.974600000001374,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant file exists","status":"passed","title":"file exists","duration":21.481837999999698,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":19.13102500000059,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":18.475377000000663,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.727429999999003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.504076999999597,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.789520999998786,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.794754000000466,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.275981999999203,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.792113999999856,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.16852800000015,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":19.983060999998997,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.774242000001323,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.527946000000156,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant file exists","status":"passed","title":"file exists","duration":21.968278000000282,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.373193999999785,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":21.112366000001202,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":20.834585000000516,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":18.866700000000492,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.73212599999897,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":18.62636999999995,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":18.609087999999247,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.136375000000044,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.710119999999733,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.367640999998912,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.37229500000103,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.111125999999786,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant file exists","status":"passed","title":"file exists","duration":23.115146000000095,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.841001000000688,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":25.618693999998868,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":26.44474099999934,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.388074999998935,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.318978000001152,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":22.925771000000168,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":22.55961599999864,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":21.921400999999605,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.88905700000032,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.19219499999963,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.037437999999383,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.76250599999912,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant file exists","status":"passed","title":"file exists","duration":23.785079999999653,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.860097999999198,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":24.520237000000634,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":22.794025000001056,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.567094999998517,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.087714999999662,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":20.634030000001076,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.04418799999985,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":22.131024000000252,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.612286999999924,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.46215900000061,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.417123999999603,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.045170999999755,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant file exists","status":"passed","title":"file exists","duration":21.66256599999906,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.657326999998986,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":22.32643900000039,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":19.510755999999674,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.0992040000001,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.390581000001475,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.439727000000858,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.797223999999915,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":25.521342000000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.699812999999267,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.616151000000173,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.97858400000041,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.709476999998515,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant file exists","status":"passed","title":"file exists","duration":20.320002000000386,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.81548500000099,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":25.312651000000187,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.71130500000072,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.87140400000135,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.53309900000022,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.749714999999924,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.11882499999956,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":18.485286000000997,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.020699000000604,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.70262300000104,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":19.3493440000002,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":19.09718200000134,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant file exists","status":"passed","title":"file exists","duration":19.590745999999854,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":19.25097999999889,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":22.32946499999889,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.281166999999186,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":21.682973999999376,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.792797000000064,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.648333999999522,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.653057999999874,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":24.17417899999964,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":25.37051900000006,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":23.036228999999366,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.728551999998672,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.394836999999825,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant file exists","status":"passed","title":"file exists","duration":21.653630000000703,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.856481000000713,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":18.782812999999805,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.125201999999263,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.64955100000043,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.142006000000038,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.96201099999962,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":18.086018999998487,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":17.782439999999042,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":18.012179999999717,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.337799999999334,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":21.4316230000004,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.48256399999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant file exists","status":"passed","title":"file exists","duration":24.226587000001018,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.21958199999972,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":24.468980999999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.58727799999906,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.22615399999995,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":22.682404999999562,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":25.59581100000105,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.533503000000564,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":24.136868999999933,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.984459000001152,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.221089000000575,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.100289000001794,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.163375000000087,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant file exists","status":"passed","title":"file exists","duration":30.677958000000217,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.489653000000544,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":29.860758000000715,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.298375000000306,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.784082000000126,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.832965999999942,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.29860000000008,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.651098000000275,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.312431999998807,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":28.977615000001606,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":30.652351000000635,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.637402999998812,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.259626999999455,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant file exists","status":"passed","title":"file exists","duration":30.77987899999971,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.8082200000008,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":29.15642900000057,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":30.910804999999527,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.14925100000073,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.69467600000098,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.563195000000633,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.266148000000612,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":19.82245999999941,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.22679000000062,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.370412000000215,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":25.829728999999134,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.601543000000675,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant file exists","status":"passed","title":"file exists","duration":29.670452000000296,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":30.15764399999898,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":29.973479000000225,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":31.489767999999458,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.194644000001063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":30.70970800000032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.788040999999794,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.337725999999748,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.85200199999963,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.126612999998542,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.6950680000009,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.097405999998955,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":28.277352999999493,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant file exists","status":"passed","title":"file exists","duration":28.08184699999947,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":30.50080700000035,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":27.407795000000988,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.621236999999383,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.86908399999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.0245730000006,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.85715899999923,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.204302000000098,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.804261999999653,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.94497600000068,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.001498000001448,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.65607000000091,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.87439599999925,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant file exists","status":"passed","title":"file exists","duration":31.152917999999772,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":31.05563600000096,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":28.438485000000583,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.174714999999196,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.71763699999974,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.64926899999955,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.927772999999434,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.983275000000503,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":28.66393699999935,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.85468899999978,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":27.81557900000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.778419000000213,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.832099000001108,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant file exists","status":"passed","title":"file exists","duration":25.30192100000022,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.22793300000012,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":25.520220000000336,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":27.53215700000146,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.39429199999904,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.513788000000204,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.54967300000135,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.004057000000103,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":28.2606420000011,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.32517999999982,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.66475100000025,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.312332999999853,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.867960999999923,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant file exists","status":"passed","title":"file exists","duration":24.744737999999415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.22333400000025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":28.362081999999646,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.0795049999997,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.07835999999952,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.07912100000067,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":30.48454700000002,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.898702000000412,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":31.5785649999998,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.835440999999264,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":31.83575700000074,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.699162999999317,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":28.38486499999999,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant file exists","status":"passed","title":"file exists","duration":31.091832999998587,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":31.491141000000425,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":31.014259000001402,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":32.80594300000121,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.740475999999035,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.95526500000051,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.773794999999154,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.31388700000025,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.0002970000005,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.932584999998653,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":26.982357999999294,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.90686199999982,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.969531999999163,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant file exists","status":"passed","title":"file exists","duration":28.655329999999594,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":28.01361999999972,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":29.609268000001975,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":27.969005000002653,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.352671000000555,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.974269999998796,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.447007999999187,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":33.6128839999983,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":32.33504100000209,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.50252499999988,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":33.882730000001175,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":31.51414400000067,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":30.211834999998246,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant file exists","status":"passed","title":"file exists","duration":30.155320000001666,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.60289499999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":30.13869799999884,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.206460999997944,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.27385900000081,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.391155999997864,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.20708800000284,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.495359000000462,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.15384400000039,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":30.974614000002475,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":28.575982000002114,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.087664999999106,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":24.598674000000756,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant file exists","status":"passed","title":"file exists","duration":23.015118999999686,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.286974999999074,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":24.13921400000254,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.34796500000084,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.93742199999906,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.384674000000814,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":33.125952000002144,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":34.980673999998544,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":32.83335299999817,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.26253500000166,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":32.23569399999906,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":32.401255000000674,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.186413000003085,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant file exists","status":"passed","title":"file exists","duration":32.251554000002216,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.897367999998096,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":32.311516999998275,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.914569000000483,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.79128600000331,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":32.59716199999821,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":30.857474000000366,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.373632999999245,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.20178400000077,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":31.283151999999973,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.301139999999577,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.585109999999986,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.06315899999754,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant file exists","status":"passed","title":"file exists","duration":31.667310999997426,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.232631999999285,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":26.402704000000085,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.30297999999675,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.63484299999982,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.042051000000356,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.138043000002654,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.451780999999755,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":28.902874999999767,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.07271799999944,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.831762000001618,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.06103400000211,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.85377100000187,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant file exists","status":"passed","title":"file exists","duration":21.69913699999961,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.59844299999895,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":23.533971999997448,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.599247000001924,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.10442999999941,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.87302699999782,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":23.201379999998608,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.358790999998746,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":24.805905000001076,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":24.927008000002388,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.800493999999162,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.162029999999504,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.59521400000085,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant file exists","status":"passed","title":"file exists","duration":28.20506600000226,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.145760000003065,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":26.163002999997843,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.029962000000523,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":21.36652000000322,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.159772999999404,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.120771000001696,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.961522999998124,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.38409699999829,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.274833999999828,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":26.58530299999984,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.320788000000903,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.833385000001726,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant file exists","status":"passed","title":"file exists","duration":26.347297999996954,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.733908000001975,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":23.19250000000102,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.27670500000022,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.558666000000812,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.995555999998032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.969074000000546,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.674580000002607,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.005026000002545,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":25.725163000002794,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.46939100000236,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.82893100000001,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.442802999998094,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant file exists","status":"passed","title":"file exists","duration":23.0576570000012,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":28.178735999998025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":26.17557499999748,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.431350000002567,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.063367999999173,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.54788600000029,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":22.33647700000074,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.52921299999798,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":22.73737699999765,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.15361699999994,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.471976000000723,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.488655999997718,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.09998600000108,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant file exists","status":"passed","title":"file exists","duration":27.114754999998695,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.600761000001512,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":23.881399999998393,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.916753000001336,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.800835999998526,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.821246999999858,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.04804199999853,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.57019699999728,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":22.648049999999785,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":30.19599400000152,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.184990999998263,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":29.551547000002756,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.693653999998787,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant file exists","status":"passed","title":"file exists","duration":29.35260500000004,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.593727999999828,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":23.215913,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.610522000002675,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.94511599999896,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":30.47291299999779,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":32.125426999999036,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":32.214083000002574,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":32.998603,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":33.64284899999984,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.65947999999844,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.84191600000122,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.37186799999836,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant file exists","status":"passed","title":"file exists","duration":32.85521299999891,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.56488499999978,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":34.511836000001495,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.623530000000756,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":31.139060000001336,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":31.946302000000287,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":34.69952700000067,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":35.308367999998154,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.14112699999896,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":35.725798999999824,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":35.74772999999914,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":34.67760599999747,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.36355800000092,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant file exists","status":"passed","title":"file exists","duration":35.28646600000138,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.463746000001265,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":34.4239910000033,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":36.48958899999707,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":36.290766000001895,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.181204000000434,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":36.15238799999861,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":38.56948399999965,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.07371100000091,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":36.19586899999922,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":35.34209999999803,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":33.9769750000014,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":36.67793200000233,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant file exists","status":"passed","title":"file exists","duration":35.26839199999813,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":33.91229299999759,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":28.551755000000412,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":26.951669000001857,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.217327000002115,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":26.978598999998212,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.036027000001923,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":25.88308799999868,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":28.401213000001007,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.08277699999962,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.628561999998055,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.467211999999563,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.55474099999992,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant file exists","status":"passed","title":"file exists","duration":33.98629200000141,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.655305000000226,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":32.23258799999894,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":29.701138000000356,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.035169999999198,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.714092000001983,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":26.250636000000668,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.21694800000114,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":25.286871000000247,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":31.833961000000272,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.63795700000264,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":32.066256000001886,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.343086000000767,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant file exists","status":"passed","title":"file exists","duration":23.78537000000142,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.226834000000963,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":22.896244999999908,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.360305999998673,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.12557199999719,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.879360999999335,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.25701300000219,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.932535999996617,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.272256000000198,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":24.452128000000812,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.513364999998885,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.873004000000947,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.052443000000494,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant file exists","status":"passed","title":"file exists","duration":26.617813999997452,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.553594000000885,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":25.33089299999847,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.243803000001208,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":25.30808099999922,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":31.871431999999913,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.405769999997574,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":36.7627109999994,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.35850399999981,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.65881900000022,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.92244900000151,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.1373620000013,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.85601999999926,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant file exists","status":"passed","title":"file exists","duration":34.007471000000805,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.21923500000048,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":28.233157999999094,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.45866499999829,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.74276800000007,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.54189000000042,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.51332199999888,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.803341999999247,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.586675000002288,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.461417999998957,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":30.437826000001223,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.558452999997826,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.926705000001675,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant file exists","status":"passed","title":"file exists","duration":31.050735000000714,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":36.21411300000182,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":34.73187799999869,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.71556199999759,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.258370999999897,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.94478700000036,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.26231099999859,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":35.83696699999928,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":32.394311000000016,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.59494900000209,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":27.111558000000514,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.16909399999713,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.885401999999885,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant file exists","status":"passed","title":"file exists","duration":32.57216300000073,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":35.22531199999867,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":33.84766200000013,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":34.176588000002084,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":33.76680099999794,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":34.24343299999964,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":34.1948029999985,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":34.338732000000164,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":35.64254299999811,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":35.73995500000092,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.70947100000194,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":35.68456200000219,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":33.192825999998604,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant file exists","status":"passed","title":"file exists","duration":28.807784000000538,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":27.049191999998584,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":37.19658299999719,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.66302399999768,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.15855400000146,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.67258799999763,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.636662000000797,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.28735500000039,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":24.94520199999897,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.706186999999773,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.5746309999995,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.19416099999944,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.782028999998147,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant file exists","status":"passed","title":"file exists","duration":35.07065199999852,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.718550000001414,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":28.510677999998734,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.62546300000031,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.350969000002806,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.491629999996803,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":26.679329000002326,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.20333000000028,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":34.08043800000087,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.16809999999896,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.528229999999894,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.8813659999978,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":37.15841100000034,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant file exists","status":"passed","title":"file exists","duration":35.59036500000002,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":35.15731500000038,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":35.86492999999973,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":38.90957100000014,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":36.909035000000586,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":34.61151199999949,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.96874400000161,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":37.73060400000031,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":38.88115800000014,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":34.620028000001184,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":34.80999399999928,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":33.837422000000515,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.83907900000122,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant file exists","status":"passed","title":"file exists","duration":36.30697700000019,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.22632899999735,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":39.46110399999816,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.19932600000175,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":40.21902300000147,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":40.287200999999186,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.291958999998315,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.42826200000127,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":40.407146000001376,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":39.257313000001886,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.3487030000033,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":36.92474500000026,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.3611639999981,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant file exists","status":"passed","title":"file exists","duration":38.931752000000415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.863993999999366,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":39.17858400000114,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":39.309940999999526,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":39.513842000000295,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.19108299999789,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":38.2490439999965,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.442581999999675,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":40.91854299999977,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":39.21450200000254,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.00071200000093,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":42.09865300000092,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":39.582390999999916,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant file exists","status":"passed","title":"file exists","duration":37.903667000002315,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":38.14215500000137,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":37.50786599999992,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":39.176329999998416,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.50460999999996,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.70333599999867,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":38.396701000001485,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":38.376774000000296,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.97441500000059,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":40.598793999997724,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":41.69933499999752,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.03827799999999,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.44641400000182,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant file exists","status":"passed","title":"file exists","duration":37.34993100000065,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.55328200000076,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":38.35385099999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.192424000000756,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":39.88823400000183,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.62198300000091,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.726911999998265,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.837007999998605,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.3794510000007,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":40.34332599999834,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":40.70317000000068,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.607593000000634,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":39.94722399999955,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant file exists","status":"passed","title":"file exists","duration":39.62284699999873,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":40.261553000000276,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":39.58227099999931,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":38.17081800000233,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":38.8506610000004,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.8236109999998,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.79409900000246,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.93487399999867,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.68178199999966,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.31533599999966,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":40.92005599999902,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":45.430091000001994,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":41.67759400000068,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant file exists","status":"passed","title":"file exists","duration":40.81945800000176,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":41.907444000000396,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":41.12942699999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":41.61155000000144,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":42.46117099999901,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":39.48436799999763,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.356267000002845,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":41.20413800000097,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.855256999999256,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.028408000001946,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.06724399999803,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.27869799999826,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.85705299999972,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant file exists","status":"passed","title":"file exists","duration":39.12415299999702,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":38.90594500000225,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":39.027783000001364,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.28879400000005,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.593988000000536,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":39.48972800000047,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":42.02592600000207,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":41.47525499999756,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.93439999999828,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.072251000001415,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.50045500000124,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.58405900000071,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":42.6921540000003,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant file exists","status":"passed","title":"file exists","duration":42.344772999997076,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":41.078512000000046,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":40.01478099999804,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.57884700000068,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":40.88863700000002,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":40.65399800000159,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.349277000001166,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.69592399999965,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":38.43048400000043,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.84983700000157,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.57550199999969,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":35.90609899999981,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":37.16865200000029,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant file exists","status":"passed","title":"file exists","duration":38.72958500000095,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":40.22601600000053,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":40.1451049999996,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":43.64632100000017,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.10976099999971,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":41.39958300000217,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.825355999997555,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.01024200000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.168321000001015,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.68172200000117,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.96580600000016,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":39.73527699999977,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.672867999997834,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant loads","status":"passed","title":"loads","duration":38.005999000000884,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.15248500000234,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.20295199999964,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant loads","status":"passed","title":"loads","duration":29.469085999997333,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":28.141599999999016,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":28.89123400000244,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant loads","status":"passed","title":"loads","duration":28.738648000002286,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.176220000001194,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.81213399999979,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant loads","status":"passed","title":"loads","duration":35.52868099999978,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":37.96477199999936,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.01607100000183,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant loads","status":"passed","title":"loads","duration":37.31377400000201,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.69793799999752,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.1797719999995,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant loads","status":"passed","title":"loads","duration":42.75095399999918,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.643191999999544,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.50441199999841,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant loads","status":"passed","title":"loads","duration":41.58757600000172,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.76038100000005,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.34803599999941,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant loads","status":"passed","title":"loads","duration":41.91163199999937,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.25704200000109,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.20564200000081,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant loads","status":"passed","title":"loads","duration":43.146074000000226,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.10628899999938,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.585901999998896,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant loads","status":"passed","title":"loads","duration":41.515870999999606,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.346043999998074,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.135965000001306,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant loads","status":"passed","title":"loads","duration":42.637040999998135,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.107395999999426,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.585095999998885,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant loads","status":"passed","title":"loads","duration":36.91607899999872,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.752830000001268,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.19742199999746,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant loads","status":"passed","title":"loads","duration":31.82496700000047,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.111299000000145,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":30.94172299999991,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant loads","status":"passed","title":"loads","duration":33.058937000001606,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.132840999998734,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.9839979999997,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant loads","status":"passed","title":"loads","duration":42.592407000000094,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.64181000000099,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.98556000000099,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant loads","status":"passed","title":"loads","duration":44.805630999999266,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.52076600000146,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.58288199999879,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant loads","status":"passed","title":"loads","duration":43.16681299999982,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.143990000000485,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.42227499999717,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant loads","status":"passed","title":"loads","duration":43.34896300000037,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.90108700000201,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.480077000000165,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant loads","status":"passed","title":"loads","duration":42.669943000000785,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.6553700000004,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.58797599999889,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant loads","status":"passed","title":"loads","duration":43.018144000001485,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.69075899999734,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.356988999999885,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant loads","status":"passed","title":"loads","duration":42.499352999999246,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.890770999998495,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.98894400000063,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant loads","status":"passed","title":"loads","duration":43.87873600000239,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.09128300000157,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.95533699999942,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant loads","status":"passed","title":"loads","duration":42.90805800000089,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.83946699999797,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.38180400000056,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant loads","status":"passed","title":"loads","duration":45.41719599999851,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.98527500000273,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.373820000000705,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant loads","status":"passed","title":"loads","duration":42.370310999998765,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.90196699999797,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.137008999998216,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant loads","status":"passed","title":"loads","duration":43.04434300000139,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.832698999998684,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.798790000000736,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant loads","status":"passed","title":"loads","duration":32.10131399999955,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":33.24271099999896,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":34.5193419999996,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant loads","status":"passed","title":"loads","duration":34.67014400000335,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":32.76556900000287,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.92626599999494,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant loads","status":"passed","title":"loads","duration":32.37823300000309,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.04791000000114,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.29993499999546,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant loads","status":"passed","title":"loads","duration":34.61795600000187,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":31.74275299999863,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":29.295270000002347,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant loads","status":"passed","title":"loads","duration":30.35714900000312,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":38.42891199999576,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.74049699999887,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant loads","status":"passed","title":"loads","duration":43.754924000000756,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.56905299999926,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.71420500000386,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant loads","status":"passed","title":"loads","duration":43.46703399999387,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.934792000000016,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.711130999996385,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant loads","status":"passed","title":"loads","duration":44.46408099999826,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.301494999999704,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.81057999999757,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant loads","status":"passed","title":"loads","duration":39.02729199999885,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.329438000000664,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.32841200000257,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant loads","status":"passed","title":"loads","duration":42.63895400000183,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.144735000001674,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.021498000001884,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant loads","status":"passed","title":"loads","duration":40.638668999999936,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.64620999999897,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.14182900000014,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant loads","status":"passed","title":"loads","duration":39.43774000000121,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":38.6019759999981,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.71010499999829,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant loads","status":"passed","title":"loads","duration":41.931619999995746,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.86777399999846,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.88915800000541,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant loads","status":"passed","title":"loads","duration":46.76908700000058,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.997129999996105,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.81896699999925,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant loads","status":"passed","title":"loads","duration":45.923063000002,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.85077500000625,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.24295700000221,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant loads","status":"passed","title":"loads","duration":44.6615610000008,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.74590199999511,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.5094190000018,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant loads","status":"passed","title":"loads","duration":46.358307999995304,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.65401700000075,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.686915999998746,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant loads","status":"passed","title":"loads","duration":44.60156899999856,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.47553499999776,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.081788000003144,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant loads","status":"passed","title":"loads","duration":46.2101610000027,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.78632500000094,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.11910799999896,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant loads","status":"passed","title":"loads","duration":45.39097799999581,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.62150799999654,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.58176100000128,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant loads","status":"passed","title":"loads","duration":44.99130899999727,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.1037490000017,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.838550000000396,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant loads","status":"passed","title":"loads","duration":44.911159000002954,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.00509199999942,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.29789200000232,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant loads","status":"passed","title":"loads","duration":44.07254799999646,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.150393999996595,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.76995200000238,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant loads","status":"passed","title":"loads","duration":41.26635499999975,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.495145000000775,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.53457899999921,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant loads","status":"passed","title":"loads","duration":44.20716000000539,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.51973600000201,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.329651999993075,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant loads","status":"passed","title":"loads","duration":45.35093199999392,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.6599600000045,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.8408519999939,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant loads","status":"passed","title":"loads","duration":43.102161000002525,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.851817999995546,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.84976599999936,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant loads","status":"passed","title":"loads","duration":47.18422400000418,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.665373000003456,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.33433700000023,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant loads","status":"passed","title":"loads","duration":44.867677000002004,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.335643999998865,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.38435500000196,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant loads","status":"passed","title":"loads","duration":47.57500599999912,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.89207799999713,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.795170999997936,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant loads","status":"passed","title":"loads","duration":44.792265999996744,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.54219999999623,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.88528799999767,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant loads","status":"passed","title":"loads","duration":45.109511000002385,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.14565500000026,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.17255000000296,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant loads","status":"passed","title":"loads","duration":46.81671600000118,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.940386000002036,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.29363900000317,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant loads","status":"passed","title":"loads","duration":44.28928399999859,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.04195299999992,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.306767000001855,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant loads","status":"passed","title":"loads","duration":44.01749500000005,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.68749199999729,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.877250000005006,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant loads","status":"passed","title":"loads","duration":44.11463700000604,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.104050000001735,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.97967699999572,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant loads","status":"passed","title":"loads","duration":45.31915300000401,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.42751799999678,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.850443000003,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant loads","status":"passed","title":"loads","duration":45.506253000006836,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.78300399999716,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.18485299999884,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant loads","status":"passed","title":"loads","duration":45.572156000001996,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.87702900000295,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.24040499999683,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant loads","status":"passed","title":"loads","duration":44.57620099999622,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.101056999999855,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.816595999996935,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant loads","status":"passed","title":"loads","duration":48.559369000002334,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.684346000001824,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.74453899999935,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant loads","status":"passed","title":"loads","duration":45.9989659999992,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.069980000000214,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.17891899999813,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant loads","status":"passed","title":"loads","duration":50.37550999999803,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":52.35714000000007,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":56.6306609999956,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant loads","status":"passed","title":"loads","duration":48.469169999996666,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.33660200000304,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.19181099999696,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant loads","status":"passed","title":"loads","duration":45.374496000004,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.32003399999667,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.21643800000311,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant loads","status":"passed","title":"loads","duration":38.71545699999842,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.53062300000602,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.954501000000164,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant loads","status":"passed","title":"loads","duration":34.948465000001306,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.533809000000474,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":32.144313999997394,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant loads","status":"passed","title":"loads","duration":32.50147299999662,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.75605899999937,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.457493000001705,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant loads","status":"passed","title":"loads","duration":39.74701900000218,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.88614300000336,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.5635470000052,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant loads","status":"passed","title":"loads","duration":40.18777499999851,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.578773999994155,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.43218000000343,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant loads","status":"passed","title":"loads","duration":41.96701600000233,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.11547699999937,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.71625700000004,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant loads","status":"passed","title":"loads","duration":43.063178999997035,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.425113000004785,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.780557999998564,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant loads","status":"passed","title":"loads","duration":46.26079500000196,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.59165799999755,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.51948699999775,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant loads","status":"passed","title":"loads","duration":47.22439899999881,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.81283699999767,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.425889000005554,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant loads","status":"passed","title":"loads","duration":46.9381429999994,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.594262999999046,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.543100000002596,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant loads","status":"passed","title":"loads","duration":41.763636000003316,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.65639699999883,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.88128699999652,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant loads","status":"passed","title":"loads","duration":45.87095599999884,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.481800000001385,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.468926000001375,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant loads","status":"passed","title":"loads","duration":33.68408799999452,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":33.72558500000014,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":35.369613999995636,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant loads","status":"passed","title":"loads","duration":35.2068089999957,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.889916000000085,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":34.9872880000039,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant loads","status":"passed","title":"loads","duration":34.023252999999386,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.6454670000021,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.60455599999841,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant loads","status":"passed","title":"loads","duration":35.890378999996756,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.99015299999883,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.570213999999396,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant loads","status":"passed","title":"loads","duration":43.57010699999955,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.999025999997684,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.011686999998346,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant loads","status":"passed","title":"loads","duration":36.58625200000097,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.96784400000615,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.16748899999948,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant loads","status":"passed","title":"loads","duration":34.16488799999934,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.0612620000029,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.513184999996156,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant loads","status":"passed","title":"loads","duration":40.7182180000018,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.34887400000298,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.32206099999894,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant loads","status":"passed","title":"loads","duration":44.36875300000247,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.40085900000122,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.36279700000159,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant loads","status":"passed","title":"loads","duration":45.24097500000062,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.058877999996184,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.63740200000029,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant loads","status":"passed","title":"loads","duration":44.65563000000111,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.245928000003914,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.492362000004505,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant loads","status":"passed","title":"loads","duration":38.32340400000248,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.35780800000066,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.55279000000155,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant loads","status":"passed","title":"loads","duration":44.513113000000885,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.23265399999946,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.99703800000134,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant loads","status":"passed","title":"loads","duration":40.85001500000362,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.643110000004526,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.76307000000088,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant loads","status":"passed","title":"loads","duration":37.59098300000187,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.58111399999325,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.28978500000085,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant loads","status":"passed","title":"loads","duration":44.88564100000076,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.177966000002925,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.42305900000065,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant loads","status":"passed","title":"loads","duration":45.80647499999759,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.68452199999592,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":51.92641400000139,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant loads","status":"passed","title":"loads","duration":46.833667000006244,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.22730199999933,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.13070499999594,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant loads","status":"passed","title":"loads","duration":48.64607100000285,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.78833299999678,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.97249000000011,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant loads","status":"passed","title":"loads","duration":48.41245300000446,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.582180999997945,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.30973800000356,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant loads","status":"passed","title":"loads","duration":48.290194000001065,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.712383999998565,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.3139730000039,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant loads","status":"passed","title":"loads","duration":47.74810900000011,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.549559999999474,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.48370100000466,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant loads","status":"passed","title":"loads","duration":46.36221300000034,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.01890600000479,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.07706699999835,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant loads","status":"passed","title":"loads","duration":42.5612159999946,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.54126499999984,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.57852599999751,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant loads","status":"passed","title":"loads","duration":44.3757839999962,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.74263799999608,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.51357499999722,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant loads","status":"passed","title":"loads","duration":46.82864699999482,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.88565899999958,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.00246999999945,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant loads","status":"passed","title":"loads","duration":48.568114000001515,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.79377499999828,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.6508909999975,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant loads","status":"passed","title":"loads","duration":48.68537400000059,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.60107599999901,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.103837000002386,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant loads","status":"passed","title":"loads","duration":49.49246600000333,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.308463999994274,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":52.430006999995385,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant loads","status":"passed","title":"loads","duration":50.84267399999953,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":51.300821999997424,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":51.98520400000416,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant loads","status":"passed","title":"loads","duration":50.039310000000114,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":52.07690599999478,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.71176299999934,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant loads","status":"passed","title":"loads","duration":47.50866099999985,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":49.501321999996435,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.99707600000693,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant loads","status":"passed","title":"loads","duration":50.190081000000646,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.15821500000311,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.197283000001335,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant loads","status":"passed","title":"loads","duration":50.5102509999997,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.624455999997735,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":50.16401300000143,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'parties'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'parties' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":47.803501999995206,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'election-cycle'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'election-cycle' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":49.64211599999544,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'committees'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'committees' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":50.66860799999995,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'coalitions'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'coalitions' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":50.06668100000388,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'seasonal-patterns'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'seasonal-patterns' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":49.385385000001406,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'pre-election'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'pre-election' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":45.741941000000224,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'anomaly-detection'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'anomaly-detection' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":44.27487399999518,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'ministers'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'ministers' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":42.61721000000398,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'risk'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'risk' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":47.342328999999154,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'en' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'en' variant hub section exists","status":"passed","title":"hub section exists","duration":48.67845099999977,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'en' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'en' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":48.688670000003185,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'sv' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'sv' variant hub section exists","status":"passed","title":"hub section exists","duration":46.55332199999975,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'sv' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'sv' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":44.31462899999315,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'da' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'da' variant hub section exists","status":"passed","title":"hub section exists","duration":43.877770999999484,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'da' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'da' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":44.910234000002674,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nb' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nb' variant hub section exists","status":"passed","title":"hub section exists","duration":44.26220099999773,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nb' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nb' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":43.110954999996466,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fi' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fi' variant hub section exists","status":"passed","title":"hub section exists","duration":42.99732199999562,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fi' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fi' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":50.37300400000095,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'de' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'de' variant hub section exists","status":"passed","title":"hub section exists","duration":52.52471399999922,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'de' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'de' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":48.90497599999799,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fr' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fr' variant hub section exists","status":"passed","title":"hub section exists","duration":49.64543199999753,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fr' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fr' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":49.99855299999763,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'es' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'es' variant hub section exists","status":"passed","title":"hub section exists","duration":50.60428800000227,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'es' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'es' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":53.23404300000402,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nl' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nl' variant hub section exists","status":"passed","title":"hub section exists","duration":52.023574999999255,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nl' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nl' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":51.19019500000286,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ar' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ar' variant hub section exists","status":"passed","title":"hub section exists","duration":51.52849900000001,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ar' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ar' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":51.03998399999546,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'he' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'he' variant hub section exists","status":"passed","title":"hub section exists","duration":53.308271000001696,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'he' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'he' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":52.145855000002484,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ja' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ja' variant hub section exists","status":"passed","title":"hub section exists","duration":53.23385199999757,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ja' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ja' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":52.403386999998474,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ko' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ko' variant hub section exists","status":"passed","title":"hub section exists","duration":53.8014650000041,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ko' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ko' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":50.8674600000013,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'zh' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'zh' variant hub section exists","status":"passed","title":"hub section exists","duration":49.02865700000257,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'zh' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'zh' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":46.48196800000005,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["sitemap source — dashboard page registration"],"fullName":"sitemap source — dashboard page registration scripts/sitemap-xml/render/sitemap.ts registers all 9 dashboard slugs","status":"passed","title":"scripts/sitemap-xml/render/sitemap.ts registers all 9 dashboard slugs","duration":50.58527199999662,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]}],"startTime":1787953737269,"endTime":1787953783016.5852,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-pages.test.js"},{"assertionResults":[{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should prefer dok_id as the primary identifier","status":"passed","title":"should prefer dok_id as the primary identifier","duration":7.484974999999963,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to dokument_id when dok_id is missing","status":"passed","title":"should fall back to dokument_id when dok_id is missing","duration":1.1705520000000433,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to rel_dok_id when dok_id and dokument_id are missing","status":"passed","title":"should fall back to rel_dok_id when dok_id and dokument_id are missing","duration":1.0154210000000035,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to id when higher-priority fields are missing","status":"passed","title":"should fall back to id when higher-priority fields are missing","duration":1.0647539999999935,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to dokumentnamn as last resort","status":"passed","title":"should fall back to dokumentnamn as last resort","duration":1.031722000000002,"failureMessages":[],"location":{"line":135,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","whitespace trimming on IDs"],"fullName":"data-downloader enrichment whitespace trimming on IDs should trim whitespace from dok_id before calling fetchDocumentDetails","status":"passed","title":"should trim whitespace from dok_id before calling fetchDocumentDetails","duration":0.8431780000000231,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","whitespace trimming on IDs"],"fullName":"data-downloader enrichment whitespace trimming on IDs should skip empty/whitespace-only IDs and fall back","status":"passed","title":"should skip empty/whitespace-only IDs and fall back","duration":0.9183190000000536,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should assign fullText when length exceeds FULL_TEXT_MIN_LENGTH","status":"passed","title":"should assign fullText when length exceeds FULL_TEXT_MIN_LENGTH","duration":1.4587619999999788,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should NOT assign fullText when length is <= FULL_TEXT_MIN_LENGTH","status":"passed","title":"should NOT assign fullText when length is <= FULL_TEXT_MIN_LENGTH","duration":1.249890999999991,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should assign fullContent (from html) when length exceeds FULL_TEXT_MIN_LENGTH","status":"passed","title":"should assign fullContent (from html) when length exceeds FULL_TEXT_MIN_LENGTH","duration":0.9720110000000091,"failureMessages":[],"location":{"line":210,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should NOT assign fullContent when html length is <= FULL_TEXT_MIN_LENGTH","status":"passed","title":"should NOT assign fullContent when html length is <= FULL_TEXT_MIN_LENGTH","duration":0.8208470000000148,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should not overwrite existing summary","status":"passed","title":"should not overwrite existing summary","duration":0.8785950000000184,"failureMessages":[],"location":{"line":238,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should not overwrite existing notis","status":"passed","title":"should not overwrite existing notis","duration":0.9925089999999841,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should set summary when doc does not already have one","status":"passed","title":"should set summary when doc does not already have one","duration":1.0191389999999956,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","isPersonProfileText sanitization"],"fullName":"data-downloader enrichment isPersonProfileText sanitization should filter out MP profile text from fullText","status":"passed","title":"should filter out MP profile text from fullText","duration":0.9681530000000294,"failureMessages":[],"location":{"line":282,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","isPersonProfileText sanitization"],"fullName":"data-downloader enrichment isPersonProfileText sanitization should filter out deceased notice text from summary","status":"passed","title":"should filter out deceased notice text from summary","duration":0.9923379999999611,"failureMessages":[],"location":{"line":298,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","enrichment skips when no IDs available"],"fullName":"data-downloader enrichment enrichment skips when no IDs available should not call fetchDocumentDetails when no ID fields are present","status":"passed","title":"should not call fetchDocumentDetails when no ID fields are present","duration":1.2616729999999734,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","enrichment disabled when enrichLimit is 0"],"fullName":"data-downloader enrichment enrichment disabled when enrichLimit is 0 should skip enrichment when enrichLimit is 0","status":"passed","title":"should skip enrichment when enrichLimit is 0","duration":1.2092150000000288,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should assign fullContent from MCP text field when length exceeds threshold","status":"passed","title":"should assign fullContent from MCP text field when length exceeds threshold","duration":1.1032760000000508,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should prefer text field over html field for fullContent","status":"passed","title":"should prefer text field over html field for fullContent","duration":1.1399339999999825,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should use snippet as summary fallback when no legacy summary field exists","status":"passed","title":"should use snippet as summary fallback when no legacy summary field exists","duration":1.2936219999999707,"failureMessages":[],"location":{"line":378,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should not overwrite existing summary with snippet","status":"passed","title":"should not overwrite existing summary with snippet","duration":1.1404249999999934,"failureMessages":[],"location":{"line":392,"column":5},"meta":{},"tags":[]}],"startTime":1787953789500,"endTime":1787953789531.1404,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/data-downloader-enrichment.test.ts"},{"assertionResults":[{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for live data","status":"passed","title":"should create a disclaimer element for live data","duration":9.54386199999999,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for synthetic data","status":"passed","title":"should create a disclaimer element for synthetic data","duration":1.6409530000000245,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for mock data","status":"passed","title":"should create a disclaimer element for mock data","duration":0.8634770000000458,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-live class for live data","status":"passed","title":"should have data-source-live class for live data","duration":0.8241129999999544,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-synthetic class for synthetic data","status":"passed","title":"should have data-source-synthetic class for synthetic data","duration":0.7241970000000038,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-mock class for mock data","status":"passed","title":"should have data-source-mock class for mock data","duration":0.6975369999999543,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Accessibility"],"fullName":"Data Source Disclaimer Accessibility should have role=\"status\" for screen readers","status":"passed","title":"should have role=\"status\" for screen readers","duration":0.6847420000000284,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should insert after heading when heading exists","status":"passed","title":"should insert after heading when heading exists","duration":0.7380319999999756,"failureMessages":[],"location":{"line":96,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should prepend to container when no heading exists","status":"passed","title":"should prepend to container when no heading exists","duration":1.0120049999999878,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should insert after heading when heading is the last child","status":"passed","title":"should insert after heading when heading is the last child","duration":0.8131630000000314,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Deduplication"],"fullName":"Data Source Disclaimer Deduplication should replace existing disclaimer when called again","status":"passed","title":"should replace existing disclaimer when called again","duration":1.4063540000000216,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Deduplication"],"fullName":"Data Source Disclaimer Deduplication should update CSS class when source type changes","status":"passed","title":"should update CSS class when source type changes","duration":0.7795000000000414,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show ✅ icon for live data","status":"passed","title":"should show ✅ icon for live data","duration":0.6483139999999707,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show ⚠️ icon for synthetic data","status":"passed","title":"should show ⚠️ icon for synthetic data","duration":0.5734630000000038,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show 🔧 icon for mock data","status":"passed","title":"should show 🔧 icon for mock data","duration":0.6209629999999606,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Type Safety"],"fullName":"Data Source Disclaimer Type Safety should accept all valid DataSourceType values","status":"passed","title":"should accept all valid DataSourceType values","duration":0.8729840000000308,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]}],"startTime":1787953847239,"endTime":1787953847261.873,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/data-source-disclaimer.test.ts"},{"assertionResults":[{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback replaces existing container content","status":"passed","title":"replaces existing container content","duration":7.838318000000015,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback renders a skeleton wrapper with role=status","status":"passed","title":"renders a skeleton wrapper with role=status","duration":1.6971880000000397,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback has aria-live=\"polite\" on the skeleton wrapper","status":"passed","title":"has aria-live=\"polite\" on the skeleton wrapper","duration":0.7319800000000214,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback uses the default \"Loading…\" aria-label when no label is supplied","status":"passed","title":"uses the default \"Loading…\" aria-label when no label is supplied","duration":0.6162939999999821,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback uses a custom aria-label when loadingLabel is provided","status":"passed","title":"uses a custom aria-label when loadingLabel is provided","duration":0.6823880000000031,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback renders at least one skeleton bar","status":"passed","title":"renders at least one skeleton bar","duration":1.2767810000000281,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback replaces existing container content","status":"passed","title":"replaces existing container content","duration":1.206278999999995,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders an error card with role=alert","status":"passed","title":"renders an error card with role=alert","duration":0.6850729999999885,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback displays the provided message","status":"passed","title":"displays the provided message","duration":0.7813129999999546,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses default message when none is provided","status":"passed","title":"uses default message when none is provided","duration":0.5471850000000131,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback does not render a retry button when retryFn is omitted","status":"passed","title":"does not render a retry button when retryFn is omitted","duration":0.5878510000000006,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders a retry button when retryFn is provided","status":"passed","title":"renders a retry button when retryFn is provided","duration":1.0546150000000125,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses the default \"Retry\" label for the retry button","status":"passed","title":"uses the default \"Retry\" label for the retry button","duration":0.7898590000000354,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses a custom label for the retry button when retryLabel is provided","status":"passed","title":"uses a custom label for the retry button when retryLabel is provided","duration":0.8082130000000234,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback calls retryFn when the retry button is clicked","status":"passed","title":"calls retryFn when the retry button is clicked","duration":1.8575890000000186,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders an icon element","status":"passed","title":"renders an icon element","duration":0.8427780000000098,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback calls the renderFn on success","status":"passed","title":"calls the renderFn on success","duration":7.597696999999982,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback renders error fallback when renderFn throws synchronously","status":"passed","title":"renders error fallback when renderFn throws synchronously","duration":2.0402709999999615,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback renders error fallback when renderFn rejects","status":"passed","title":"renders error fallback when renderFn rejects","duration":1.7916250000000105,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback shows a retry button after failure","status":"passed","title":"shows a retry button after failure","duration":1.7636319999999728,"failureMessages":[],"location":{"line":183,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback re-runs renderFn when retry button is clicked","status":"passed","title":"re-runs renderFn when retry button is clicked","duration":3.528457000000003,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback does not render error card when renderFn succeeds","status":"passed","title":"does not render error card when renderFn succeeds","duration":1.7269739999999842,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback uses default fallback message when none is supplied","status":"passed","title":"uses default fallback message when none is supplied","duration":2.319474000000014,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback removes the loading overlay after a successful render","status":"passed","title":"removes the loading overlay after a successful render","duration":2.157880999999975,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback removes the loading overlay after a failed render","status":"passed","title":"removes the loading overlay after a failed render","duration":1.7970250000000192,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback ignores concurrent retry clicks while an attempt is already in flight","status":"passed","title":"ignores concurrent retry clicks while an attempt is already in flight","duration":3.0493000000000166,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback preserves existing container HTML when renderFn runs on the first attempt","status":"passed","title":"preserves existing container HTML when renderFn runs on the first attempt","duration":2.2180040000000076,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback restores original HTML before retry after failure","status":"passed","title":"restores original HTML before retry after failure","duration":4.186538999999982,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback forwards options.loadingLabel to the loading overlay ARIA label","status":"passed","title":"forwards options.loadingLabel to the loading overlay ARIA label","duration":1.4529899999999998,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback forwards options.retryLabel to the retry button on failure","status":"passed","title":"forwards options.retryLabel to the retry button on failure","duration":1.6381069999999909,"failureMessages":[],"location":{"line":321,"column":3},"meta":{},"tags":[]}],"startTime":1787953808335,"endTime":1787953808394.6382,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/error-boundary.test.ts"},{"assertionResults":[{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks removes a single ```mermaid block while preserving surrounding prose","status":"passed","title":"removes a single ```mermaid block while preserving surrounding prose","duration":3.8649970000000167,"failureMessages":[],"location":{"line":8,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks preserves non-mermaid fenced code blocks","status":"passed","title":"preserves non-mermaid fenced code blocks","duration":0.5914080000000013,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks strips multiple ```mermaid blocks independently","status":"passed","title":"strips multiple ```mermaid blocks independently","duration":0.4930529999999749,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks is case-insensitive on the mermaid fence opener","status":"passed","title":"is case-insensitive on the mermaid fence opener","duration":0.4340230000000247,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns true for identical inputs","status":"passed","title":"returns true for identical inputs","duration":0.4953570000000127,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns true when the only change is inside a ```mermaid block (autofix case)","status":"passed","title":"returns true when the only change is inside a ```mermaid block (autofix case)","duration":0.41799300000002404,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a brand-new ```mermaid block is appended with surrounding blank lines","status":"passed","title":"returns false when a brand-new ```mermaid block is appended with surrounding blank lines","duration":0.4077429999999822,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a narrative line changes","status":"passed","title":"returns false when a narrative line changes","duration":0.377708000000041,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a non-mermaid fenced block changes","status":"passed","title":"returns false when a non-mermaid fenced block changes","duration":0.4320189999999684,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a heading is added","status":"passed","title":"returns false when a heading is added","duration":0.49704100000002427,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly normalises CRLF vs LF line endings","status":"passed","title":"normalises CRLF vs LF line endings","duration":0.3860230000000229,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]}],"startTime":1787953913948,"endTime":1787953913957.386,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/exec-brief-narrative-drift.test.ts"},{"assertionResults":[{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":5.016440999999986,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.8750280000001567,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":17.303875000000062,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":6.510487999999896,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.812953000000107,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.888522999999623,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":5.966891000000032,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7868430000003173,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.8530369999998584,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.2997610000002169,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3904609999999593,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.218221999999969,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.124693000000207,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.898520999999619,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.463946999999735,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.7946640000000116,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.5780119999999442,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.5048850000002858,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.2917760000000271,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3611959999998362,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.69183699999985,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.162452999999914,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.597740000000158,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":13.805897000000186,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":2.895140000000083,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.6360610000001543,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.6002639999996973,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.43916200000012395,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3451660000000629,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.873665999999957,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.93370700000014,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":7.222271999999975,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.17506800000001,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.733339000000342,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7614460000004328,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.557875000000422,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.4904679999999644,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.39901700000018536,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":7.247799000000214,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.2230759999997645,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.85823500000015,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.384449000000131,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.598488999999972,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7594719999997324,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.6680999999998676,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.49559799999997267,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.47481900000002497,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.96959599999991,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.207056000000193,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.861532000000352,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":14.264754999999695,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.859827999999652,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.9671210000001338,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.7935359999996763,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.6155519999997523,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.5901249999997162,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":1.6289790000000721,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":1.1307969999998022,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":1.300894999999855,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":1.6713989999998375,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":1.129584999999679,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7352659999996831,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.7111620000000585,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.7632190000003902,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.76767800000016,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.893385999999737,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.651459000000159,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.276708999999755,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.956811000000016,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.376702999999907,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.1460250000000087,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.0956919999998718,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.8855979999998453,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.9392079999997804,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.473809999999958,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.880947000000106,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":6.810469999999896,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.59509399999979,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.5787320000004,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.856927000000269,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.8523279999999431,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.755537000000004,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.7740210000001753,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":8.238152999999784,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.329145000000153,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.61296799999991,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":8.80328099999997,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.7292019999999866,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.4378719999999703,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.3646859999998924,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.1966899999997622,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.3082490000001599,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.440875999999662,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.126534999999876,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.728451999999834,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":8.498810999999932,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.6939360000001216,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.5879429999999957,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.497534000000087,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.3850440000001072,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.6042030000003251,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":4.885706999999911,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":3.367334000000028,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":3.7876510000000962,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":5.743301999999858,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.0686650000002373,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.712485999999899,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.7243889999999737,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.5486789999999928,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.935573000000204,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":8.682045000000016,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.539800000000014,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.005620999999792,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":6.859852000000046,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":2.7987699999998767,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.8755409999998847,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.8274109999997563,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]}],"startTime":1787953665517,"endTime":1787953665953.8274,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/executive-brief-seo-corpus.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records parses --date and --doc-type and --persist happy path","status":"passed","title":"parses --date and --doc-type and --persist happy path","duration":3.976937000000021,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records defaults date to today when not provided","status":"passed","title":"defaults date to today when not provided","duration":1.0664470000000392,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records returns error for invalid date format","status":"passed","title":"returns error for invalid date format","duration":0.746688000000006,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records returns error for non-date string","status":"passed","title":"returns error for non-date string","duration":0.5257249999999658,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records parses --date without --doc-type","status":"passed","title":"parses --date without --doc-type","duration":0.4732360000000426,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records persist defaults to false when flag is absent","status":"passed","title":"persist defaults to false when flag is absent","duration":0.631672999999978,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors returns vote_pending status when input is empty","status":"passed","title":"returns vote_pending status when input is empty","duration":1.653316000000018,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors detects an MP voting Nej when party majority is Ja","status":"passed","title":"detects an MP voting Nej when party majority is Ja","duration":1.906630000000007,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors detects no defectors when all MPs vote with their party","status":"passed","title":"detects no defectors when all MPs vote with their party","duration":0.6699440000000436,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors excludes Frånvarande from defector list","status":"passed","title":"excludes Frånvarande from defector list","duration":0.5549589999999966,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors handles multiple defectors across multiple parties","status":"passed","title":"handles multiple defectors across multiple parties","duration":0.9299510000000168,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors handles votes with alternative field names","status":"passed","title":"handles votes with alternative field names","duration":0.6127670000000194,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart produces a valid mermaid string for party votes","status":"passed","title":"produces a valid mermaid string for party votes","duration":0.7006920000000036,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart returns a flowchart-style diagram when there are no party votes","status":"passed","title":"returns a flowchart-style diagram when there are no party votes","duration":0.5254740000000311,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart includes x-axis and y-axis labels","status":"passed","title":"includes x-axis and y-axis labels","duration":0.481521999999984,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues extracts beteckning values from manifest text","status":"passed","title":"extracts beteckning values from manifest text","duration":0.8356850000000122,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues filters out common false-positive acronyms","status":"passed","title":"filters out common false-positive acronyms","duration":0.7407870000000116,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues returns empty array for manifest with no beteckning values","status":"passed","title":"returns empty array for manifest with no beteckning values","duration":0.6032490000000053,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet lowercases and preserves alphanumeric content","status":"passed","title":"lowercases and preserves alphanumeric content","duration":0.5385089999999764,"failureMessages":[],"location":{"line":238,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet replaces special characters with hyphens","status":"passed","title":"replaces special characters with hyphens","duration":0.5227489999999761,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet collapses multiple hyphens","status":"passed","title":"collapses multiple hyphens","duration":0.45041300000002593,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract: voting records have status field"],"fullName":"contract: voting records have status field every voting record JSON in data/voteringar/ has a status field","status":"passed","title":"every voting record JSON in data/voteringar/ has a status field","duration":0.6113740000000121,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract: voting records have status field"],"fullName":"contract: voting records have status field cited betänkanden have either a voting record or an explicit pending/not-found/error annotation","status":"passed","title":"cited betänkanden have either a voting record or an explicit pending/not-found/error annotation","duration":1.9332599999999616,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]}],"startTime":1787953790982,"endTime":1787953791004.9333,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-voting-records.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc loads and validates the real registry without error","status":"passed","title":"loads and validates the real registry without error","duration":4.09987799999999,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc renders a table containing all registry IDs","status":"passed","title":"renders a table containing all registry IDs","duration":1.3256119999999783,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc replaces content between sentinels correctly","status":"passed","title":"replaces content between sentinels correctly","duration":0.8002390000000332,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc is idempotent — running twice produces same output","status":"passed","title":"is idempotent — running twice produces same output","duration":0.7114520000000084,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on missing sentinels","status":"passed","title":"throws on missing sentinels","duration":1.3618210000000204,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on invalid registry (empty types)","status":"passed","title":"throws on invalid registry (empty types)","duration":1.3881089999999858,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing articleWordFloor","status":"passed","title":"throws on registry entry missing articleWordFloor","duration":0.961731000000043,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc renders dispatch-only types with italic marker","status":"passed","title":"renders dispatch-only types with italic marker","duration":0.5191429999999855,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc does not modify content outside sentinels in Article-Generation.md","status":"passed","title":"does not modify content outside sentinels in Article-Generation.md","duration":0.973041999999964,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry missing version field","status":"passed","title":"throws on registry missing version field","duration":0.800249000000008,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing id/family/horizonDays/tierCMultiplier","status":"passed","title":"throws on registry entry missing id/family/horizonDays/tierCMultiplier","duration":0.9926190000000474,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing electionCycleAnchor","status":"passed","title":"throws on registry entry missing electionCycleAnchor","duration":0.7950389999999743,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing cronExpression when not dispatchOnly","status":"passed","title":"throws on registry entry missing cronExpression when not dispatchOnly","duration":0.7469180000000506,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws when END sentinel appears before BEGIN sentinel","status":"passed","title":"throws when END sentinel appears before BEGIN sentinel","duration":0.5689160000000015,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc generate() writes updated content to a temp doc","status":"passed","title":"generate() writes updated content to a temp doc","duration":0.9576729999999998,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]}],"startTime":1787953830469,"endTime":1787953830485.9578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-article-types-doc.test.ts"},{"assertionResults":[{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects methodology catalog with all expected entries","status":"passed","title":"collects methodology catalog with all expected entries","duration":15.241341000000034,"failureMessages":[],"location":{"line":42,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects template catalog with all expected entries","status":"passed","title":"collects template catalog with all expected entries","duration":1.8827260000000479,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects daily artifacts grouped by date (newest first)","status":"passed","title":"collects daily artifacts grouped by date (newest first)","duration":91.88651600000003,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":6.644252000000051,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8799679999999626,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.5232300000000123,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.5422259999999142,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.3949890000000096,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.811719999999923,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.4808709999999792,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.46976999999992586,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.221270000000004,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.6748039999999946,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":6.473494000000073,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.818702999999914,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.6048019999999497,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.4870420000000877,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.3791200000000572,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.9316749999999274,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.45097500000008495,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.4572160000000167,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.193829000000051,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.5246329999999944,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.519071000000167,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.7787479999999505,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.48790299999996023,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.4833659999999327,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.37968099999989136,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.6390069999999923,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.486601999999948,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.6139299999999821,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.392871000000014,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.7250070000000051,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.450934999999845,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8088540000001103,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.5485869999999977,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.5903060000000551,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.47820499999988897,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.6576419999998961,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.5393599999999878,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.4918210000000727,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.477558999999928,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.7707729999999628,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.682086000000027,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8976920000000064,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.519172000000026,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.6009950000000117,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.5191529999999602,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.7501949999998487,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.6373730000000251,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.5960969999998724,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.307620999999926,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.8289219999999204,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.882039999999961,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.031631999999945,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.7374919999999747,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.7283039999999801,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.6422029999998813,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.8565739999999096,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.7557150000000092,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.734185000000025,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.537372000000005,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.0506069999999,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.344785999999885,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.16269699999998,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.879758000000038,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.9280979999998635,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.8034350000000359,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.0272029999998722,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.8886640000000625,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.8461839999999938,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.596042000000125,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.170562000000018,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.801107999999886,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.78707600000007,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.0220240000001013,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.0708559999998215,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.9722609999998895,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.4481719999998859,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.2993039999998928,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.075563000000102,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.0041459999999915,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.615664999999808,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.869134000000031,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.6742749999998523,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.186151000000109,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.192303000000038,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.2594890000000305,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.46850900000004,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.2371160000000145,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.188385000000153,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.049980999999889,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.668685000000096,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":9.280056000000059,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.995486000000028,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.3790120000001025,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.4506559999999808,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.431831000000102,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.6398910000000342,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.5079840000000786,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.7935990000000857,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.127584999999954,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":3.9127659999999196,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.312143000000106,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.3757190000001174,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.5426390000002357,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.5440110000004097,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.4696619999999712,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.692047999999886,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.5704109999996945,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.5606419999999162,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.1632220000001325,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.151789000000008,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.40231199999971,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.252769000000171,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.71330799999987,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.723117000000002,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.7388960000002953,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.038206000000173,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.867978000000221,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.7056539999998677,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.204670000000078,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.0517219999996996,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.792352999999821,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.356231000000207,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.8189659999998185,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.9584569999997257,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":2.5640109999999368,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.1654849999999897,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.943398999999772,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":2.0561800000000403,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.333119999999781,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.3363039999999273,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":10.554462000000058,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.618872999999894,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":2.0278080000002774,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":2.1345470000001114,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":2.0487459999999373,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.2395430000001397,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":2.1676189999998314,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":2.1176249999998618,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.5961230000002615,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.7829609999998866,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence.html on disk","status":"passed","title":"writes political-intelligence.html on disk","duration":14.128293999999642,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_sv.html on disk","status":"passed","title":"writes political-intelligence_sv.html on disk","duration":12.673048000000108,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_da.html on disk","status":"passed","title":"writes political-intelligence_da.html on disk","duration":9.960979999999836,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_no.html on disk","status":"passed","title":"writes political-intelligence_no.html on disk","duration":9.853379000000132,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_fi.html on disk","status":"passed","title":"writes political-intelligence_fi.html on disk","duration":9.821429999999964,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_de.html on disk","status":"passed","title":"writes political-intelligence_de.html on disk","duration":10.488418999999794,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_fr.html on disk","status":"passed","title":"writes political-intelligence_fr.html on disk","duration":14.370887999999923,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_es.html on disk","status":"passed","title":"writes political-intelligence_es.html on disk","duration":29.221854999999778,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_nl.html on disk","status":"passed","title":"writes political-intelligence_nl.html on disk","duration":9.745898000000125,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ar.html on disk","status":"passed","title":"writes political-intelligence_ar.html on disk","duration":10.148682999999892,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_he.html on disk","status":"passed","title":"writes political-intelligence_he.html on disk","duration":10.120950999999877,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ja.html on disk","status":"passed","title":"writes political-intelligence_ja.html on disk","duration":9.959789,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ko.html on disk","status":"passed","title":"writes political-intelligence_ko.html on disk","duration":10.468181000000186,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_zh.html on disk","status":"passed","title":"writes political-intelligence_zh.html on disk","duration":23.486135000000104,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ aggregates keywords from methodology + template titles (capped at 30)","status":"passed","title":"aggregates keywords from methodology + template titles (capped at 30)","duration":10.52614900000026,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ deduplicates keyword entries","status":"passed","title":"deduplicates keyword entries","duration":3.1451090000000477,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ does NOT leak English methodology/template titles into non-EN keywords (W3 regression)","status":"passed","title":"does NOT leak English methodology/template titles into non-EN keywords (W3 regression)","duration":1415.0040209999997,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ keeps the EN methodology titles in the EN PI page (sanity check — no over-correction)","status":"passed","title":"keeps the EN methodology titles in the EN PI page (sanity check — no over-correction)","duration":114.28237100000024,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ emits a FAQPage JSON-LD block","status":"passed","title":"emits a FAQPage JSON-LD block","duration":3.517095000000154,"failureMessages":[],"location":{"line":274,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":7.553944000000229,"failureMessages":[],"location":{"line":278,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ localises the FAQ heading for non-English pages","status":"passed","title":"localises the FAQ heading for non-English pages","duration":114.23523300000033,"failureMessages":[],"location":{"line":284,"column":5},"meta":{},"tags":[]}],"startTime":1787953809472,"endTime":1787953813420.2354,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-political-intelligence.test.ts"},{"assertionResults":[{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape ampersand","status":"passed","title":"should escape ampersand","duration":3.4250729999999976,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape angle brackets","status":"passed","title":"should escape angle brackets","duration":0.5270270000000892,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape quotes","status":"passed","title":"should escape quotes","duration":0.3818949999999859,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape apostrophes","status":"passed","title":"should escape apostrophes","duration":0.3906819999999698,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should handle plain text","status":"passed","title":"should handle plain text","duration":0.5521340000000237,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode existing numeric entities","status":"passed","title":"should not double-encode existing numeric entities","duration":0.3893190000000004,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode decimal entities","status":"passed","title":"should not double-encode decimal entities","duration":0.40818400000000565,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode named entities","status":"passed","title":"should not double-encode named entities","duration":0.3673479999999927,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should return articles","status":"passed","title":"should return articles","duration":137.2899309999999,"failureMessages":[],"location":{"line":90,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should return English articles only","status":"passed","title":"should return English articles only","duration":131.03243199999997,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have multi-language alternates","status":"passed","title":"should have multi-language alternates","duration":172.91293700000006,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should extract article titles","status":"passed","title":"should extract article titles","duration":128.14704800000004,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have valid links","status":"passed","title":"should have valid links","duration":126.58995299999992,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should be sorted by date (most recent first)","status":"passed","title":"should be sorted by date (most recent first)","duration":165.65114300000005,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should limit to 50 articles","status":"passed","title":"should limit to 50 articles","duration":125.03715499999998,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have author field on articles","status":"passed","title":"should have author field on articles","duration":125.45652900000005,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have category field on articles","status":"passed","title":"should have category field on articles","duration":122.95050400000014,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should derive stable pubDate from filename when meta tag is missing","status":"passed","title":"should derive stable pubDate from filename when meta tag is missing","duration":186.38644399999998,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should return valid RSS 2.0 XML","status":"passed","title":"should return valid RSS 2.0 XML","duration":1.40954899999997,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel element","status":"passed","title":"should have channel element","duration":0.4804300000000694,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel title","status":"passed","title":"should have channel title","duration":0.4859700000001794,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel link","status":"passed","title":"should have channel link","duration":0.3720570000000407,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel description","status":"passed","title":"should have channel description","duration":0.4299850000002152,"failureMessages":[],"location":{"line":188,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have language element","status":"passed","title":"should have language element","duration":0.37470200000007026,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have atom self link","status":"passed","title":"should have atom self link","duration":0.43840100000034,"failureMessages":[],"location":{"line":196,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have atom namespace","status":"passed","title":"should have atom namespace","duration":0.4079229999997551,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have dc namespace","status":"passed","title":"should have dc namespace","duration":0.3778069999998479,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel image","status":"passed","title":"should have channel image","duration":0.4622159999998985,"failureMessages":[],"location":{"line":208,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have items","status":"passed","title":"should have items","duration":0.45662499999980355,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item titles","status":"passed","title":"should have item titles","duration":0.5390200000001641,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item links","status":"passed","title":"should have item links","duration":0.5371259999997164,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item guids","status":"passed","title":"should have item guids","duration":0.5331690000002709,"failureMessages":[],"location":{"line":227,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have pubDate elements","status":"passed","title":"should have pubDate elements","duration":0.5497299999997267,"failureMessages":[],"location":{"line":231,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have dc:creator elements","status":"passed","title":"should have dc:creator elements","duration":0.49108899999964706,"failureMessages":[],"location":{"line":235,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have per-item category elements","status":"passed","title":"should have per-item category elements","duration":0.5547289999999521,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have multi-language hreflang alternates","status":"passed","title":"should have multi-language hreflang alternates","duration":0.46345800000017334,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have hreflang alternates for multiple languages","status":"passed","title":"should have hreflang alternates for multiple languages","duration":0.8948760000002949,"failureMessages":[],"location":{"line":249,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel categories","status":"passed","title":"should have channel categories","duration":0.5528960000001462,"failureMessages":[],"location":{"line":255,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have copyright","status":"passed","title":"should have copyright","duration":0.4946460000001025,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have ttl element","status":"passed","title":"should have ttl element","duration":0.49074800000016694,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have lastBuildDate","status":"passed","title":"should have lastBuildDate","duration":0.47954799999979514,"failureMessages":[],"location":{"line":269,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have generator element","status":"passed","title":"should have generator element","duration":0.5049859999999171,"failureMessages":[],"location":{"line":273,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have docs link","status":"passed","title":"should have docs link","duration":0.5014489999998659,"failureMessages":[],"location":{"line":277,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should pass for valid RSS","status":"passed","title":"should pass for valid RSS","duration":2.2519970000003013,"failureMessages":[],"location":{"line":283,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing XML declaration","status":"passed","title":"should throw for missing XML declaration","duration":0.9507000000003245,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing RSS version","status":"passed","title":"should throw for missing RSS version","duration":0.7497440000001916,"failureMessages":[],"location":{"line":292,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing channel","status":"passed","title":"should throw for missing channel","duration":0.738503000000037,"failureMessages":[],"location":{"line":296,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for empty feed","status":"passed","title":"should throw for empty feed","duration":0.7367899999999281,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds English feed keeps the branded channel title and en language","status":"passed","title":"English feed keeps the branded channel title and en language","duration":0.6180469999999332,"failureMessages":[],"location":{"line":307,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds Swedish feed localizes title, description, language and self link","status":"passed","title":"Swedish feed localizes title, description, language and self link","duration":127.90203900000006,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds German feed localizes the channel header","status":"passed","title":"German feed localizes the channel header","duration":121.87650799999983,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds Norwegian feed uses BCP-47 hreflang \"nb\" for <language>","status":"passed","title":"Norwegian feed uses BCP-47 hreflang \"nb\" for <language>","duration":117.0616299999997,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds localized item link/guid point at the requested language variant","status":"passed","title":"localized item link/guid point at the requested language variant","duration":183.30492700000013,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds getRssArticles(lang) anchors items on that language variant","status":"passed","title":"getRssArticles(lang) anchors items on that language variant","duration":131.05940099999998,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]}],"startTime":1787953804640,"endTime":1787953806770.0593,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-rss.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap HTML Generation","escapeHtml"],"fullName":"Sitemap HTML Generation escapeHtml should escape HTML special characters","status":"passed","title":"should escape HTML special characters","duration":3.725485000000049,"failureMessages":[],"location":{"line":42,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","escapeHtml"],"fullName":"Sitemap HTML Generation escapeHtml should handle plain text without changes","status":"passed","title":"should handle plain text without changes","duration":0.6137590000000159,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have metadata for all 14 languages","status":"passed","title":"should have metadata for all 14 languages","duration":1.587742999999989,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have RTL direction for Arabic and Hebrew","status":"passed","title":"should have RTL direction for Arabic and Hebrew","duration":0.4693889999999783,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have LTR direction for other languages","status":"passed","title":"should have LTR direction for other languages","duration":0.814534999999978,"failureMessages":[],"location":{"line":69,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should use nb hreflang for Norwegian","status":"passed","title":"should use nb hreflang for Norwegian","duration":0.46601200000003473,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should return articles grouped by language","status":"passed","title":"should return articles grouped by language","duration":1799.6112320000002,"failureMessages":[],"location":{"line":82,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should include English articles","status":"passed","title":"should include English articles","duration":1902.408343,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should include Swedish articles","status":"passed","title":"should include Swedish articles","duration":1864.633769,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should extract article titles","status":"passed","title":"should extract article titles","duration":1877.6908780000003,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should populate an ISO date (YYYY-MM-DD) parsed from the filename","status":"passed","title":"should populate an ISO date (YYYY-MM-DD) parsed from the filename","duration":1866.0611510000008,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should return articles sorted by date descending (newest first)","status":"passed","title":"should return articles sorted by date descending (newest first)","duration":1832.7099040000012,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","all-pages contract"],"fullName":"Sitemap HTML Generation all-pages contract should list every English article in the generated HTML (no artificial cap)","status":"passed","title":"should list every English article in the generated HTML (no artificial cap)","duration":1831.878525,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","all-pages contract"],"fullName":"Sitemap HTML Generation all-pages contract should render articles in chronological (desc) order in the HTML","status":"passed","title":"should render articles in chronological (desc) order in the HTML","duration":1817.0226950000015,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate valid HTML for English","status":"passed","title":"should generate valid HTML for English","duration":1827.4968449999978,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate RTL HTML for Arabic","status":"passed","title":"should generate RTL HTML for Arabic","duration":1832.725555000001,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate RTL HTML for Hebrew","status":"passed","title":"should generate RTL HTML for Hebrew","duration":1837.6454159999994,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include hreflang tags","status":"passed","title":"should include hreflang tags","duration":1833.2851420000006,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include article links for the target language","status":"passed","title":"should include article links for the target language","duration":1815.5746330000002,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include dashboard links","status":"passed","title":"should include dashboard links","duration":1820.9017459999995,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include docs section when docs exist","status":"passed","title":"should include docs section when docs exist","duration":1841.8231349999987,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include proper meta tags","status":"passed","title":"should include proper meta tags","duration":1827.2917000000016,"failureMessages":[],"location":{"line":216,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include skip link for accessibility","status":"passed","title":"should include skip link for accessibility","duration":1827.209745,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include localized section headings","status":"passed","title":"should include localized section headings","duration":1832.5752219999958,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include JSON-LD structured data","status":"passed","title":"should include JSON-LD structured data","duration":1849.2409079999998,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should use index.html for English home link","status":"passed","title":"should use index.html for English home link","duration":1838.0931860000055,"failureMessages":[],"location":{"line":258,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should use language-specific home link for non-English languages","status":"passed","title":"should use language-specific home link for non-English languages","duration":1846.669259000002,"failureMessages":[],"location":{"line":267,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include the unified `rm-site-header` brand row","status":"passed","title":"should include the unified `rm-site-header` brand row","duration":1855.4431669999976,"failureMessages":[],"location":{"line":279,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the canonical `rm-site-header` (with theme toggle and lang switcher)","status":"passed","title":"emits the canonical `rm-site-header` (with theme toggle and lang switcher)","duration":1.7950409999975818,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the canonical 3-column `rm-site-footer` and footer language row","status":"passed","title":"emits the canonical 3-column `rm-site-footer` and footer language row","duration":1.1258680000028107,"failureMessages":[],"location":{"line":304,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the anti-flash inline theme bootstrap in <head>","status":"passed","title":"emits the anti-flash inline theme bootstrap in <head>","duration":0.4882339999967371,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits a `BreadcrumbList` JSON-LD blob (Home > Sitemap)","status":"passed","title":"emits a `BreadcrumbList` JSON-LD blob (Home > Sitemap)","duration":0.4951770000043325,"failureMessages":[],"location":{"line":318,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits a localised footer (Swedish)","status":"passed","title":"emits a localised footer (Swedish)","duration":1862.9123130000007,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) uses the sitemap-specific lang switcher fallback (`sitemap_sv.html`, not `index_sv.html`)","status":"passed","title":"uses the sitemap-specific lang switcher fallback (`sitemap_sv.html`, not `index_sv.html`)","duration":1.3445579999970505,"failureMessages":[],"location":{"line":331,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) uses og:type=\"website\" (suppresses article:* meta)","status":"passed","title":"uses og:type=\"website\" (suppresses article:* meta)","duration":0.6299790000048233,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a meta description between 140 and 200 chars (EN budget per seo-metadata-contract.md §4)","status":"passed","title":"emits a meta description between 140 and 200 chars (EN budget per seo-metadata-contract.md §4)","duration":2.253629999999248,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a FAQPage JSON-LD block","status":"passed","title":"emits a FAQPage JSON-LD block","duration":0.6086190000060014,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":0.8160879999995814,"failureMessages":[],"location":{"line":362,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ localises the FAQ heading for non-English pages","status":"passed","title":"localises the FAQ heading for non-English pages","duration":1841.7026069999993,"failureMessages":[],"location":{"line":368,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a WebPage JSON-LD node with @id","status":"passed","title":"emits a WebPage JSON-LD node with @id","duration":1.7952809999987949,"failureMessages":[],"location":{"line":374,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits an ItemList JSON-LD of catalogued articles (up to 200)","status":"passed","title":"emits an ItemList JSON-LD of catalogued articles (up to 200)","duration":0.61600300000282,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Generated Files Validation"],"fullName":"Sitemap HTML Generation Generated Files Validation should have valid HTML structure in all existing files","status":"passed","title":"should have valid HTML structure in all existing files","duration":0.6741020000044955,"failureMessages":[],"location":{"line":396,"column":5},"meta":{},"tags":[]}],"startTime":1787953687094,"endTime":1787953734989.674,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-sitemap-html.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should return valid XML string","status":"passed","title":"should return valid XML string","duration":353.885979,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include main index page","status":"passed","title":"should include main index page","duration":258.094651,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include language index pages","status":"passed","title":"should include language index pages","duration":191.20198799999991,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include politician dashboard page","status":"passed","title":"should include politician dashboard page","duration":201.76572699999997,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include dashboard pages","status":"passed","title":"should include dashboard pages","duration":199.43017499999996,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include sitemap HTML pages","status":"passed","title":"should include sitemap HTML pages","duration":242.33588900000018,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include xhtml namespace for hreflang","status":"passed","title":"should include xhtml namespace for hreflang","duration":189.91596900000013,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include hreflang alternate links","status":"passed","title":"should include hreflang alternate links","duration":183.25120000000015,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include changefreq and priority tags","status":"passed","title":"should include changefreq and priority tags","duration":184.4254289999999,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include lastmod tags","status":"passed","title":"should include lastmod tags","duration":225.11570200000006,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include news index pages","status":"passed","title":"should include news index pages","duration":200.06671300000016,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include all 14 news index languages when they exist","status":"passed","title":"should include all 14 news index languages when they exist","duration":186.23659099999986,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include localized rss feeds that exist on disk","status":"passed","title":"should include localized rss feeds that exist on disk","duration":186.0032940000001,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should only reference URLs whose backing files exist","status":"passed","title":"should only reference URLs whose backing files exist","duration":230.13685499999974,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should pass for valid sitemap XML","status":"passed","title":"should pass for valid sitemap XML","duration":195.80874399999993,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should return true for valid sitemap","status":"passed","title":"should return true for valid sitemap","duration":189.205019,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for missing XML declaration","status":"passed","title":"should throw for missing XML declaration","duration":1.0754339999998592,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for missing sitemap namespace","status":"passed","title":"should throw for missing sitemap namespace","duration":0.7003610000001572,"failureMessages":[],"location":{"line":171,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for empty sitemap with no URLs","status":"passed","title":"should throw for empty sitemap with no URLs","duration":0.6373640000001615,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for sitemap with no <loc> tags","status":"passed","title":"should throw for sitemap with no <loc> tags","duration":0.6605570000001535,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]}],"startTime":1787953850071,"endTime":1787953853491.6606,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-sitemap.test.ts"},{"assertionResults":[{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh script is executable and bash-syntax clean (and shellcheck-clean if available)","status":"passed","title":"script is executable and bash-syntax clean (and shellcheck-clean if available)","duration":2060.204425,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 1: primary path with bundle + manifest succeeds (dry run)","status":"passed","title":"scenario 1: primary path with bundle + manifest succeeds (dry run)","duration":576.8515520000001,"failureMessages":[],"location":{"line":183,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 1b: auto-probes manifest at agent/aw-fallback.json (current contract location)","status":"passed","title":"scenario 1b: auto-probes manifest at agent/aw-fallback.json (current contract location)","duration":568.8577249999998,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 2: primary path with bundle only derives branch from bundle","status":"passed","title":"scenario 2: primary path with bundle only derives branch from bundle","duration":259.4626980000003,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 3: secondary path on session-not-found + dirty workspace","status":"passed","title":"scenario 3: secondary path on session-not-found + dirty workspace","duration":169.86076900000035,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 4: no-op when no handoff and no session-not-found marker","status":"passed","title":"scenario 4: no-op when no handoff and no session-not-found marker","duration":75.33140300000014,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh skip when safeoutputs already created the PR","status":"passed","title":"skip when safeoutputs already created the PR","duration":141.88150399999995,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh recovers failed safeoutputs aw-main bundle instead of treating the request as success","status":"passed","title":"recovers failed safeoutputs aw-main bundle instead of treating the request as success","duration":278.46063799999956,"failureMessages":[],"location":{"line":303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh fails non-zero when manifest is malformed JSON","status":"passed","title":"fails non-zero when manifest is malformed JSON","duration":157.87383299999965,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh refuses to push when recovered branch equals the default branch","status":"passed","title":"refuses to push when recovered branch equals the default branch","duration":520.5280279999997,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh refuses to push when recovered commit modifies protected paths","status":"passed","title":"refuses to push when recovered commit modifies protected paths","duration":569.8963890000005,"failureMessages":[],"location":{"line":398,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh preflight: exits as a no-op when safeoutputs primary path already opened the PR at recovered SHA","status":"passed","title":"preflight: exits as a no-op when safeoutputs primary path already opened the PR at recovered SHA","duration":709.1469809999999,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]}],"startTime":1787953668871,"endTime":1787953674960.147,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/gh-aw-pat-pr-fallback.test.ts"},{"assertionResults":[{"ancestorTitles":["horizon-context — registry loading"],"fullName":"horizon-context — registry loading loads and returns the registry","status":"passed","title":"loads and returns the registry","duration":4.031298000000049,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — registry loading"],"fullName":"horizon-context — registry loading caches the result (same reference on repeat call)","status":"passed","title":"caches the result (same reference on repeat call)","duration":0.7050489999999741,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType returns the canonical entry for week-ahead","status":"passed","title":"returns the canonical entry for week-ahead","duration":0.6541149999999902,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType returns election-cycle with correct multiplier","status":"passed","title":"returns election-cycle with correct multiplier","duration":0.5046349999999507,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType throws on unknown id","status":"passed","title":"throws on unknown id","duration":1.4073850000000334,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is positive for dates before 2026-09-13","status":"passed","title":"is positive for dates before 2026-09-13","duration":0.726509999999962,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is negative for dates after 2026-09-13","status":"passed","title":"is negative for dates after 2026-09-13","duration":0.49073900000001913,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is zero on election day","status":"passed","title":"is zero on election day","duration":0.37580400000001646,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — activeCycleAnchor"],"fullName":"horizon-context — activeCycleAnchor returns current before 2026-09-13","status":"passed","title":"returns current before 2026-09-13","duration":0.48357600000002776,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — activeCycleAnchor"],"fullName":"horizon-context — activeCycleAnchor returns next on or after 2026-09-13","status":"passed","title":"returns next on or after 2026-09-13","duration":0.40877499999999145,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Apr-YEAR for May–Oct of YEAR","status":"passed","title":"Apr-YEAR for May–Oct of YEAR","duration":0.5049060000000054,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Oct-YEAR for Nov–Dec of YEAR","status":"passed","title":"Oct-YEAR for Nov–Dec of YEAR","duration":0.4333609999999908,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Oct-YEAR-1 for Jan–Apr of YEAR","status":"passed","title":"Oct-YEAR-1 for Jan–Apr of YEAR","duration":0.3655039999999872,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase autumn covers Sep–early Dec","status":"passed","title":"autumn covers Sep–early Dec","duration":0.44121599999999717,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase xmas-recess covers late Dec–Jan","status":"passed","title":"xmas-recess covers late Dec–Jan","duration":0.4053389999999695,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase spring covers Feb–early Jun","status":"passed","title":"spring covers Feb–early Jun","duration":0.3856519999999932,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase summer-recess covers late Jun–Aug","status":"passed","title":"summer-recess covers late Jun–Aug","duration":0.4451829999999859,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition composes a coherent record for year-ahead 2026-07-05 (typical run)","status":"passed","title":"composes a coherent record for year-ahead 2026-07-05 (typical run)","duration":0.49104900000003227,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition flags cycleRolloverActive within ± 30 days of election","status":"passed","title":"flags cycleRolloverActive within ± 30 days of election","duration":0.38891799999998966,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition flags cycleRolloverActive outside ± 30 days as false","status":"passed","title":"flags cycleRolloverActive outside ± 30 days as false","duration":0.3554849999999874,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]}],"startTime":1787953894577,"endTime":1787953894592.3555,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/horizon-context.test.ts"},{"assertionResults":[{"ancestorTitles":["hreflang validation across all HTML files"],"fullName":"hreflang validation across all HTML files should find HTML files with hreflang links","status":"passed","title":"should find HTML files with hreflang links","duration":3.6082360000000335,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","absolute URLs"],"fullName":"hreflang validation across all HTML files absolute URLs all hreflang links must use absolute URLs (not relative)","status":"passed","title":"all hreflang links must use absolute URLs (not relative)","duration":0.4352650000000722,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","x-default entry"],"fullName":"hreflang validation across all HTML files x-default entry all multi-language pages must include hreflang=\"x-default\"","status":"passed","title":"all multi-language pages must include hreflang=\"x-default\"","duration":0.49434499999915715,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","valid hreflang codes"],"fullName":"hreflang validation across all HTML files valid hreflang codes all hreflang codes must be valid BCP-47 codes (Norwegian = nb, not no)","status":"passed","title":"all hreflang codes must be valid BCP-47 codes (Norwegian = nb, not no)","duration":0.36284899999918707,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","hreflang href format"],"fullName":"hreflang validation across all HTML files hreflang href format all absolute hreflang URLs must use the correct base URL","status":"passed","title":"all absolute hreflang URLs must use the correct base URL","duration":0.43195900000137044,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["renderHreflangBlock helper"],"fullName":"renderHreflangBlock helper generates absolute URLs with BASE_URL prefix","status":"passed","title":"generates absolute URLs with BASE_URL prefix","duration":23.540281999999934,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderHreflangBlock helper"],"fullName":"renderHreflangBlock helper uses nb hreflang for Norwegian (no) file suffix","status":"passed","title":"uses nb hreflang for Norwegian (no) file suffix","duration":0.6322540000001027,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) all root HTML pages should have hreflang links","status":"passed","title":"all root HTML pages should have hreflang links","duration":89.13662399999885,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) root pages should have absolute hreflang URLs","status":"passed","title":"root pages should have absolute hreflang URLs","duration":64.5268329999999,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) root pages should have x-default","status":"passed","title":"root pages should have x-default","duration":51.66113099999893,"failureMessages":[],"location":{"line":264,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) all dashboard pages should have hreflang links","status":"passed","title":"all dashboard pages should have hreflang links","duration":9.271031000000221,"failureMessages":[],"location":{"line":280,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) dashboard pages should have absolute hreflang URLs","status":"passed","title":"dashboard pages should have absolute hreflang URLs","duration":8.732451999998375,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) dashboard pages should have x-default","status":"passed","title":"dashboard pages should have x-default","duration":9.176483999999618,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard index pages (dashboard/)"],"fullName":"hreflang coverage by page type dashboard index pages (dashboard/) all dashboard index pages should have hreflang links","status":"passed","title":"all dashboard index pages should have hreflang links","duration":1.4154099999996106,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard index pages (dashboard/)"],"fullName":"hreflang coverage by page type dashboard index pages (dashboard/) dashboard index pages should have absolute hreflang URLs","status":"passed","title":"dashboard index pages should have absolute hreflang URLs","duration":1.5082339999989927,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","news article pages"],"fullName":"hreflang coverage by page type news article pages news articles with hreflang should have absolute URLs and x-default","status":"passed","title":"news articles with hreflang should have absolute URLs and x-default","duration":12.067587999999887,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]}],"startTime":1787953803675,"endTime":1787953803953.0676,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/hreflang-validation.test.ts"},{"assertionResults":[{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape ampersands","status":"passed","title":"should escape ampersands","duration":4.024917000000016,"failureMessages":[],"location":{"line":9,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape angle brackets","status":"passed","title":"should escape angle brackets","duration":0.5319160000000238,"failureMessages":[],"location":{"line":13,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape double quotes","status":"passed","title":"should escape double quotes","duration":0.509884999999997,"failureMessages":[],"location":{"line":19,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape single quotes","status":"passed","title":"should escape single quotes","duration":0.3819459999999708,"failureMessages":[],"location":{"line":23,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle null input","status":"passed","title":"should handle null input","duration":0.5342909999999961,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle undefined input","status":"passed","title":"should handle undefined input","duration":0.3692219999999793,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle empty string","status":"passed","title":"should handle empty string","duration":0.3755729999999744,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle numeric input via String coercion","status":"passed","title":"should handle numeric input via String coercion","duration":0.3327129999999556,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle strings with no special characters","status":"passed","title":"should handle strings with no special characters","duration":0.590816000000018,"failureMessages":[],"location":{"line":43,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape all special characters together","status":"passed","title":"should escape all special characters together","duration":0.35797999999999774,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode Swedish numeric entities to UTF-8","status":"passed","title":"should decode Swedish numeric entities to UTF-8","duration":0.7387929999999869,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode ä ö å entities","status":"passed","title":"should decode ä ö å entities","duration":0.5656089999999949,"failureMessages":[],"location":{"line":59,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode uppercase Swedish entities","status":"passed","title":"should decode uppercase Swedish entities","duration":0.3938180000000102,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode em-dash and en-dash entities","status":"passed","title":"should decode em-dash and en-dash entities","duration":0.560058999999967,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode hex entities","status":"passed","title":"should decode hex entities","duration":0.44587400000000343,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode named entities","status":"passed","title":"should decode named entities","duration":0.5384180000000356,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode mixed content with entities and regular text","status":"passed","title":"should decode mixed content with entities and regular text","duration":0.3669170000000008,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle text with no entities","status":"passed","title":"should handle text with no entities","duration":0.3468599999999924,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle null input","status":"passed","title":"should handle null input","duration":0.4244850000000042,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle undefined input","status":"passed","title":"should handle undefined input","duration":0.35339100000004464,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle empty string","status":"passed","title":"should handle empty string","duration":0.42810200000002396,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should preserve valid UTF-8 characters","status":"passed","title":"should preserve valid UTF-8 characters","duration":0.3712850000000003,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode author name with entities","status":"passed","title":"should decode author name with entities","duration":0.4430889999999863,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode article title with multiple entity types","status":"passed","title":"should decode article title with multiple entity types","duration":0.5285890000000109,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]}],"startTime":1787953901102,"endTime":1787953901116.5286,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/html-utils.test.ts"},{"assertionResults":[{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":4.317352000000028,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete every entry has non-empty nativeName, flag, locale, hreflang","status":"passed","title":"every entry has non-empty nativeName, flag, locale, hreflang","duration":1.6021590000000288,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete RTL languages have dir=\"rtl\"","status":"passed","title":"RTL languages have dir=\"rtl\"","duration":0.6033390000000054,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete LTR languages have dir=\"ltr\"","status":"passed","title":"LTR languages have dir=\"ltr\"","duration":0.6415920000000597,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete Norwegian uses BCP-47 \"nb\" for hreflang","status":"passed","title":"Norwegian uses BCP-47 \"nb\" for hreflang","duration":0.4387810000000627,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete every language has complete translations object","status":"passed","title":"every language has complete translations object","duration":8.002292000000011,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete non-EN articleEnglishCoverageHeading is translated (not EN copy-paste)","status":"passed","title":"non-EN articleEnglishCoverageHeading is translated (not EN copy-paste)","duration":1.6345000000000027,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness returns a non-null ChromeStrings for every language","status":"passed","title":"returns a non-null ChromeStrings for every language","duration":0.6473719999999048,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness fallback to English for unknown language codes","status":"passed","title":"fallback to English for unknown language codes","duration":0.5560110000000122,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness every language has non-empty sample chrome strings","status":"passed","title":"every language has non-empty sample chrome strings","duration":1.9745770000000675,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness non-EN languages have translated headerTagline (no EN leak)","status":"passed","title":"non-EN languages have translated headerTagline (no EN leak)","duration":0.8840850000000273,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness non-EN languages have translated heroSubtitle (no EN leak)","status":"passed","title":"non-EN languages have translated heroSubtitle (no EN leak)","duration":0.691765999999916,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback returns translated label for known types in every language","status":"passed","title":"returns translated label for known types in every language","duration":0.9094619999999622,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback falls back to English for unknown type IDs (all languages get same fallback)","status":"passed","title":"falls back to English for unknown type IDs (all languages get same fallback)","duration":0.5840930000000526,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback every registered type has all 14 languages","status":"passed","title":"every registered type has all 14 languages","duration":3.046944000000053,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback en: produces non-empty title from localized input","status":"passed","title":"en: produces non-empty title from localized input","duration":0.8363959999999224,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback en: falls back gracefully when title is empty","status":"passed","title":"en: falls back gracefully when title is empty","duration":0.6836399999999685,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback sv: produces non-empty title from localized input","status":"passed","title":"sv: produces non-empty title from localized input","duration":0.4035660000000689,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback sv: falls back gracefully when title is empty","status":"passed","title":"sv: falls back gracefully when title is empty","duration":0.37549300000000585,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback da: produces non-empty title from localized input","status":"passed","title":"da: produces non-empty title from localized input","duration":0.31679300000007515,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback da: falls back gracefully when title is empty","status":"passed","title":"da: falls back gracefully when title is empty","duration":0.49709999999993215,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback no: produces non-empty title from localized input","status":"passed","title":"no: produces non-empty title from localized input","duration":0.31950799999992796,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback no: falls back gracefully when title is empty","status":"passed","title":"no: falls back gracefully when title is empty","duration":0.33802300000002106,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fi: produces non-empty title from localized input","status":"passed","title":"fi: produces non-empty title from localized input","duration":0.34490500000003976,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fi: falls back gracefully when title is empty","status":"passed","title":"fi: falls back gracefully when title is empty","duration":0.32931700000006003,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback de: produces non-empty title from localized input","status":"passed","title":"de: produces non-empty title from localized input","duration":0.3090589999999338,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback de: falls back gracefully when title is empty","status":"passed","title":"de: falls back gracefully when title is empty","duration":0.3937870000000885,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fr: produces non-empty title from localized input","status":"passed","title":"fr: produces non-empty title from localized input","duration":0.35328100000003815,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fr: falls back gracefully when title is empty","status":"passed","title":"fr: falls back gracefully when title is empty","duration":0.343913999999927,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback es: produces non-empty title from localized input","status":"passed","title":"es: produces non-empty title from localized input","duration":0.3739699999999857,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback es: falls back gracefully when title is empty","status":"passed","title":"es: falls back gracefully when title is empty","duration":0.5313540000000785,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback nl: produces non-empty title from localized input","status":"passed","title":"nl: produces non-empty title from localized input","duration":0.7031259999999975,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback nl: falls back gracefully when title is empty","status":"passed","title":"nl: falls back gracefully when title is empty","duration":0.41339400000003934,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ar: produces non-empty title from localized input","status":"passed","title":"ar: produces non-empty title from localized input","duration":0.7166620000000421,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ar: falls back gracefully when title is empty","status":"passed","title":"ar: falls back gracefully when title is empty","duration":0.4748780000001034,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback he: produces non-empty title from localized input","status":"passed","title":"he: produces non-empty title from localized input","duration":0.4018019999999751,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback he: falls back gracefully when title is empty","status":"passed","title":"he: falls back gracefully when title is empty","duration":0.40168199999993703,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ja: produces non-empty title from localized input","status":"passed","title":"ja: produces non-empty title from localized input","duration":0.46255600000006325,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ja: falls back gracefully when title is empty","status":"passed","title":"ja: falls back gracefully when title is empty","duration":0.5933710000000474,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ko: produces non-empty title from localized input","status":"passed","title":"ko: produces non-empty title from localized input","duration":0.4884140000000343,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ko: falls back gracefully when title is empty","status":"passed","title":"ko: falls back gracefully when title is empty","duration":0.48095999999998185,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback zh: produces non-empty title from localized input","status":"passed","title":"zh: produces non-empty title from localized input","duration":0.4560840000000326,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback zh: falls back gracefully when title is empty","status":"passed","title":"zh: falls back gracefully when title is empty","duration":0.5581549999999424,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback CJK titles respect 45-char budget","status":"passed","title":"CJK titles respect 45-char budget","duration":0.64822300000003,"failureMessages":[],"location":{"line":266,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback RTL titles respect 60-char budget","status":"passed","title":"RTL titles respect 60-char budget","duration":0.7690900000000056,"failureMessages":[],"location":{"line":280,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback Latin LTR titles respect 70-char budget","status":"passed","title":"Latin LTR titles respect 70-char budget","duration":0.8580860000000712,"failureMessages":[],"location":{"line":294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets en: produces non-empty description","status":"passed","title":"en: produces non-empty description","duration":1.5126719999999523,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets en: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"en: synthesises a non-empty fallback from the title for an empty description","duration":0.77647300000001,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets sv: produces non-empty description","status":"passed","title":"sv: produces non-empty description","duration":0.7474690000000237,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets sv: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"sv: synthesises a non-empty fallback from the title for an empty description","duration":0.7367189999999937,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets da: produces non-empty description","status":"passed","title":"da: produces non-empty description","duration":0.7122739999999794,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets da: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"da: synthesises a non-empty fallback from the title for an empty description","duration":0.7381320000000642,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets no: produces non-empty description","status":"passed","title":"no: produces non-empty description","duration":0.7423800000000256,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets no: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"no: synthesises a non-empty fallback from the title for an empty description","duration":0.725447000000031,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fi: produces non-empty description","status":"passed","title":"fi: produces non-empty description","duration":0.7883160000000089,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fi: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"fi: synthesises a non-empty fallback from the title for an empty description","duration":0.7400149999999712,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets de: produces non-empty description","status":"passed","title":"de: produces non-empty description","duration":0.8068099999999276,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets de: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"de: synthesises a non-empty fallback from the title for an empty description","duration":0.930531999999971,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fr: produces non-empty description","status":"passed","title":"fr: produces non-empty description","duration":0.8657709999999952,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fr: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"fr: synthesises a non-empty fallback from the title for an empty description","duration":0.8347730000000411,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets es: produces non-empty description","status":"passed","title":"es: produces non-empty description","duration":0.8611419999999725,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets es: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"es: synthesises a non-empty fallback from the title for an empty description","duration":0.902198999999996,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets nl: produces non-empty description","status":"passed","title":"nl: produces non-empty description","duration":0.863666999999964,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets nl: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"nl: synthesises a non-empty fallback from the title for an empty description","duration":1.088647999999921,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ar: produces non-empty description","status":"passed","title":"ar: produces non-empty description","duration":1.5515349999999444,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ar: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ar: synthesises a non-empty fallback from the title for an empty description","duration":1.0176950000000033,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets he: produces non-empty description","status":"passed","title":"he: produces non-empty description","duration":1.0139380000000529,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets he: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"he: synthesises a non-empty fallback from the title for an empty description","duration":1.1805500000000393,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ja: produces non-empty description","status":"passed","title":"ja: produces non-empty description","duration":1.1925529999999753,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ja: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ja: synthesises a non-empty fallback from the title for an empty description","duration":1.1391929999999775,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ko: produces non-empty description","status":"passed","title":"ko: produces non-empty description","duration":1.0053820000000542,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ko: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ko: synthesises a non-empty fallback from the title for an empty description","duration":1.0542639999999892,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets zh: produces non-empty description","status":"passed","title":"zh: produces non-empty description","duration":1.0198689999999715,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets zh: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"zh: synthesises a non-empty fallback from the title for an empty description","duration":1.0837690000000748,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets CJK descriptions respect 120-char budget","status":"passed","title":"CJK descriptions respect 120-char budget","duration":1.3166350000000193,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets RTL descriptions respect 170-char budget","status":"passed","title":"RTL descriptions respect 170-char budget","duration":1.4024060000000418,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets Latin LTR descriptions respect 200-char budget","status":"passed","title":"Latin LTR descriptions respect 200-char budget","duration":1.4102289999999584,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy en: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"en: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":2.1148889999999483,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy sv: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"sv: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.5522760000000062,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy da: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"da: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3750340000000278,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy no: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"no: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.2695169999999507,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy fi: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"fi: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3478730000000496,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy de: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"de: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.6330770000000712,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy fr: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"fr: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.6988300000000436,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy es: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"es: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3267439999999624,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy nl: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"nl: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3756459999999606,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ar: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ar: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.7853619999999637,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy he: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"he: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.346420999999964,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ja: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ja: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3823680000000422,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ko: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ko: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.405571000000009,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy zh: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"zh: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.43301299999996,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy non-EN keywords do NOT contain English-only tokens","status":"passed","title":"non-EN keywords do NOT contain English-only tokens","duration":2.6891440000000557,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy keywords with briefEntities seeded correctly for all languages","status":"passed","title":"keywords with briefEntities seeded correctly for all languages","duration":3.3262569999999414,"failureMessages":[],"location":{"line":420,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages returns English unchanged for lang=en","status":"passed","title":"returns English unchanged for lang=en","duration":3.035131999999976,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages sv: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"sv: merges with empty localized markdown (pure EN fallback)","duration":8.928626000000008,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages sv: merges localized body with English coverage boundary","status":"passed","title":"sv: merges localized body with English coverage boundary","duration":3.1114350000000286,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages da: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"da: merges with empty localized markdown (pure EN fallback)","duration":5.305732999999918,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages da: merges localized body with English coverage boundary","status":"passed","title":"da: merges localized body with English coverage boundary","duration":1.8644600000000082,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages no: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"no: merges with empty localized markdown (pure EN fallback)","duration":1.5966000000000804,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages no: merges localized body with English coverage boundary","status":"passed","title":"no: merges localized body with English coverage boundary","duration":2.066438000000062,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fi: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"fi: merges with empty localized markdown (pure EN fallback)","duration":1.8085459999999784,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fi: merges localized body with English coverage boundary","status":"passed","title":"fi: merges localized body with English coverage boundary","duration":1.992840000000001,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages de: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"de: merges with empty localized markdown (pure EN fallback)","duration":1.8592200000000503,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages de: merges localized body with English coverage boundary","status":"passed","title":"de: merges localized body with English coverage boundary","duration":1.6431870000000117,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fr: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"fr: merges with empty localized markdown (pure EN fallback)","duration":1.6103140000000167,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fr: merges localized body with English coverage boundary","status":"passed","title":"fr: merges localized body with English coverage boundary","duration":2.130529000000024,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages es: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"es: merges with empty localized markdown (pure EN fallback)","duration":1.4770249999999123,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages es: merges localized body with English coverage boundary","status":"passed","title":"es: merges localized body with English coverage boundary","duration":1.6125789999999824,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages nl: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"nl: merges with empty localized markdown (pure EN fallback)","duration":1.559570000000008,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages nl: merges localized body with English coverage boundary","status":"passed","title":"nl: merges localized body with English coverage boundary","duration":1.786465000000021,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ar: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ar: merges with empty localized markdown (pure EN fallback)","duration":1.6122980000000098,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ar: merges localized body with English coverage boundary","status":"passed","title":"ar: merges localized body with English coverage boundary","duration":2.417204999999967,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages he: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"he: merges with empty localized markdown (pure EN fallback)","duration":1.6621020000000044,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages he: merges localized body with English coverage boundary","status":"passed","title":"he: merges localized body with English coverage boundary","duration":1.6807369999999082,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ja: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ja: merges with empty localized markdown (pure EN fallback)","duration":1.6365240000000085,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ja: merges localized body with English coverage boundary","status":"passed","title":"ja: merges localized body with English coverage boundary","duration":1.718166999999994,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ko: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ko: merges with empty localized markdown (pure EN fallback)","duration":1.643626999999924,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ko: merges localized body with English coverage boundary","status":"passed","title":"ko: merges localized body with English coverage boundary","duration":1.7977359999999862,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages zh: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"zh: merges with empty localized markdown (pure EN fallback)","duration":1.7511580000000322,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages zh: merges localized body with English coverage boundary","status":"passed","title":"zh: merges localized body with English coverage boundary","duration":1.8120720000000574,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages buildEnglishCoverageBoundary produces unique heading per language","status":"passed","title":"buildEnglishCoverageBoundary produces unique heading per language","duration":2.1504659999999376,"failureMessages":[],"location":{"line":507,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages CLEAR_FILTERS_LABELS has entry for every language","status":"passed","title":"CLEAR_FILTERS_LABELS has entry for every language","duration":1.8658530000000155,"failureMessages":[],"location":{"line":524,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages RECENCY_LABELS has entry for every language with all 3 keys","status":"passed","title":"RECENCY_LABELS has entry for every language with all 3 keys","duration":2.8082979999999225,"failureMessages":[],"location":{"line":530,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages HERO_METRIC_LABELS has entry for every language with all 4 keys","status":"passed","title":"HERO_METRIC_LABELS has entry for every language with all 4 keys","duration":2.3627440000000206,"failureMessages":[],"location":{"line":540,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages localizeClearFilters falls back to English for unknown language","status":"passed","title":"localizeClearFilters falls back to English for unknown language","duration":1.8444230000000061,"failureMessages":[],"location":{"line":551,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages buildRecencyLabels falls back to English for unknown language","status":"passed","title":"buildRecencyLabels falls back to English for unknown language","duration":1.7915540000000192,"failureMessages":[],"location":{"line":555,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages heroMetricLabels falls back to English for unknown language","status":"passed","title":"heroMetricLabels falls back to English for unknown language","duration":1.9143440000000282,"failureMessages":[],"location":{"line":562,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages non-EN recency labels are translated (differ from EN)","status":"passed","title":"non-EN recency labels are translated (differ from EN)","duration":2.2686169999999493,"failureMessages":[],"location":{"line":568,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages non-EN hero metric labels are translated (differ from EN)","status":"passed","title":"non-EN hero metric labels are translated (differ from EN)","duration":2.557136999999898,"failureMessages":[],"location":{"line":580,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization maps \"no\" to \"nb\"","status":"passed","title":"maps \"no\" to \"nb\"","duration":2.5707420000001093,"failureMessages":[],"location":{"line":592,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization passes through other codes unchanged","status":"passed","title":"passes through other codes unchanged","duration":2.269278999999983,"failureMessages":[],"location":{"line":596,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization uses fallback for undefined/empty input","status":"passed","title":"uses fallback for undefined/empty input","duration":2.45307200000002,"failureMessages":[],"location":{"line":602,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for DE vs. EN on same article","status":"passed","title":"produces distinct translated keywords for DE vs. EN on same article","duration":2.507163999999989,"failureMessages":[],"location":{"line":611,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for JA vs. EN on same article","status":"passed","title":"produces distinct translated keywords for JA vs. EN on same article","duration":2.3873499999999694,"failureMessages":[],"location":{"line":638,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for AR vs. EN on same article","status":"passed","title":"produces distinct translated keywords for AR vs. EN on same article","duration":2.402967999999987,"failureMessages":[],"location":{"line":653,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) articleTypeIcon returns an icon for every known type (language-neutral)","status":"passed","title":"articleTypeIcon returns an icon for every known type (language-neutral)","duration":3.088702000000012,"failureMessages":[],"location":{"line":668,"column":3},"meta":{},"tags":[]}],"startTime":1787953662433,"endTime":1787953662633.0886,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/i18n-fallback-all-languages.test.ts"},{"assertionResults":[{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants runs image optimization before page generation in the build pipeline","status":"passed","title":"runs image optimization before page generation in the build pipeline","duration":4.314527999999996,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants keeps every generated variant present with the expected dimensions","status":"passed","title":"keeps every generated variant present with the expected dimensions","duration":24.366424999999992,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants serves every local HTML image (excluding generated news/ pages) through srcset or a picture fallback","status":"passed","title":"serves every local HTML image (excluding generated news/ pages) through srcset or a picture fallback","duration":365.96271200000007,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants keeps all local HTML srcset image URLs (excluding generated news/ pages) backed by generated files","status":"passed","title":"keeps all local HTML srcset image URLs (excluding generated news/ pages) backed by generated files","duration":445.70853599999987,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["S3 image content types"],"fullName":"S3 image content types deploys each supported image format with explicit MIME metadata","status":"passed","title":"deploys each supported image format with explicit MIME metadata","duration":1.1253679999999804,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["S3 image content types"],"fullName":"S3 image content types can repair AVIF MIME metadata on existing bucket objects","status":"passed","title":"can repair AVIF MIME metadata on existing bucket objects","duration":0.6640330000000176,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]}],"startTime":1787953871569,"endTime":1787953872411.664,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/image-optimization.test.ts"},{"assertionResults":[{"ancestorTitles":["imf-codes","COUNTRY_CODES"],"fullName":"imf-codes COUNTRY_CODES exposes Nordic + German + EU peer set in ISO-3","status":"passed","title":"exposes Nordic + German + EU peer set in ISO-3","duration":3.903749000000005,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA covers the full Nordic + DE peer set","status":"passed","title":"covers the full Nordic + DE peer set","duration":0.79618099999999,"failureMessages":[],"location":{"line":34,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA is deep-frozen (immutable)","status":"passed","title":"is deep-frozen (immutable)","duration":0.42782099999999446,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA has a consistent inverse map","status":"passed","title":"has a consistent inverse map","duration":0.8121009999999842,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toDatamapperCode"],"fullName":"imf-codes toDatamapperCode returns ISO-3 codes uppercase, trimmed","status":"passed","title":"returns ISO-3 codes uppercase, trimmed","duration":0.4677149999999983,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toDatamapperCode"],"fullName":"imf-codes toDatamapperCode passes through EU / EURO aggregates","status":"passed","title":"passes through EU / EURO aggregates","duration":0.5310439999999517,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode converts ISO-3 to 3-digit IMF AREA code","status":"passed","title":"converts ISO-3 to 3-digit IMF AREA code","duration":0.5706789999999842,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode throws for unknown ISO-3 instead of silently dropping the request","status":"passed","title":"throws for unknown ISO-3 instead of silently dropping the request","duration":1.2292620000000056,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode throws for empty / whitespace input","status":"passed","title":"throws for empty / whitespace input","duration":0.6446469999999636,"failureMessages":[],"location":{"line":74,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","isKnownIso3"],"fullName":"imf-codes isKnownIso3 returns true for mapped codes","status":"passed","title":"returns true for mapped codes","duration":0.5016990000000305,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","isKnownIso3"],"fullName":"imf-codes isKnownIso3 returns false for unknown codes","status":"passed","title":"returns false for unknown codes","duration":0.39789500000000544,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","COUNTRY_NAMES_EN"],"fullName":"imf-codes COUNTRY_NAMES_EN carries English display names for the peer set","status":"passed","title":"carries English display names for the peer set","duration":0.40818500000000313,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","COUNTRY_NAMES_EN"],"fullName":"imf-codes COUNTRY_NAMES_EN covers the expanded Eurozone comparator set (BEL / AUT / IRL)","status":"passed","title":"covers the expanded Eurozone comparator set (BEL / AUT / IRL)","duration":0.3507769999999937,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes returns every ISO-3 code in ISO3_TO_IMF_AREA, sorted","status":"passed","title":"returns every ISO-3 code in ISO3_TO_IMF_AREA, sorted","duration":1.1391229999999837,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes includes the Nordic + DE peer set","status":"passed","title":"includes the Nordic + DE peer set","duration":1.2688459999999964,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes is frozen (immutable)","status":"passed","title":"is frozen (immutable)","duration":0.41212200000001076,"failureMessages":[],"location":{"line":121,"column":5},"meta":{},"tags":[]}],"startTime":1787953903959,"endTime":1787953903973.412,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-codes.test.ts"},{"assertionResults":[{"ancestorTitles":["parseVintage"],"fullName":"parseVintage parses a canonical WEO tag","status":"passed","title":"parses a canonical WEO tag","duration":4.449310000000025,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseVintage"],"fullName":"parseVintage parses a Fiscal Monitor tag","status":"passed","title":"parses a Fiscal Monitor tag","duration":0.7501249999999686,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseVintage"],"fullName":"parseVintage returns null on malformed input","status":"passed","title":"returns null on malformed input","duration":0.7418890000000147,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths reports 0 months for the current vintage","status":"passed","title":"reports 0 months for the current vintage","duration":0.6758560000000102,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths reports the gap in months for older vintages","status":"passed","title":"reports the gap in months for older vintages","duration":0.4893260000000055,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths clamps future-dated vintages to 0","status":"passed","title":"clamps future-dated vintages to 0","duration":0.6200110000000336,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths returns +Infinity for malformed vintages","status":"passed","title":"returns +Infinity for malformed vintages","duration":0.4264479999999935,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports ok=true on all three probes when the client succeeds","status":"passed","title":"reports ok=true on all three probes when the client succeeds","duration":2.4769469999999956,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes captures network failures into ok=false + error","status":"passed","title":"captures network failures into ok=false + error","duration":1.0491240000000062,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks empty WEO/FM series as not ok (defensive against silent schema drift)","status":"passed","title":"marks empty WEO/FM series as not ok (defensive against silent schema drift)","duration":0.8020209999999679,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks non-object SDMX responses as not ok","status":"passed","title":"marks non-object SDMX responses as not ok","duration":0.8074019999999678,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks SDMX 200-but-empty-series responses as not ok with sdmx-empty-series (silent-drift guard)","status":"passed","title":"marks SDMX 200-but-empty-series responses as not ok with sdmx-empty-series (silent-drift guard)","duration":0.5806869999999549,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured when key missing AND endpoint returns 401/403","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured when key missing AND endpoint returns 401/403","duration":0.6737210000000005,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured on 403 when key missing","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured on 403 when key missing","duration":0.6678809999999658,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured on 404 (real APIM gateway response when no key sent)","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured on 404 (real APIM gateway response when no key sent)","duration":0.6322630000000231,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes preserves the raw SDMX error when a key IS configured (so ops can see real cause)","status":"passed","title":"preserves the raw SDMX error when a key IS configured (so ops can see real cause)","duration":1.023727000000008,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes preserves a non-auth SDMX failure (e.g. 503) even when key missing","status":"passed","title":"preserves a non-auth SDMX failure (e.g. 503) even when key missing","duration":0.6880570000000148,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes enforces PROBE_TIMEOUT_MS so a hung IMF endpoint cannot starve the composite-action budget","status":"passed","title":"enforces PROBE_TIMEOUT_MS so a hung IMF endpoint cannot starve the composite-action budget","duration":4.1031920000000355,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=ok with no warning block when fresh + all probes ok","status":"passed","title":"returns status=ok with no warning block when fresh + all probes ok","duration":0.8289519999999584,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=stale-vintage with ℹ️ annotation when vintage > 6 months","status":"passed","title":"returns status=stale-vintage with ℹ️ annotation when vintage > 6 months","duration":0.8669529999999668,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=degraded with ℹ️ block when only the auxiliary SDMX probe failed","status":"passed","title":"returns status=degraded with ℹ️ block when only the auxiliary SDMX probe failed","duration":0.8670930000000681,"failureMessages":[],"location":{"line":317,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=unavailable with ⚠️ block when a critical WEO/FM probe failed","status":"passed","title":"returns status=unavailable with ⚠️ block when a critical WEO/FM probe failed","duration":0.6672190000000455,"failureMessages":[],"location":{"line":329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport treats malformed vintage as definitely stale","status":"passed","title":"treats malformed vintage as definitely stale","duration":0.550200000000018,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatUnavailableWarning"],"fullName":"formatUnavailableWarning renders failed probes with their dataflow + error in the warning text","status":"passed","title":"renders failed probes with their dataflow + error in the warning text","duration":0.6989690000000337,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation mentions the vintage tag and the age in months","status":"passed","title":"mentions the vintage tag and the age in months","duration":0.5979900000000953,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation uses STALE_VINTAGE_MAX_MONTHS in the heading instead of a hardcoded number","status":"passed","title":"uses STALE_VINTAGE_MAX_MONTHS in the heading instead of a hardcoded number","duration":0.5415649999999914,"failureMessages":[],"location":{"line":375,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation renders -1 (sentinel for malformed vintage) as \"unknown age\" instead of a literal \"-1 months\"","status":"passed","title":"renders -1 (sentinel for malformed vintage) as \"unknown age\" instead of a literal \"-1 months\"","duration":0.5217370000000301,"failureMessages":[],"location":{"line":380,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatDegradedWarning"],"fullName":"formatDegradedWarning renders failed auxiliary probes without saying IMF is unavailable","status":"passed","title":"renders failed auxiliary probes without saying IMF is unavailable","duration":0.6331959999999981,"failureMessages":[],"location":{"line":389,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport writes imf-context.json on success and does NOT write the unavailable flag","status":"passed","title":"writes imf-context.json on success and does NOT write the unavailable flag","duration":1.267513000000008,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport writes BOTH imf-context.json AND imf-unavailable.flag on connectivity failure","status":"passed","title":"writes BOTH imf-context.json AND imf-unavailable.flag on connectivity failure","duration":1.2398220000000038,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport does NOT write the unavailable flag on degraded auxiliary SDMX failure","status":"passed","title":"does NOT write the unavailable flag on degraded auxiliary SDMX failure","duration":1.4257090000000971,"failureMessages":[],"location":{"line":457,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport does NOT write the unavailable flag when status is stale-vintage (annotate, do not block)","status":"passed","title":"does NOT write the unavailable flag when status is stale-vintage (annotate, do not block)","duration":1.154991999999993,"failureMessages":[],"location":{"line":475,"column":3},"meta":{},"tags":[]}],"startTime":1787953679676,"endTime":1787953679710.155,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-connectivity.test.ts"},{"assertionResults":[{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue exposes the headline WEO indicators used by article workflows","status":"passed","title":"exposes the headline WEO indicators used by article workflows","duration":4.315208999999982,"failureMessages":[],"location":{"line":25,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue marks every WEO/FM indicator as projection-capable","status":"passed","title":"marks every WEO/FM indicator as projection-capable","duration":0.9359119999999734,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue has policyAreas and committees for every entry","status":"passed","title":"has policyAreas and committees for every entry","duration":2.2168000000000347,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains returns fiscal-policy indicators for \"fiscal policy\"","status":"passed","title":"returns fiscal-policy indicators for \"fiscal policy\"","duration":1.4055309999999963,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains is case-insensitive","status":"passed","title":"is case-insensitive","duration":1.3620910000000208,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains returns an empty list for an empty domain array","status":"passed","title":"returns an empty list for an empty domain array","duration":0.5833519999999908,"failureMessages":[],"location":{"line":69,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains matches substrings defensively","status":"passed","title":"matches substrings defensively","duration":0.5587859999999978,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee returns FiU (finance) headline indicators","status":"passed","title":"returns FiU (finance) headline indicators","duration":0.692136000000005,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee returns AU (labour market) indicators","status":"passed","title":"returns AU (labour market) indicators","duration":0.6873870000000011,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.6008139999999571,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_NORDIC_PEERS"],"fullName":"imf-context IMF_NORDIC_PEERS contains the SE/DK/NO/FI/DE peer set","status":"passed","title":"contains the SE/DK/NO/FI/DE peer set","duration":0.6781700000000228,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_NORDIC_PEERS"],"fullName":"imf-context IMF_NORDIC_PEERS is immutable","status":"passed","title":"is immutable","duration":0.4864200000000096,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCountryNameEn"],"fullName":"imf-context imfCountryNameEn returns English display names","status":"passed","title":"returns English display names","duration":0.6275549999999726,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCountryNameEn"],"fullName":"imf-context imfCountryNameEn falls back to the upper-cased code when unknown","status":"passed","title":"falls back to the upper-cased code when unknown","duration":0.6416209999999865,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCitation"],"fullName":"imf-context imfCitation joins database and indicator with a colon","status":"passed","title":"joins database and indicator with a colon","duration":0.7719849999999724,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns the matching indicator for a known (database, id) pair","status":"passed","title":"returns the matching indicator for a known (database, id) pair","duration":0.6702450000000226,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode keeps strict ImfDatabase literal callers backwards compatible","status":"passed","title":"keeps strict ImfDatabase literal callers backwards compatible","duration":0.4699590000000171,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode is case-insensitive on both arguments","status":"passed","title":"is case-insensitive on both arguments","duration":0.4869520000000307,"failureMessages":[],"location":{"line":143,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode trims whitespace before matching","status":"passed","title":"trims whitespace before matching","duration":0.47043100000001914,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns undefined for an unknown indicator id","status":"passed","title":"returns undefined for an unknown indicator id","duration":0.5088729999999941,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns undefined when database and id do not co-occur","status":"passed","title":"returns undefined when database and id do not co-occur","duration":0.6117150000000038,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode resolves GFS_COFOG committee-aligned spending indicators (post-2026-05 codes)","status":"passed","title":"resolves GFS_COFOG committee-aligned spending indicators (post-2026-05 codes)","duration":0.669885000000022,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation parses a canonical DATABASE:INDICATOR citation","status":"passed","title":"parses a canonical DATABASE:INDICATOR citation","duration":0.6398179999999911,"failureMessages":[],"location":{"line":172,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation normalizes citation database prefixes without unsafe casts","status":"passed","title":"normalizes citation database prefixes without unsafe casts","duration":0.5180000000000291,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation round-trips imfCitation for every catalogue entry","status":"passed","title":"round-trips imfCitation for every catalogue entry","duration":0.9689239999999586,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation returns undefined for malformed citations","status":"passed","title":"returns undefined for malformed citations","duration":0.7339339999999765,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfDatabasesInUse"],"fullName":"imf-context getImfDatabasesInUse includes the IMF databases actually referenced by the catalogue","status":"passed","title":"includes the IMF databases actually referenced by the catalogue","duration":0.7447940000000131,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfDatabasesInUse"],"fullName":"imf-context getImfDatabasesInUse never contains databases absent from IMF_INDICATORS","status":"passed","title":"never contains databases absent from IMF_INDICATORS","duration":0.7012630000000399,"failureMessages":[],"location":{"line":208,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix keys are UPPER-CASE committee codes","status":"passed","title":"keys are UPPER-CASE committee codes","duration":1.0428019999999947,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix FIU surfaces the headline macro+fiscal indicator set","status":"passed","title":"FIU surfaces the headline macro+fiscal indicator set","duration":0.762346999999977,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix FÖU surfaces COFOG GF02_T (defence spending, post-2026-05 code)","status":"passed","title":"FÖU surfaces COFOG GF02_T (defence spending, post-2026-05 code)","duration":0.929128999999989,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix each entry is sorted and deduplicated","status":"passed","title":"each entry is sorted and deduplicated","duration":1.5998050000000035,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix covers every committee referenced by any indicator","status":"passed","title":"covers every committee referenced by any indicator","duration":0.8783540000000016,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","listImfCitations"],"fullName":"imf-context listImfCitations returns every DATABASE:INDICATOR citation, sorted and frozen","status":"passed","title":"returns every DATABASE:INDICATOR citation, sorted and frozen","duration":0.8642480000000319,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","listImfCitations"],"fullName":"imf-context listImfCitations citations are unique","status":"passed","title":"citations are unique","duration":0.6036700000000224,"failureMessages":[],"location":{"line":268,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","connectivity pre-flight integration"],"fullName":"imf-context connectivity pre-flight integration exposes the pre-flight surface that workflows depend on","status":"passed","title":"exposes the pre-flight surface that workflows depend on","duration":5.12392600000004,"failureMessages":[],"location":{"line":281,"column":5},"meta":{},"tags":[]}],"startTime":1787953824824,"endTime":1787953824861.124,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-context.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchWeoPayload"],"fullName":"fetchWeoPayload retries transient failures and succeeds before exhausting the budget","status":"passed","title":"retries transient failures and succeeds before exhausting the budget","duration":5.492713999999978,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWeoPayload"],"fullName":"fetchWeoPayload falls back to direct Datamapper REST when repeated empty-series failures persist","status":"passed","title":"falls back to direct Datamapper REST when repeated empty-series failures persist","duration":4.664742999999987,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]}],"startTime":1787953917575,"endTime":1787953917585.6648,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch-cli.test.ts"},{"assertionResults":[{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) identifies IMF as the authoritative economic source","status":"passed","title":"identifies IMF as the authoritative economic source","duration":3.567010000000039,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) carries a current WEO vintage tag in the standard format","status":"passed","title":"carries a current WEO vintage tag in the standard format","duration":0.5926690000000008,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) declares all 9 canonical IMF SDMX 3.0 dataflows (post-2026-05 refactor)","status":"passed","title":"declares all 9 canonical IMF SDMX 3.0 dataflows (post-2026-05 refactor)","duration":0.6050619999999753,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) declares core policy domains with IMF-primary ownership","status":"passed","title":"declares core policy domains with IMF-primary ownership","duration":0.7119329999999877,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) lists at least the core WEO macro+fiscal headline indicators","status":"passed","title":"lists at least the core WEO macro+fiscal headline indicators","duration":0.7511470000000031,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) every indicator has the minimum required fields","status":"passed","title":"every indicator has the minimum required fields","duration":2.085555999999997,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) IMF inventory uses provider routing (no deprecation block)","status":"passed","title":"IMF inventory uses provider routing (no deprecation block)","duration":0.4124519999999734,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) committee matrix covers the main economic committees with IMF provider","status":"passed","title":"committee matrix covers the main economic committees with IMF provider","duration":0.6447979999999802,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) totalIndicators count matches the unique indicator-ID count across domains","status":"passed","title":"totalIndicators count matches the unique indicator-ID count across domains","duration":0.6305009999999811,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) is at version 4.1 or higher","status":"passed","title":"is at version 4.1 or higher","duration":0.4324699999999666,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) points at the canonical IMF inventory","status":"passed","title":"points at the canonical IMF inventory","duration":0.3788990000000467,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) master and IMF inventories use provider routing (no deprecation block)","status":"passed","title":"master and IMF inventories use provider routing (no deprecation block)","duration":0.5079709999999977,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) IMF inventory indicators use IMF dataflows directly (no `supersedes` mapping)","status":"passed","title":"IMF inventory indicators use IMF dataflows directly (no `supersedes` mapping)","duration":1.0000220000000013,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]}],"startTime":1787953849632,"endTime":1787953849644,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-inventory.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfDataPoint provider invariant"],"fullName":"ImfDataPoint provider invariant IMF data points must carry provider \"imf\" (compile-time type)","status":"passed","title":"IMF data points must carry provider \"imf\" (compile-time type)","duration":4.713625000000036,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfDataPoint provider invariant"],"fullName":"ImfDataPoint provider invariant a list of IMF data points can be sorted before WB/SCB/Riksbank points","status":"passed","title":"a list of IMF data points can be sorted before WB/SCB/Riksbank points","duration":0.7756620000000112,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCBEconomicProvenance type enforces provider \"scb\"","status":"passed","title":"SCBEconomicProvenance type enforces provider \"scb\"","duration":0.8695069999999987,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB provider is never \"imf\"","status":"passed","title":"SCB provider is never \"imf\"","duration":0.5208049999999957,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB provider is never \"riksbank\"","status":"passed","title":"SCB provider is never \"riksbank\"","duration":0.5601790000000051,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCBFetchPayload top-level provider is \"scb\"","status":"passed","title":"SCBFetchPayload top-level provider is \"scb\"","duration":0.6514500000000112,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract fetchSCBTablePayload emits provider \"scb\" on fail-soft (network down)","status":"passed","title":"fetchSCBTablePayload emits provider \"scb\" on fail-soft (network down)","duration":1.7595039999999926,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB retrieved_at is a valid ISO timestamp","status":"passed","title":"SCB retrieved_at is a valid ISO timestamp","duration":0.48448700000000144,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract RiksbankEconomicProvenance type enforces provider \"riksbank\"","status":"passed","title":"RiksbankEconomicProvenance type enforces provider \"riksbank\"","duration":0.7154499999999757,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract Riksbank provider is never \"imf\"","status":"passed","title":"Riksbank provider is never \"imf\"","duration":0.49777199999999766,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract Riksbank provider is never \"scb\"","status":"passed","title":"Riksbank provider is never \"scb\"","duration":0.5571630000000027,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract RiksbankFetchPayload top-level provider is \"riksbank\"","status":"passed","title":"RiksbankFetchPayload top-level provider is \"riksbank\"","duration":0.5353719999999953,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract fetchRiksbankPayload emits provider \"riksbank\" on HTML response","status":"passed","title":"fetchRiksbankPayload emits provider \"riksbank\" on HTML response","duration":7.000786000000005,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence inventory version is at least 4.x","status":"passed","title":"inventory version is at least 4.x","duration":0.7548329999999623,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence macro domain prefers IMF","status":"passed","title":"macro domain prefers IMF","duration":0.6189790000000244,"failureMessages":[],"location":{"line":324,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence fiscal domain prefers IMF","status":"passed","title":"fiscal domain prefers IMF","duration":0.6330449999999814,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence monetary domain prefers IMF","status":"passed","title":"monetary domain prefers IMF","duration":0.6013960000000225,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence external sector prefers IMF","status":"passed","title":"external sector prefers IMF","duration":0.6202410000000214,"failureMessages":[],"location":{"line":336,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence Sweden primary provider is SCB, not IMF","status":"passed","title":"Sweden primary provider is SCB, not IMF","duration":0.7990259999999694,"failureMessages":[],"location":{"line":340,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence IMF databases list includes the canonical SDMX 3.0 dataflows","status":"passed","title":"IMF databases list includes the canonical SDMX 3.0 dataflows","duration":2.3849739999999997,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence master inventory uses provider routing (not a deprecation block)","status":"passed","title":"master inventory uses provider routing (not a deprecation block)","duration":0.7784670000000347,"failureMessages":[],"location":{"line":356,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence master inventory carries IMF identifiers for every macro / fiscal / monetary / external / trade indicator","status":"passed","title":"master inventory carries IMF identifiers for every macro / fiscal / monetary / external / trade indicator","duration":1.0979460000000358,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence every economic indicator (provider !== \"scb\" Swedish-specific & domain ∈ macro/fiscal/monetary/external/trade) MUST come from IMF","status":"passed","title":"every economic indicator (provider !== \"scb\" Swedish-specific & domain ∈ macro/fiscal/monetary/external/trade) MUST come from IMF","duration":0.8016210000000115,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence headline real GDP growth indicator uses IMF WEO","status":"passed","title":"headline real GDP growth indicator uses IMF WEO","duration":0.8498109999999883,"failureMessages":[],"location":{"line":384,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence IMF indicators never carry provider \"scb\"","status":"passed","title":"IMF indicators never carry provider \"scb\"","duration":2.372873000000027,"failureMessages":[],"location":{"line":390,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses table command with required --table-id flag","status":"passed","title":"parses table command with required --table-id flag","duration":1.1796390000000088,"failureMessages":[],"location":{"line":406,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses preset command with required --preset flag","status":"passed","title":"parses preset command with required --preset flag","duration":0.9292489999999702,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses list-presets command","status":"passed","title":"parses list-presets command","duration":0.5281489999999849,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for unknown command","status":"passed","title":"throws for unknown command","duration":1.3273159999999962,"failureMessages":[],"location":{"line":424,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for missing required flag","status":"passed","title":"throws for missing required flag","duration":0.6625510000000077,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for unexpected positional arg","status":"passed","title":"throws for unexpected positional arg","duration":0.8907080000000178,"failureMessages":[],"location":{"line":432,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parseSCBArgs defaults to help when no command given","status":"passed","title":"parseSCBArgs defaults to help when no command given","duration":0.9155640000000176,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing SCB_PRESETS covers all four preset keys","status":"passed","title":"SCB_PRESETS covers all four preset keys","duration":1.171042,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses repo-rate-path command","status":"passed","title":"parses repo-rate-path command","duration":0.8284010000000421,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses fetch command with --kind and --url flags","status":"passed","title":"parses fetch command with --kind and --url flags","duration":0.789828,"failureMessages":[],"location":{"line":460,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses --persist boolean alongside repo-rate-path","status":"passed","title":"parses --persist boolean alongside repo-rate-path","duration":0.8624249999999734,"failureMessages":[],"location":{"line":467,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing throws for unknown command","status":"passed","title":"throws for unknown command","duration":0.8259259999999813,"failureMessages":[],"location":{"line":472,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing throws for unexpected positional arg","status":"passed","title":"throws for unexpected positional arg","duration":3.597485000000006,"failureMessages":[],"location":{"line":476,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankArgs defaults to help when no command given","status":"passed","title":"parseRiksbankArgs defaults to help when no command given","duration":0.4883440000000405,"failureMessages":[],"location":{"line":480,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankKind accepts all valid kinds","status":"passed","title":"parseRiksbankKind accepts all valid kinds","duration":0.589572999999973,"failureMessages":[],"location":{"line":485,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankKind throws for invalid kind","status":"passed","title":"parseRiksbankKind throws for invalid kind","duration":0.6075379999999768,"failureMessages":[],"location":{"line":491,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget accepts valid riksbank.se HTTPS URLs","status":"passed","title":"assertRiksbankFetchTarget accepts valid riksbank.se HTTPS URLs","duration":0.9604979999999728,"failureMessages":[],"location":{"line":495,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget rejects non-HTTPS","status":"passed","title":"assertRiksbankFetchTarget rejects non-HTTPS","duration":0.5658189999999763,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget rejects non-Riksbank hosts","status":"passed","title":"assertRiksbankFetchTarget rejects non-Riksbank hosts","duration":0.6672399999999925,"failureMessages":[],"location":{"line":503,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants SCB and Riksbank providers are distinct strings","status":"passed","title":"SCB and Riksbank providers are distinct strings","duration":0.6450080000000185,"failureMessages":[],"location":{"line":513,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants neither SCB nor Riksbank providers equal \"imf\"","status":"passed","title":"neither SCB nor Riksbank providers equal \"imf\"","duration":0.5845850000000041,"failureMessages":[],"location":{"line":532,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants neither SCB nor Riksbank providers equal \"worldBank\"","status":"passed","title":"neither SCB nor Riksbank providers equal \"worldBank\"","duration":0.5691749999999729,"failureMessages":[],"location":{"line":537,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants a synthetic IMF data point is sorted before SCB and Riksbank","status":"passed","title":"a synthetic IMF data point is sorted before SCB and Riksbank","duration":0.6017359999999599,"failureMessages":[],"location":{"line":542,"column":3},"meta":{},"tags":[]}],"startTime":1787953680789,"endTime":1787953680843.6018,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-precedence-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd produces a valid NewsArticle with required Schema.org fields","status":"passed","title":"produces a valid NewsArticle with required Schema.org fields","duration":5.574057999999923,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes author as Organization","status":"passed","title":"includes author as Organization","duration":0.6712969999999814,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes publisher with logo","status":"passed","title":"includes publisher with logo","duration":0.5816190000000461,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd marks content as isAccessibleForFree","status":"passed","title":"marks content as isAccessibleForFree","duration":0.35966399999995247,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes isPartOf WebSite reference","status":"passed","title":"includes isPartOf WebSite reference","duration":0.48298399999998765,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes isBasedOn when provenance is provided","status":"passed","title":"includes isBasedOn when provenance is provided","duration":1.418676000000005,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd omits isBasedOn when provenance is empty","status":"passed","title":"omits isBasedOn when provenance is empty","duration":0.5163770000000341,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd produces valid JSON when serialized","status":"passed","title":"produces valid JSON when serialized","duration":1.199907000000053,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd emits NewsArticle.keywords as a deduped array when keywords are supplied","status":"passed","title":"emits NewsArticle.keywords as a deduped array when keywords are supplied","duration":1.2573149999999487,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd drops NewsArticle.keywords entirely when only blanks are supplied","status":"passed","title":"drops NewsArticle.keywords entirely when only blanks are supplied","duration":0.4067209999999477,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd drops NewsArticle.keywords entirely when no keywords field is supplied","status":"passed","title":"drops NewsArticle.keywords entirely when no keywords field is supplied","duration":0.3850209999999379,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd emits NewsArticle.articleSection when a non-empty value is supplied","status":"passed","title":"emits NewsArticle.articleSection when a non-empty value is supplied","duration":0.34653900000000704,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd trims NewsArticle.articleSection and drops it when only whitespace","status":"passed","title":"trims NewsArticle.articleSection and drops it when only whitespace","duration":0.3685199999999895,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd survives JSON.stringify with keywords + articleSection both set","status":"passed","title":"survives JSON.stringify with keywords + articleSection both set","duration":0.5223680000000286,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd produces a valid BreadcrumbList with positions","status":"passed","title":"produces a valid BreadcrumbList with positions","duration":0.6561990000000151,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd last entry omits item URL (current page)","status":"passed","title":"last entry omits item URL (current page)","duration":0.39431899999999587,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd intermediate entries include item URL","status":"passed","title":"intermediate entries include item URL","duration":0.34760099999994054,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd throws when entries array is empty","status":"passed","title":"throws when entries array is empty","duration":0.5281089999999722,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd throws when intermediate entry is missing item","status":"passed","title":"throws when intermediate entry is missing item","duration":0.4516559999999572,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd exports BREADCRUMB_TITLE_MAX_LENGTH constant","status":"passed","title":"exports BREADCRUMB_TITLE_MAX_LENGTH constant","duration":0.35227999999995063,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd produces a valid WebPage with speakable","status":"passed","title":"produces a valid WebPage with speakable","duration":0.8622239999999692,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd includes isPartOf WebSite reference","status":"passed","title":"includes isPartOf WebSite reference","duration":0.4334720000000516,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd throws when no valid selectors provided","status":"passed","title":"throws when no valid selectors provided","duration":0.5495190000000321,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd filters blank selectors","status":"passed","title":"filters blank selectors","duration":0.6512000000000171,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renderMarkdownToHtml works without importing chrome modules","status":"passed","title":"renderMarkdownToHtml works without importing chrome modules","duration":20.536548999999923,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renders GFM tables","status":"passed","title":"renders GFM tables","duration":5.745409999999993,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renders GFM strikethrough","status":"passed","title":"renders GFM strikethrough","duration":2.681502000000023,"failureMessages":[],"location":{"line":274,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes script tags in markdown","status":"passed","title":"sanitizes script tags in markdown","duration":3.768367000000012,"failureMessages":[],"location":{"line":279,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes javascript: URLs","status":"passed","title":"sanitizes javascript: URLs","duration":4.181129999999939,"failureMessages":[],"location":{"line":285,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes iframe tags","status":"passed","title":"sanitizes iframe tags","duration":2.2778749999999945,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome preserves mermaid code blocks","status":"passed","title":"preserves mermaid code blocks","duration":6.211402999999905,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome generates heading IDs (rehype-slug)","status":"passed","title":"generates heading IDs (rehype-slug)","duration":1.3874779999999873,"failureMessages":[],"location":{"line":302,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome wraps tables in responsive container","status":"passed","title":"wraps tables in responsive container","duration":1.8141669999999976,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries allows className on pre (for mermaid)","status":"passed","title":"allows className on pre (for mermaid)","duration":0.5159060000000864,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries allows id on heading elements (for slug anchors)","status":"passed","title":"allows id on heading elements (for slug anchors)","duration":0.8082839999999578,"failureMessages":[],"location":{"line":327,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries does not allow onclick or event handlers","status":"passed","title":"does not allow onclick or event handlers","duration":0.6185289999999668,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor converts mermaid code fences to <pre class=\"mermaid\">","status":"passed","title":"converts mermaid code fences to <pre class=\"mermaid\">","duration":0.6298090000000229,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor leaves non-mermaid code fences untouched","status":"passed","title":"leaves non-mermaid code fences untouched","duration":0.5040030000000115,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor handles multiple mermaid blocks","status":"passed","title":"handles multiple mermaid blocks","duration":0.5168879999999945,"failureMessages":[],"location":{"line":359,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor auto-repairs `-->|label]` edge-label closing typo","status":"passed","title":"auto-repairs `-->|label]` edge-label closing typo","duration":0.5378569999999172,"failureMessages":[],"location":{"line":374,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor repairs the typo across multiple arrow shapes","status":"passed","title":"repairs the typo across multiple arrow shapes","duration":0.5297219999999925,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor leaves correct `-->|label|` syntax untouched","status":"passed","title":"leaves correct `-->|label|` syntax untouched","duration":0.8152570000000878,"failureMessages":[],"location":{"line":397,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor does not rewrite `]` inside flowchart node bodies","status":"passed","title":"does not rewrite `]` inside flowchart node bodies","duration":0.7060519999999997,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor preserves `data-mermaid-source=\"true\"` after sanitization","status":"passed","title":"preserves `data-mermaid-source=\"true\"` after sanitization","duration":4.573564999999917,"failureMessages":[],"location":{"line":412,"column":3},"meta":{},"tags":[]}],"startTime":1787953784174,"endTime":1787953784253.5735,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/jsonld-and-markdown-pipeline.test.ts"},{"assertionResults":[{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch extracts matching Lagrådet entries from search HTML","status":"passed","title":"extracts matching Lagrådet entries from search HTML","duration":5.29158799999999,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch returns not_configured when no reference is provided","status":"passed","title":"returns not_configured when no reference is provided","duration":1.4493640000000028,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch does not match adjacent longer reference numbers","status":"passed","title":"does not match adjacent longer reference numbers","duration":0.5019100000000094,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953938511,"endTime":1787953938517.502,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/lagradet-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["initLazyDashboards","Skeleton class"],"fullName":"initLazyDashboards Skeleton class adds chart-skeleton class to container while loading","status":"passed","title":"adds chart-skeleton class to container while loading","duration":12.106395999999961,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Skeleton class"],"fullName":"initLazyDashboards Skeleton class removes chart-skeleton class when loader rejects","status":"passed","title":"removes chart-skeleton class when loader rejects","duration":2.723137999999949,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading does not call loader before intersection","status":"passed","title":"does not call loader before intersection","duration":1.3944810000000416,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading calls loader when container intersects viewport","status":"passed","title":"calls loader when container intersects viewport","duration":1.2463730000000055,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading does not call loader for non-intersecting entries","status":"passed","title":"does not call loader for non-intersecting entries","duration":1.0043400000000133,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading unobserves element after first intersection","status":"passed","title":"unobserves element after first intersection","duration":1.0719270000000165,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading calls loader only once even when intersected multiple times","status":"passed","title":"calls loader only once even when intersected multiple times","duration":1.0159119999999575,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Multiple dashboards"],"fullName":"initLazyDashboards Multiple dashboards observes all containers on registration","status":"passed","title":"observes all containers on registration","duration":1.5194649999999683,"failureMessages":[],"location":{"line":178,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Multiple dashboards"],"fullName":"initLazyDashboards Multiple dashboards loads dashboards independently when each intersects","status":"passed","title":"loads dashboards independently when each intersects","duration":1.6982889999999884,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Missing containers"],"fullName":"initLazyDashboards Missing containers skips dashboards whose container is not in the DOM","status":"passed","title":"skips dashboards whose container is not in the DOM","duration":1.9115589999999543,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Missing containers"],"fullName":"initLazyDashboards Missing containers still loads present dashboards when some containers are missing","status":"passed","title":"still loads present dashboards when some containers are missing","duration":1.1988639999999577,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Return value"],"fullName":"initLazyDashboards Return value returns the IntersectionObserver when IO is available","status":"passed","title":"returns the IntersectionObserver when IO is available","duration":0.8849669999999605,"failureMessages":[],"location":{"line":256,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Return value"],"fullName":"initLazyDashboards Return value returns undefined in fallback mode (no IntersectionObserver)","status":"passed","title":"returns undefined in fallback mode (no IntersectionObserver)","duration":0.6689430000000129,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Sync-throw safety"],"fullName":"initLazyDashboards Sync-throw safety removes skeleton and does not propagate when loader throws synchronously (IO path)","status":"passed","title":"removes skeleton and does not propagate when loader throws synchronously (IO path)","duration":2.2537490000000275,"failureMessages":[],"location":{"line":277,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Sync-throw safety"],"fullName":"initLazyDashboards Sync-throw safety removes skeleton and does not propagate when loader throws synchronously (fallback path)","status":"passed","title":"removes skeleton and does not propagate when loader throws synchronously (fallback path)","duration":2.1718159999999784,"failureMessages":[],"location":{"line":295,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) loads all present dashboards immediately when IntersectionObserver is unavailable","status":"passed","title":"loads all present dashboards immediately when IntersectionObserver is unavailable","duration":1.3880889999999795,"failureMessages":[],"location":{"line":314,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) skips missing containers in fallback mode","status":"passed","title":"skips missing containers in fallback mode","duration":0.663772999999992,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) does not throw when IntersectionObserver is unavailable","status":"passed","title":"does not throw when IntersectionObserver is unavailable","duration":0.8468250000000239,"failureMessages":[],"location":{"line":344,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) applies and removes skeleton class in fallback mode","status":"passed","title":"applies and removes skeleton class in fallback mode","duration":2.3378270000000043,"failureMessages":[],"location":{"line":353,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CHART_SKELETON_CLASS"],"fullName":"CHART_SKELETON_CLASS is \"chart-skeleton\"","status":"passed","title":"is \"chart-skeleton\"","duration":0.6176869999999894,"failureMessages":[],"location":{"line":380,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports DEFAULT_ROOT_MARGIN = \"2000px\"","status":"passed","title":"exports DEFAULT_ROOT_MARGIN = \"2000px\"","duration":0.8524770000000217,"failureMessages":[],"location":{"line":409,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports DEFAULT_THRESHOLD = 0.01","status":"passed","title":"exports DEFAULT_THRESHOLD = 0.01","duration":0.5980099999999879,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract passes DEFAULT_ROOT_MARGIN + DEFAULT_THRESHOLD to the IntersectionObserver by default","status":"passed","title":"passes DEFAULT_ROOT_MARGIN + DEFAULT_THRESHOLD to the IntersectionObserver by default","duration":1.0655450000000428,"failureMessages":[],"location":{"line":417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports HOMEPAGE_ROOT_MARGIN = \"300px\"","status":"passed","title":"exports HOMEPAGE_ROOT_MARGIN = \"300px\"","duration":0.5888320000000249,"failureMessages":[],"location":{"line":437,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract parses HOMEPAGE_ROOT_MARGIN to a positive sub-viewport pixel count","status":"passed","title":"parses HOMEPAGE_ROOT_MARGIN to a positive sub-viewport pixel count","duration":0.6476630000000227,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx parses single px value","status":"passed","title":"parses single px value","duration":0.5636049999999955,"failureMessages":[],"location":{"line":451,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx parses first component of multi-side margin","status":"passed","title":"parses first component of multi-side margin","duration":0.7811330000000112,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx handles negative values","status":"passed","title":"handles negative values","duration":0.7438129999999887,"failureMessages":[],"location":{"line":459,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for percentage values (cannot resolve without root)","status":"passed","title":"returns 0 for percentage values (cannot resolve without root)","duration":0.6130779999999731,"failureMessages":[],"location":{"line":463,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for undefined","status":"passed","title":"returns 0 for undefined","duration":0.5947130000000129,"failureMessages":[],"location":{"line":467,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for empty string","status":"passed","title":"returns 0 for empty string","duration":0.536233999999979,"failureMessages":[],"location":{"line":471,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for malformed input","status":"passed","title":"returns 0 for malformed input","duration":0.6394470000000183,"failureMessages":[],"location":{"line":475,"column":3},"meta":{},"tags":[]}],"startTime":1787953685951,"endTime":1787953685999.6394,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/lazy-loader.test.js"},{"assertionResults":[{"ancestorTitles":["Load CIA Stats Script","Script Configuration"],"fullName":"Load CIA Stats Script Script Configuration should have load-cia-stats.ts script","status":"passed","title":"should have load-cia-stats.ts script","duration":3.829119999999989,"failureMessages":[],"location":{"line":16,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Script Configuration"],"fullName":"Load CIA Stats Script Script Configuration should be a Node.js ES module","status":"passed","title":"should be a Node.js ES module","duration":0.7883260000000405,"failureMessages":[],"location":{"line":21,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CIA Data Source"],"fullName":"Load CIA Stats Script CIA Data Source should reference extraction_summary_report.csv","status":"passed","title":"should reference extraction_summary_report.csv","duration":0.5647880000000214,"failureMessages":[],"location":{"line":30,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CIA Data Source"],"fullName":"Load CIA Stats Script CIA Data Source should fetch from GitHub cia repository","status":"passed","title":"should fetch from GitHub cia repository","duration":0.5055769999999598,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should include ISO 27001 compliance comments","status":"passed","title":"should include ISO 27001 compliance comments","duration":0.6060139999999592,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should document data classification","status":"passed","title":"should document data classification","duration":0.48930599999999913,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should reference GDPR compliance","status":"passed","title":"should reference GDPR compliance","duration":0.45789700000000266,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should reference Swedish Offentlighetsprincipen","status":"passed","title":"should reference Swedish Offentlighetsprincipen","duration":0.42329300000000103,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_persons statistic","status":"passed","title":"should extract total_persons statistic","duration":0.5587260000000356,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_votes statistic","status":"passed","title":"should extract total_votes statistic","duration":0.4979930000000081,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_documents statistic","status":"passed","title":"should extract total_documents statistic","duration":0.6166949999999929,"failureMessages":[],"location":{"line":82,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_committee_documents statistic","status":"passed","title":"should extract total_committee_documents statistic","duration":0.5588159999999789,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_rule_violations statistic","status":"passed","title":"should extract total_rule_violations statistic","duration":0.5816489999999703,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Output Generation"],"fullName":"Load CIA Stats Script Output Generation should output to cia-data/production-stats.json","status":"passed","title":"should output to cia-data/production-stats.json","duration":0.6011450000000309,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Output Generation"],"fullName":"Load CIA Stats Script Output Generation should create JSON output with proper structure","status":"passed","title":"should create JSON output with proper structure","duration":0.7891680000000179,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Caching Strategy"],"fullName":"Load CIA Stats Script Caching Strategy should implement cache freshness check","status":"passed","title":"should implement cache freshness check","duration":0.706813000000011,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Caching Strategy"],"fullName":"Load CIA Stats Script Caching Strategy should include last_updated timestamp","status":"passed","title":"should include last_updated timestamp","duration":0.6404289999999833,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Error Handling"],"fullName":"Load CIA Stats Script Error Handling should have error handling for network failures","status":"passed","title":"should have error handling for network failures","duration":0.6177270000000021,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Error Handling"],"fullName":"Load CIA Stats Script Error Handling should have try-catch blocks","status":"passed","title":"should have try-catch blocks","duration":0.531394999999975,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CSV Parsing"],"fullName":"Load CIA Stats Script CSV Parsing should parse CSV content","status":"passed","title":"should parse CSV content","duration":0.653082999999981,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CSV Parsing"],"fullName":"Load CIA Stats Script CSV Parsing should handle CSV headers","status":"passed","title":"should handle CSV headers","duration":0.611614999999972,"failureMessages":[],"location":{"line":154,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Data Validation"],"fullName":"Load CIA Stats Script Data Validation should validate extracted statistics are numbers","status":"passed","title":"should validate extracted statistics are numbers","duration":1.1527980000000184,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Data Validation"],"fullName":"Load CIA Stats Script Data Validation should have reasonable statistic values (sanity check)","status":"passed","title":"should have reasonable statistic values (sanity check)","duration":0.7954190000000381,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Integration with Update Script"],"fullName":"Load CIA Stats Script Integration with Update Script should be compatible with update-stats-from-cia.ts","status":"passed","title":"should be compatible with update-stats-from-cia.ts","duration":0.6881479999999556,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","GitHub Actions Integration"],"fullName":"Load CIA Stats Script GitHub Actions Integration should be referenced in update-cia-csv-data workflow","status":"passed","title":"should be referenced in update-cia-csv-data workflow","duration":0.6980970000000184,"failureMessages":[],"location":{"line":202,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","GitHub Actions Integration"],"fullName":"Load CIA Stats Script GitHub Actions Integration should have scheduled workflow for daily updates","status":"passed","title":"should have scheduled workflow for daily updates","duration":0.6636120000000005,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]}],"startTime":1787953835330,"endTime":1787953835350.6636,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/load-cia-stats.test.ts"},{"assertionResults":[{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects literal REPLACE THIS H1 placeholder","status":"passed","title":"rejects literal REPLACE THIS H1 placeholder","duration":3.998927999999978,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects Executive Brief Template heading","status":"passed","title":"rejects Executive Brief Template heading","duration":0.6811260000000061,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects AI_MUST_REPLACE marker","status":"passed","title":"rejects AI_MUST_REPLACE marker","duration":0.8240030000000047,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects the banned phrase \"AI-generated political intelligence\"","status":"passed","title":"rejects the banned phrase \"AI-generated political intelligence\"","duration":0.5811380000000099,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects bare boilerplate \"Executive Brief\" (case- and emoji-tolerant)","status":"passed","title":"rejects bare boilerplate \"Executive Brief\" (case- and emoji-tolerant)","duration":1.0576599999999985,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects empty / emoji-only headings","status":"passed","title":"rejects empty / emoji-only headings","duration":0.6934079999999767,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 accepts publishable story-oriented titles","status":"passed","title":"accepts publishable story-oriented titles","duration":0.46033199999999397,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 exposes the banned-pattern list as a frozen contract","status":"passed","title":"exposes the banned-pattern list as a frozen contract","duration":0.8382399999999848,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns both fields when the brief has publishable H1 + BLUF","status":"passed","title":"returns both fields when the brief has publishable H1 + BLUF","duration":31.061849000000052,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 is the REPLACE-THIS-H1 placeholder","status":"passed","title":"falls back to BLUF-derived title when H1 is the REPLACE-THIS-H1 placeholder","duration":4.78635300000002,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 carries the AI_MUST_REPLACE marker","status":"passed","title":"falls back to BLUF-derived title when H1 carries the AI_MUST_REPLACE marker","duration":2.4742729999999824,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 carries the banned phrase \"AI-generated political intelligence\"","status":"passed","title":"falls back to BLUF-derived title when H1 carries the banned phrase \"AI-generated political intelligence\"","duration":5.569818999999995,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null title when H1 is bare boilerplate \"Executive Brief\"","status":"passed","title":"returns null title when H1 is bare boilerplate \"Executive Brief\"","duration":1.0546850000000063,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to a localized BLUF-derived title when the translated H1 is boilerplate","status":"passed","title":"falls back to a localized BLUF-derived title when the translated H1 is boilerplate","duration":8.536433999999986,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo preserves year-led Japanese titles instead of stripping leading digits as emoji","status":"passed","title":"preserves year-led Japanese titles instead of stripping leading digits as emoji","duration":3.877601000000027,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo accepts concise but valid Chinese headlines that are shorter than the Latin minimum","status":"passed","title":"accepts concise but valid Chinese headlines that are shorter than the Latin minimum","duration":2.680880000000002,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to first prose paragraph when no BLUF heading is present","status":"passed","title":"falls back to first prose paragraph when no BLUF heading is present","duration":1.2427470000000085,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null description when BLUF section is empty","status":"passed","title":"returns null description when BLUF section is empty","duration":1.8025250000000597,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null title + null description + empty keywords when markdown is empty or absent","status":"passed","title":"returns null title + null description + empty keywords when markdown is empty or absent","duration":1.4100899999999683,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo truncates a very long BLUF to a sentence boundary","status":"passed","title":"truncates a very long BLUF to a sentence boundary","duration":0.9895930000000135,"failureMessages":[],"location":{"line":287,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 collapses to the subfolder label after cleaning","status":"passed","title":"falls back to BLUF-derived title when H1 collapses to the subfolder label after cleaning","duration":0.8814200000000483,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo strips new decision-analysis prefix forms from H1 titles","status":"passed","title":"strips new decision-analysis prefix forms from H1 titles","duration":21.441687,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo skips HTML block elements in readFirstParagraph fallback","status":"passed","title":"skips HTML block elements in readFirstParagraph fallback","duration":3.4577540000000226,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]}],"startTime":1787953787859,"endTime":1787953787960.4578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/localized-brief-seo.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should fetch motions with default limit","status":"passed","title":"should fetch motions with default limit","duration":6.212610999999981,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should pass optional rm parameter","status":"passed","title":"should pass optional rm parameter","duration":1.8217410000000314,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.9502390000000105,"failureMessages":[],"location":{"line":58,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should return empty array when response has no motions key","status":"passed","title":"should return empty array when response has no motions key","duration":0.7700510000000236,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should search documents with query parameters","status":"passed","title":"should search documents with query parameters","duration":1.6703569999999672,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.8302040000000375,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should return empty array when response has no documents key","status":"passed","title":"should return empty array when response has no documents key","duration":0.6819169999999986,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=motion on mot documents","status":"passed","title":"should stamp type=motion on mot documents","duration":0.8376480000000015,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=committee-report on bet documents","status":"passed","title":"should stamp type=committee-report on bet documents","duration":1.0529210000000262,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=proposition on prop documents","status":"passed","title":"should stamp type=proposition on prop documents","duration":1.0349780000000237,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp subtype from subtyp field","status":"passed","title":"should stamp subtype from subtyp field","duration":0.7221619999999689,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should not overwrite existing type field","status":"passed","title":"should not overwrite existing type field","duration":0.7831059999999752,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should use the dokument key before the documents key","status":"passed","title":"should use the dokument key before the documents key","duration":1.1005010000000084,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should expose query diagnostics for empty search results","status":"passed","title":"should expose query diagnostics for empty search results","duration":0.9793530000000032,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should map Swedish doktyp codes to English type strings","status":"passed","title":"should map Swedish doktyp codes to English type strings","duration":0.8873009999999795,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should return the code unchanged for unrecognised doktyp values","status":"passed","title":"should return the code unchanged for unrecognised doktyp values","duration":0.5584559999999783,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should return document for empty/undefined input","status":"passed","title":"should return document for empty/undefined input","duration":0.5689859999999953,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should be case-insensitive","status":"passed","title":"should be case-insensitive","duration":0.6148509999999874,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should search speeches with query parameters","status":"passed","title":"should search speeches with query parameters","duration":0.9404710000000023,"failureMessages":[],"location":{"line":238,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.87194199999999,"failureMessages":[],"location":{"line":250,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should return empty array when response has no speeches key","status":"passed","title":"should return empty array when response has no speeches key","duration":0.8419260000000008,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should fetch MPs with filters","status":"passed","title":"should fetch MPs with filters","duration":0.9715090000000259,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.7451249999999732,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should pass empty object when no filters provided","status":"passed","title":"should pass empty object when no filters provided","duration":0.7761330000000157,"failureMessages":[],"location":{"line":299,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should return empty array when response has no mps key","status":"passed","title":"should return empty array when response has no mps key","duration":3.501275000000021,"failureMessages":[],"location":{"line":311,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should fetch voting records with filters","status":"passed","title":"should fetch voting records with filters","duration":1.1637590000000273,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.933618000000024,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should return empty array when response has no votes key","status":"passed","title":"should return empty array when response has no votes key","duration":0.7161010000000374,"failureMessages":[],"location":{"line":347,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should emit MCP_INDEXING_LAG when current riksmöte is empty but previous has rows","status":"passed","title":"should emit MCP_INDEXING_LAG when current riksmöte is empty but previous has rows","duration":0.8897249999999985,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchDocumentDetailsWithCoverage"],"fullName":"MCPClient Part 2 fetchDocumentDetailsWithCoverage classifies same-day empty content as not_indexed","status":"passed","title":"classifies same-day empty content as not_indexed","duration":0.8926510000000007,"failureMessages":[],"location":{"line":380,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should fetch government documents","status":"passed","title":"should fetch government documents","duration":0.7789980000000014,"failureMessages":[],"location":{"line":400,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.7506959999999481,"failureMessages":[],"location":{"line":412,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should return empty array when response has no documents key","status":"passed","title":"should return empty array when response has no documents key","duration":0.7224019999999882,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should return request statistics","status":"passed","title":"should return request statistics","duration":0.8135429999999815,"failureMessages":[],"location":{"line":437,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should return 0% success rate when no requests made","status":"passed","title":"should return 0% success rate when no requests made","duration":0.9635240000000067,"failureMessages":[],"location":{"line":444,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should calculate success rate correctly","status":"passed","title":"should calculate success rate correctly","duration":1.408296000000064,"failureMessages":[],"location":{"line":449,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should show 100% success rate when all requests succeed","status":"passed","title":"should show 100% success rate when all requests succeed","duration":1.0317919999999958,"failureMessages":[],"location":{"line":472,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","resetStats"],"fullName":"MCPClient Part 2 resetStats should reset request and error counts to zero","status":"passed","title":"should reset request and error counts to zero","duration":1.0717959999999493,"failureMessages":[],"location":{"line":487,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","resetStats"],"fullName":"MCPClient Part 2 resetStats should reset after errors too","status":"passed","title":"should reset after errors too","duration":1.0685399999999845,"failureMessages":[],"location":{"line":503,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject empty tool names","status":"passed","title":"should reject empty tool names","duration":2.5904800000000705,"failureMessages":[],"location":{"line":514,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject null/undefined tool names","status":"passed","title":"should reject null/undefined tool names","duration":1.1446839999999838,"failureMessages":[],"location":{"line":518,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject non-string tool names","status":"passed","title":"should reject non-string tool names","duration":1.2948240000000624,"failureMessages":[],"location":{"line":523,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject tool names with path traversal characters","status":"passed","title":"should reject tool names with path traversal characters","duration":1.4120539999998982,"failureMessages":[],"location":{"line":527,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject tool names with special characters","status":"passed","title":"should reject tool names with special characters","duration":1.207471000000055,"failureMessages":[],"location":{"line":532,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should accept valid tool names","status":"passed","title":"should accept valid tool names","duration":1.6545280000000275,"failureMessages":[],"location":{"line":537,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","error counting accuracy"],"fullName":"MCPClient Part 2 error counting accuracy should not over-count errors on retried requests","status":"passed","title":"should not over-count errors on retried requests","duration":1.5499720000000252,"failureMessages":[],"location":{"line":551,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","error counting accuracy"],"fullName":"MCPClient Part 2 error counting accuracy should count exactly one error for a fully failed request","status":"passed","title":"should count exactly one error for a fully failed request","duration":1.3384459999999763,"failureMessages":[],"location":{"line":575,"column":5},"meta":{},"tags":[]}],"startTime":1787953667829,"endTime":1787953667886.3384,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-core-part2.test.ts"},{"assertionResults":[{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should export getDefaultClient function","status":"passed","title":"should export getDefaultClient function","duration":3.7039660000000367,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should return MCPClient instance from getDefaultClient","status":"passed","title":"should return MCPClient instance from getDefaultClient","duration":0.9661389999999983,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should return same instance on repeated getDefaultClient calls","status":"passed","title":"should return same instance on repeated getDefaultClient calls","duration":0.39479900000003454,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should export all convenience functions","status":"passed","title":"should export all convenience functions","duration":0.8043159999999716,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchCalendarEvents should delegate to default client","status":"passed","title":"convenience fetchCalendarEvents should delegate to default client","duration":2.3855970000000184,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchPropositions should delegate to default client","status":"passed","title":"convenience fetchPropositions should delegate to default client","duration":0.8186829999999645,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience searchDocuments should delegate to default client","status":"passed","title":"convenience searchDocuments should delegate to default client","duration":1.5867110000000366,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchMPs should delegate to default client","status":"passed","title":"convenience fetchMPs should delegate to default client","duration":0.8025730000000522,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchMotions should delegate to default client","status":"passed","title":"convenience fetchMotions should delegate to default client","duration":0.9115570000000162,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience searchSpeeches should delegate to default client","status":"passed","title":"convenience searchSpeeches should delegate to default client","duration":0.6348989999999617,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchVotingRecords should delegate to default client","status":"passed","title":"convenience fetchVotingRecords should delegate to default client","duration":0.9735630000000128,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchGovernmentDocuments should delegate to default client","status":"passed","title":"convenience fetchGovernmentDocuments should delegate to default client","duration":0.6671289999999885,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchCommitteeReports should delegate to default client","status":"passed","title":"convenience fetchCommitteeReports should delegate to default client","duration":0.6915149999999812,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]}],"startTime":1787953889950,"endTime":1787953889965.6914,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-exports.test.ts"},{"assertionResults":[{"ancestorTitles":["MCP client smoke"],"fullName":"MCP client smoke returns structured provenance from the live MCP endpoint","status":"skipped","title":"returns structured provenance from the live MCP endpoint","failureMessages":[],"location":{"line":8,"column":3},"meta":{},"tags":[]}],"startTime":1787953656920,"endTime":1787953656920,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-smoke.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchExternalUrlText — abort-during-body regression"],"fullName":"fetchExternalUrlText — abort-during-body regression returns null when the response body rejects after the timeout fires","status":"passed","title":"returns null when the response body rejects after the timeout fires","duration":29.54560299999997,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchExternalUrlText — abort-during-body regression"],"fullName":"fetchExternalUrlText — abort-during-body regression clears the abort timer on transport rejection (no dangling timers)","status":"passed","title":"clears the abort timer on transport rejection (no dangling timers)","duration":0.9305919999999901,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]}],"startTime":1787953911323,"endTime":1787953911353.9307,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-transport-timeout.test.ts"},{"assertionResults":[{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue deduplicates entries by resource type + id","status":"passed","title":"deduplicates entries by resource type + id","duration":5.495310000000018,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue drains a queued document once full text becomes available","status":"passed","title":"drains a queued document once full text becomes available","duration":2.576334000000031,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue does not write the queue file when there is no retry work","status":"passed","title":"does not write the queue file when there is no retry work","duration":0.8588889999999765,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue isolates transient document retry failures and emits fetch_error diagnostics","status":"passed","title":"isolates transient document retry failures and emits fetch_error diagnostics","duration":9.121419000000003,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]}],"startTime":1787953866796,"endTime":1787953866815.1213,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-retry-queue.test.ts"},{"assertionResults":[{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all 14 news workflows should exist","status":"passed","title":"all 14 news workflows should exist","duration":4.818591000000026,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should have network.allowed configuration","status":"passed","title":"all workflows should have network.allowed configuration","duration":0.9920880000000238,"failureMessages":[],"location":{"line":295,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should include required MCP service domains","status":"passed","title":"all workflows should include required MCP service domains","duration":4.998518000000047,"failureMessages":[],"location":{"line":304,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should have identical network.allowed domain sets","status":"passed","title":"all workflows should have identical network.allowed domain sets","duration":3.5448959999999943,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency network.allowed should include \"defaults\" for gh-aw built-in domains","status":"passed","title":"network.allowed should include \"defaults\" for gh-aw built-in domains","duration":1.0805230000000279,"failureMessages":[],"location":{"line":329,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency network.allowed should include \"node\" for npm registry access","status":"passed","title":"network.allowed should include \"node\" for npm registry access","duration":1.0015349999999899,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-committee-reports.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-committee-reports.md should configure riksdag-regering MCP with correct URL","duration":0.9272060000000124,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-election-cycle.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-election-cycle.md should configure riksdag-regering MCP with correct URL","duration":0.6441859999999906,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-evening-analysis.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-evening-analysis.md should configure riksdag-regering MCP with correct URL","duration":0.7851399999999558,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-interpellations.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-interpellations.md should configure riksdag-regering MCP with correct URL","duration":0.7514170000000036,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-month-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-month-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.7384830000000306,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-monthly-review.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-monthly-review.md should configure riksdag-regering MCP with correct URL","duration":0.5945130000000063,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-motions.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-motions.md should configure riksdag-regering MCP with correct URL","duration":0.6251009999999724,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-propositions.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-propositions.md should configure riksdag-regering MCP with correct URL","duration":0.6729399999999828,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-quarter-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-quarter-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.6819770000000176,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-realtime-monitor.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-realtime-monitor.md should configure riksdag-regering MCP with correct URL","duration":0.6571900000000142,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-translate.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-translate.md should configure riksdag-regering MCP with correct URL","duration":4.921703999999977,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-week-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-week-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.550660999999991,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-weekly-review.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-weekly-review.md should configure riksdag-regering MCP with correct URL","duration":0.6613989999999603,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-year-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-year-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.46108299999991686,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration MCP client default URL should match workflow configuration","status":"passed","title":"MCP client default URL should match workflow configuration","duration":0.5818189999999959,"failureMessages":[],"location":{"line":361,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration SCB client default URL should be correctly configured","status":"passed","title":"SCB client default URL should be correctly configured","duration":0.4560840000000326,"failureMessages":[],"location":{"line":377,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration mcp-setup.sh should configure gateway URL for AWF sandbox","status":"passed","title":"mcp-setup.sh should configure gateway URL for AWF sandbox","duration":0.6365710000000036,"failureMessages":[],"location":{"line":384,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should document get_sync_status() health check","status":"passed","title":"news-committee-reports.md should document get_sync_status() health check","duration":1.6438670000000002,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-committee-reports.md should have safeoutputs___noop fallback on MCP failure","duration":1.0958109999999124,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should use object payload for noop calls","status":"passed","title":"news-committee-reports.md should use object payload for noop calls","duration":1.3707470000000512,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should document get_sync_status() health check","status":"passed","title":"news-election-cycle.md should document get_sync_status() health check","duration":1.1518959999999652,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-election-cycle.md should have safeoutputs___noop fallback on MCP failure","duration":1.3288479999999936,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should use object payload for noop calls","status":"passed","title":"news-election-cycle.md should use object payload for noop calls","duration":1.272942999999941,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should document get_sync_status() health check","status":"passed","title":"news-evening-analysis.md should document get_sync_status() health check","duration":1.3434959999999592,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-evening-analysis.md should have safeoutputs___noop fallback on MCP failure","duration":1.1807000000000016,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should use object payload for noop calls","status":"passed","title":"news-evening-analysis.md should use object payload for noop calls","duration":1.3723589999999604,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should document get_sync_status() health check","status":"passed","title":"news-interpellations.md should document get_sync_status() health check","duration":1.0496850000000677,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-interpellations.md should have safeoutputs___noop fallback on MCP failure","duration":0.9888809999999921,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should use object payload for noop calls","status":"passed","title":"news-interpellations.md should use object payload for noop calls","duration":1.1197459999999637,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should document get_sync_status() health check","status":"passed","title":"news-month-ahead.md should document get_sync_status() health check","duration":1.1386120000000801,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-month-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.0543129999999792,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should use object payload for noop calls","status":"passed","title":"news-month-ahead.md should use object payload for noop calls","duration":1.2344509999999218,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should document get_sync_status() health check","status":"passed","title":"news-monthly-review.md should document get_sync_status() health check","duration":1.0799019999999473,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-monthly-review.md should have safeoutputs___noop fallback on MCP failure","duration":1.047070000000076,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should use object payload for noop calls","status":"passed","title":"news-monthly-review.md should use object payload for noop calls","duration":1.3374840000000177,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should document get_sync_status() health check","status":"passed","title":"news-motions.md should document get_sync_status() health check","duration":1.4819949999999835,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-motions.md should have safeoutputs___noop fallback on MCP failure","duration":1.460574000000065,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should use object payload for noop calls","status":"passed","title":"news-motions.md should use object payload for noop calls","duration":1.5629159999999729,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should document get_sync_status() health check","status":"passed","title":"news-propositions.md should document get_sync_status() health check","duration":1.5184030000000348,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-propositions.md should have safeoutputs___noop fallback on MCP failure","duration":1.5078829999999925,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should use object payload for noop calls","status":"passed","title":"news-propositions.md should use object payload for noop calls","duration":1.6466030000000274,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should document get_sync_status() health check","status":"passed","title":"news-quarter-ahead.md should document get_sync_status() health check","duration":1.684233000000063,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-quarter-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.7658059999999978,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should use object payload for noop calls","status":"passed","title":"news-quarter-ahead.md should use object payload for noop calls","duration":1.7618589999999585,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should document get_sync_status() health check","status":"passed","title":"news-realtime-monitor.md should document get_sync_status() health check","duration":1.563998999999967,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-realtime-monitor.md should have safeoutputs___noop fallback on MCP failure","duration":1.6656979999999066,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should use object payload for noop calls","status":"passed","title":"news-realtime-monitor.md should use object payload for noop calls","duration":1.9046260000000075,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should document get_sync_status() health check","status":"passed","title":"news-translate.md should document get_sync_status() health check","duration":1.3372739999999794,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-translate.md should have safeoutputs___noop fallback on MCP failure","duration":1.3838709999999992,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should use object payload for noop calls","status":"passed","title":"news-translate.md should use object payload for noop calls","duration":1.6169779999999037,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should document get_sync_status() health check","status":"passed","title":"news-week-ahead.md should document get_sync_status() health check","duration":1.7574299999999994,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-week-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.8400050000000192,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should use object payload for noop calls","status":"passed","title":"news-week-ahead.md should use object payload for noop calls","duration":1.9258049999999685,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should document get_sync_status() health check","status":"passed","title":"news-weekly-review.md should document get_sync_status() health check","duration":1.7569989999999507,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-weekly-review.md should have safeoutputs___noop fallback on MCP failure","duration":1.7046119999999974,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should use object payload for noop calls","status":"passed","title":"news-weekly-review.md should use object payload for noop calls","duration":1.9302640000000792,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should document get_sync_status() health check","status":"passed","title":"news-year-ahead.md should document get_sync_status() health check","duration":1.8409670000000915,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-year-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":3.1961639999999534,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should use object payload for noop calls","status":"passed","title":"news-year-ahead.md should use object payload for noop calls","duration":1.5313370000000077,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-committee-reports.md should set threat detection to warning-only mode","status":"passed","title":"news-committee-reports.md should set threat detection to warning-only mode","duration":1.1976319999999987,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-election-cycle.md should set threat detection to warning-only mode","status":"passed","title":"news-election-cycle.md should set threat detection to warning-only mode","duration":1.0008040000000165,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-evening-analysis.md should set threat detection to warning-only mode","status":"passed","title":"news-evening-analysis.md should set threat detection to warning-only mode","duration":1.6827509999999393,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-interpellations.md should set threat detection to warning-only mode","status":"passed","title":"news-interpellations.md should set threat detection to warning-only mode","duration":1.6254430000000184,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-month-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-month-ahead.md should set threat detection to warning-only mode","duration":1.030909999999949,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-monthly-review.md should set threat detection to warning-only mode","status":"passed","title":"news-monthly-review.md should set threat detection to warning-only mode","duration":0.944248000000016,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-motions.md should set threat detection to warning-only mode","status":"passed","title":"news-motions.md should set threat detection to warning-only mode","duration":0.9308330000000069,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-propositions.md should set threat detection to warning-only mode","status":"passed","title":"news-propositions.md should set threat detection to warning-only mode","duration":0.9605880000000298,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-quarter-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-quarter-ahead.md should set threat detection to warning-only mode","duration":1.0529219999999668,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-realtime-monitor.md should set threat detection to warning-only mode","status":"passed","title":"news-realtime-monitor.md should set threat detection to warning-only mode","duration":1.0711259999999356,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-translate.md should set threat detection to warning-only mode","status":"passed","title":"news-translate.md should set threat detection to warning-only mode","duration":1.076816000000008,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-week-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-week-ahead.md should set threat detection to warning-only mode","duration":1.109136000000035,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-weekly-review.md should set threat detection to warning-only mode","status":"passed","title":"news-weekly-review.md should set threat detection to warning-only mode","duration":1.0306800000000749,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-year-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-year-ahead.md should set threat detection to warning-only mode","duration":1.2184409999999843,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-committee-reports.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-committee-reports.md should have safe-outputs.allowed-domains covering MCP services","duration":1.9085730000000467,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-election-cycle.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-election-cycle.md should have safe-outputs.allowed-domains covering MCP services","duration":1.336691999999971,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-evening-analysis.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-evening-analysis.md should have safe-outputs.allowed-domains covering MCP services","duration":2.174500999999964,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-interpellations.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-interpellations.md should have safe-outputs.allowed-domains covering MCP services","duration":2.361831000000052,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-month-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-month-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.7682810000000018,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-monthly-review.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-monthly-review.md should have safe-outputs.allowed-domains covering MCP services","duration":1.5559520000000475,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-motions.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-motions.md should have safe-outputs.allowed-domains covering MCP services","duration":1.3972760000000335,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-propositions.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-propositions.md should have safe-outputs.allowed-domains covering MCP services","duration":1.487013999999931,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-quarter-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-quarter-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.3861049999999295,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-realtime-monitor.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-realtime-monitor.md should have safe-outputs.allowed-domains covering MCP services","duration":1.4408680000000231,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-translate.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-translate.md should have safe-outputs.allowed-domains covering MCP services","duration":1.4586910000000444,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-week-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-week-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.530746000000022,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-weekly-review.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-weekly-review.md should have safe-outputs.allowed-domains covering MCP services","duration":1.6933199999999715,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-year-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-year-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.513392999999951,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains safe-output domains should be a subset of network.allowed domains (literal or via ecosystem identifier)","status":"passed","title":"safe-output domains should be a subset of network.allowed domains (literal or via ecosystem identifier)","duration":18.919579999999996,"failureMessages":[],"location":{"line":473,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm composite action exists","status":"passed","title":"shared news-prewarm composite action exists","duration":2.0881990000000314,"failureMessages":[],"location":{"line":502,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action labels pre-flight step correctly","status":"passed","title":"shared news-prewarm action labels pre-flight step correctly","duration":1.7791809999999941,"failureMessages":[],"location":{"line":509,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) all workflows reference the shared news-prewarm composite action","status":"passed","title":"all workflows reference the shared news-prewarm composite action","duration":4.1500200000000405,"failureMessages":[],"location":{"line":525,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action has canonical diagnostics content","status":"passed","title":"shared news-prewarm action has canonical diagnostics content","duration":1.768340999999964,"failureMessages":[],"location":{"line":546,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action probes all required MCP/data domains","status":"passed","title":"shared news-prewarm action probes all required MCP/data domains","duration":1.8494719999999916,"failureMessages":[],"location":{"line":554,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-committee-reports.md should expose MCP health gate in effective prompt","status":"passed","title":"news-committee-reports.md should expose MCP health gate in effective prompt","duration":2.3489080000000513,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-committee-reports.md should wire shared pre-flight composite action","status":"passed","title":"news-committee-reports.md should wire shared pre-flight composite action","duration":1.893685000000005,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-election-cycle.md should expose MCP health gate in effective prompt","status":"passed","title":"news-election-cycle.md should expose MCP health gate in effective prompt","duration":2.629232000000002,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-election-cycle.md should wire shared pre-flight composite action","status":"passed","title":"news-election-cycle.md should wire shared pre-flight composite action","duration":1.8011920000000146,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-evening-analysis.md should expose MCP health gate in effective prompt","status":"passed","title":"news-evening-analysis.md should expose MCP health gate in effective prompt","duration":2.4581719999999905,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-evening-analysis.md should wire shared pre-flight composite action","status":"passed","title":"news-evening-analysis.md should wire shared pre-flight composite action","duration":1.8880250000000842,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-interpellations.md should expose MCP health gate in effective prompt","status":"passed","title":"news-interpellations.md should expose MCP health gate in effective prompt","duration":2.334600000000023,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-interpellations.md should wire shared pre-flight composite action","status":"passed","title":"news-interpellations.md should wire shared pre-flight composite action","duration":1.8968919999999798,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-month-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-month-ahead.md should expose MCP health gate in effective prompt","duration":2.4862850000000662,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-month-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-month-ahead.md should wire shared pre-flight composite action","duration":1.8742690000000266,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-monthly-review.md should expose MCP health gate in effective prompt","status":"passed","title":"news-monthly-review.md should expose MCP health gate in effective prompt","duration":3.5111930000000484,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-monthly-review.md should wire shared pre-flight composite action","status":"passed","title":"news-monthly-review.md should wire shared pre-flight composite action","duration":1.868408000000045,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-motions.md should expose MCP health gate in effective prompt","status":"passed","title":"news-motions.md should expose MCP health gate in effective prompt","duration":2.085002999999915,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-motions.md should wire shared pre-flight composite action","status":"passed","title":"news-motions.md should wire shared pre-flight composite action","duration":1.678861999999981,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-propositions.md should expose MCP health gate in effective prompt","status":"passed","title":"news-propositions.md should expose MCP health gate in effective prompt","duration":2.029178999999999,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-propositions.md should wire shared pre-flight composite action","status":"passed","title":"news-propositions.md should wire shared pre-flight composite action","duration":2.520057999999949,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-quarter-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-quarter-ahead.md should expose MCP health gate in effective prompt","duration":2.807235999999989,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-quarter-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-quarter-ahead.md should wire shared pre-flight composite action","duration":1.8105299999999716,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-realtime-monitor.md should expose MCP health gate in effective prompt","status":"passed","title":"news-realtime-monitor.md should expose MCP health gate in effective prompt","duration":2.355278999999996,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-realtime-monitor.md should wire shared pre-flight composite action","status":"passed","title":"news-realtime-monitor.md should wire shared pre-flight composite action","duration":2.07081699999992,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-week-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-week-ahead.md should expose MCP health gate in effective prompt","duration":2.254049000000009,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-week-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-week-ahead.md should wire shared pre-flight composite action","duration":1.7915740000000824,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-weekly-review.md should expose MCP health gate in effective prompt","status":"passed","title":"news-weekly-review.md should expose MCP health gate in effective prompt","duration":2.233812000000057,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-weekly-review.md should wire shared pre-flight composite action","status":"passed","title":"news-weekly-review.md should wire shared pre-flight composite action","duration":1.838512000000037,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-year-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-year-ahead.md should expose MCP health gate in effective prompt","duration":2.2789260000000695,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-year-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-year-ahead.md should wire shared pre-flight composite action","duration":1.8815829999999778,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) shared news-prewarm action probes the Render MCP endpoint","status":"passed","title":"shared news-prewarm action probes the Render MCP endpoint","duration":2.0133999999999332,"failureMessages":[],"location":{"line":612,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns shared news-prewarm action contains MCP pre-warm step","status":"passed","title":"shared news-prewarm action contains MCP pre-warm step","duration":2.0516509999999926,"failureMessages":[],"location":{"line":625,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-committee-reports.md should reference MCP pre-warm or health check","status":"passed","title":"news-committee-reports.md should reference MCP pre-warm or health check","duration":2.6049970000000258,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-election-cycle.md should reference MCP pre-warm or health check","status":"passed","title":"news-election-cycle.md should reference MCP pre-warm or health check","duration":2.6663619999999355,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-evening-analysis.md should reference MCP pre-warm or health check","status":"passed","title":"news-evening-analysis.md should reference MCP pre-warm or health check","duration":2.6357940000000326,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-interpellations.md should reference MCP pre-warm or health check","status":"passed","title":"news-interpellations.md should reference MCP pre-warm or health check","duration":2.5869729999999436,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-month-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-month-ahead.md should reference MCP pre-warm or health check","duration":2.6252550000000383,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-monthly-review.md should reference MCP pre-warm or health check","status":"passed","title":"news-monthly-review.md should reference MCP pre-warm or health check","duration":2.6068900000000212,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-motions.md should reference MCP pre-warm or health check","status":"passed","title":"news-motions.md should reference MCP pre-warm or health check","duration":2.6914880000000494,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-propositions.md should reference MCP pre-warm or health check","status":"passed","title":"news-propositions.md should reference MCP pre-warm or health check","duration":2.6985630000000356,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-quarter-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-quarter-ahead.md should reference MCP pre-warm or health check","duration":2.8633909999999787,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-realtime-monitor.md should reference MCP pre-warm or health check","status":"passed","title":"news-realtime-monitor.md should reference MCP pre-warm or health check","duration":3.607353000000103,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-translate.md should reference MCP pre-warm or health check","status":"passed","title":"news-translate.md should reference MCP pre-warm or health check","duration":3.2583120000000463,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-week-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-week-ahead.md should reference MCP pre-warm or health check","duration":2.8452960000000758,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-weekly-review.md should reference MCP pre-warm or health check","status":"passed","title":"news-weekly-review.md should reference MCP pre-warm or health check","duration":2.767571999999973,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-year-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-year-ahead.md should reference MCP pre-warm or health check","duration":2.8048820000000205,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Step Ordering Awareness"],"fullName":"Network Diagnostics Configuration Step Ordering Awareness pre-flight steps should be in frontmatter (via shared action), health gate in prompt body","status":"passed","title":"pre-flight steps should be in frontmatter (via shared action), health gate in prompt body","duration":10.546051000000034,"failureMessages":[],"location":{"line":659,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Tool Count Reference"],"fullName":"Network Diagnostics Configuration MCP Tool Count Reference MCP client should reference expected tool count in documentation or code","status":"passed","title":"MCP client should reference expected tool count in documentation or code","duration":2.7959050000000616,"failureMessages":[],"location":{"line":693,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Tool Count Reference"],"fullName":"Network Diagnostics Configuration MCP Tool Count Reference agentic workflow MCP queries test should exist","status":"passed","title":"agentic workflow MCP queries test should exist","duration":2.318179999999984,"failureMessages":[],"location":{"line":701,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-committee-reports.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-committee-reports.md should reference stakeholder-perspectives artifact","duration":2.6847159999999803,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-election-cycle.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-election-cycle.md should reference stakeholder-perspectives artifact","duration":2.7450589999999693,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-evening-analysis.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-evening-analysis.md should reference stakeholder-perspectives artifact","duration":2.6680249999999432,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-interpellations.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-interpellations.md should reference stakeholder-perspectives artifact","duration":2.645362999999975,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-month-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-month-ahead.md should reference stakeholder-perspectives artifact","duration":2.6690770000000157,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-monthly-review.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-monthly-review.md should reference stakeholder-perspectives artifact","duration":2.624614000000065,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-motions.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-motions.md should reference stakeholder-perspectives artifact","duration":2.9261579999999867,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-propositions.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-propositions.md should reference stakeholder-perspectives artifact","duration":4.1491379999999936,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-quarter-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-quarter-ahead.md should reference stakeholder-perspectives artifact","duration":2.9951469999999745,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-realtime-monitor.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-realtime-monitor.md should reference stakeholder-perspectives artifact","duration":2.9276309999999057,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-week-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-week-ahead.md should reference stakeholder-perspectives artifact","duration":2.920026000000007,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-weekly-review.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-weekly-review.md should reference stakeholder-perspectives artifact","duration":2.9126730000000407,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-year-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-year-ahead.md should reference stakeholder-perspectives artifact","duration":2.97968800000001,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]}],"startTime":1787953663153,"endTime":1787953663473.9797,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/network-diagnostics.test.ts"},{"assertionResults":[{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring wires polling, calendar, lagradet, and RSS context scripts","status":"passed","title":"wires polling, calendar, lagradet, and RSS context scripts","duration":3.8962250000000154,"failureMessages":[],"location":{"line":9,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring exposes optional inputs for calendar org, Lagrådet reference, and RSS dok_ids","status":"passed","title":"exposes optional inputs for calendar org, Lagrådet reference, and RSS dok_ids","duration":0.8737360000000081,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring writes transient pre-warm context artifacts under ignored data/runtime","status":"passed","title":"writes transient pre-warm context artifacts under ignored data/runtime","duration":0.5394099999999753,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring derives optional Lagrådet and RSS watch inputs from latest PIR context when inputs are empty","status":"passed","title":"derives optional Lagrådet and RSS watch inputs from latest PIR context when inputs are empty","duration":0.40877499999999145,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]}],"startTime":1787953935870,"endTime":1787953935875.4087,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-prewarm-context-scripts.test.ts"},{"assertionResults":[{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour happy path: writes ARTICLE_DATE / SUBFOLDER / ANALYSIS_DEPTH / FORCE_GENERATION to $GITHUB_ENV","status":"passed","title":"happy path: writes ARTICLE_DATE / SUBFOLDER / ANALYSIS_DEPTH / FORCE_GENERATION to $GITHUB_ENV","duration":12.638585999999975,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour empty article-date defaults to today (UTC, YYYY-MM-DD)","status":"passed","title":"empty article-date defaults to today (UTC, YYYY-MM-DD)","duration":10.078737999999987,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects malformed article_date with an ::error:: annotation","status":"passed","title":"rejects malformed article_date with an ::error:: annotation","duration":8.583320000000015,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects unknown analysis_depth","status":"passed","title":"rejects unknown analysis_depth","duration":9.343261999999982,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects subfolder values with invalid grammar","status":"passed","title":"rejects subfolder values with invalid grammar","duration":6.357762999999977,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour expands language presets for news-translate","status":"passed","title":"expands language presets for news-translate","duration":12.014049999999997,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour clamps out-of-range max_briefs to 2 with a warning","status":"passed","title":"clamps out-of-range max_briefs to 2 with a warning","duration":11.122519000000011,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates cycle_anchor against current|next|both","status":"passed","title":"validates cycle_anchor against current|next|both","duration":19.894884999999988,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates lookback_hours as a positive integer","status":"passed","title":"validates lookback_hours as a positive integer","duration":21.994871999999987,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates focus against votes|debates|questions|all","status":"passed","title":"validates focus against votes|debates|questions|all","duration":19.01087599999994,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates article_types as a comma list of [a-z][a-z0-9-]* tokens","status":"passed","title":"validates article_types as a comma list of [a-z][a-z0-9-]* tokens","duration":21.60297300000002,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects non-canonical boolean values for force_generation and force_retranslate","status":"passed","title":"rejects non-canonical boolean values for force_generation and force_retranslate","duration":18.16556099999991,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour accepts only literal `true` / `false` / empty for force_generation","status":"passed","title":"accepts only literal `true` / `false` / empty for force_generation","duration":83.92504399999996,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]}],"startTime":1787953829776,"endTime":1787953830030.925,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-resolve-inputs-runtime.test.ts"},{"assertionResults":[{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action declares the canonical env-export contract documented in 00-base-contract.md","status":"passed","title":"declares the canonical env-export contract documented in 00-base-contract.md","duration":4.22941000000003,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action rejects malformed article_date (YYYY-MM-DD enforced)","status":"passed","title":"rejects malformed article_date (YYYY-MM-DD enforced)","duration":0.7608040000000074,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts analysis_depth to standard|deep|comprehensive","status":"passed","title":"restricts analysis_depth to standard|deep|comprehensive","duration":0.41046899999997777,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts cycle_anchor to current|next|both","status":"passed","title":"restricts cycle_anchor to current|next|both","duration":0.3424810000000207,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts focus to votes|debates|questions|all","status":"passed","title":"restricts focus to votes|debates|questions|all","duration":0.5124299999999948,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action clamps out-of-range max_briefs to 2 with a warning (matches prior news-translate behaviour)","status":"passed","title":"clamps out-of-range max_briefs to 2 with a warning (matches prior news-translate behaviour)","duration":0.5500200000000177,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action expands the news-translate language presets","status":"passed","title":"expands the news-translate language presets","duration":0.5231499999999869,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action emits a \"Resolved workflow inputs\" audit group to the step log","status":"passed","title":"emits a \"Resolved workflow inputs\" audit group to the step log","duration":0.35312099999998736,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm every news-*.md uses news-prewarm","status":"passed","title":"every news-*.md uses news-prewarm","duration":1.6482159999999908,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-propositions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-propositions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.9976479999999697,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-motions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-motions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6049029999999789,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-committee-reports.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-committee-reports.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.44844000000000506,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-interpellations.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-interpellations.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.48610000000002174,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-week-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-week-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.46253600000000006,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-month-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-month-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.4922409999999786,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-quarter-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-quarter-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.5347919999999817,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-year-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-year-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.8141140000000178,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-election-cycle.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-election-cycle.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.7510770000000093,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-weekly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-weekly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6005649999999605,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-monthly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-monthly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6002550000000042,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-evening-analysis.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-evening-analysis.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.8825429999999983,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-realtime-monitor.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-realtime-monitor.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.717583999999988,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-translate.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-translate.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.9332780000000298,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md lists every canonical env var","status":"passed","title":"lists every canonical env var","duration":0.7877950000000169,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md cites the news-resolve-inputs composite as the propagation mechanism","status":"passed","title":"cites the news-resolve-inputs composite as the propagation mechanism","duration":0.515235999999959,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md forbids recomputing ARTICLE_DATE/SUBFOLDER inside agent prompts","status":"passed","title":"forbids recomputing ARTICLE_DATE/SUBFOLDER inside agent prompts","duration":0.6416009999999801,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]}],"startTime":1787953828820,"endTime":1787953828841.6416,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-resolve-inputs.test.ts"},{"assertionResults":[{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface declares no scb (pxweb) data MCP server","status":"passed","title":"declares no scb (pxweb) data MCP server","duration":3.887367999999981,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface declares no world-bank data MCP server","status":"passed","title":"declares no world-bank data MCP server","duration":0.7387729999999806,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface does not load the full github toolset (`toolsets: [all]`)","status":"passed","title":"does not load the full github toolset (`toolsets: [all]`)","duration":0.6921760000000177,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface keeps the injected github MCP read-only and minimal for safe-outputs","status":"passed","title":"keeps the injected github MCP read-only and minimal for safe-outputs","duration":0.4264689999999973,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface drops web-fetch and agentic-workflows tools","status":"passed","title":"drops web-fetch and agentic-workflows tools","duration":0.7034370000000081,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface narrows the kept riksdag-regering server to the health-gate tool only","status":"passed","title":"narrows the kept riksdag-regering server to the health-gate tool only","duration":0.6718179999999734,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface keeps the contract-required riksdag-regering MCP URL","status":"passed","title":"keeps the contract-required riksdag-regering MCP URL","duration":0.41693099999997685,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface re-baselines max_langs default to 13 (a full source in one run)","status":"passed","title":"re-baselines max_langs default to 13 (a full source in one run)","duration":0.3139679999999885,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]}],"startTime":1787953896864,"endTime":1787953896872.314,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-translate-mcp-surface.test.ts"},{"assertionResults":[{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox never writes the worklist file to /tmp (runner-only, invisible to AWF container)","status":"passed","title":"never writes the worklist file to /tmp (runner-only, invisible to AWF container)","duration":3.6387230000000272,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox writes the worklist file under ${GITHUB_WORKSPACE} so AWF --add-dir exposes it","status":"passed","title":"writes the worklist file under ${GITHUB_WORKSPACE} so AWF --add-dir exposes it","duration":0.5483159999999998,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox writes TRANSLATION_WORKLIST and friends to $GITHUB_ENV (not only $GITHUB_OUTPUT)","status":"passed","title":"writes TRANSLATION_WORKLIST and friends to $GITHUB_ENV (not only $GITHUB_OUTPUT)","duration":1.1091460000000097,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox agent prompt body reads env vars, not unreachable step outputs","status":"passed","title":"agent prompt body reads env vars, not unreachable step outputs","duration":0.669524000000024,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox base contract documents the news-translate runtime env vars","status":"passed","title":"base contract documents the news-translate runtime env vars","duration":0.4999960000000101,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox .gitignore excludes the workspace-scoped worklist file","status":"passed","title":".gitignore excludes the workspace-scoped worklist file","duration":0.46432900000002064,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox emit_bundle is used in every exit path of the worklist step (no leaked OUTPUT-only writes)","status":"passed","title":"emit_bundle is used in every exit path of the worklist step (no leaked OUTPUT-only writes)","duration":0.5226480000000038,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox caps the per-run language batch via max_langs (effective-token control)","status":"passed","title":"caps the per-run language batch via max_langs (effective-token control)","duration":0.6563090000000216,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox scopes the agent's validator calls to the per-run language batch","status":"passed","title":"scopes the agent's validator calls to the per-run language batch","duration":0.5795549999999707,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]}],"startTime":1787953839649,"endTime":1787953839657.5796,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-translate-worklist-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts realtime monitor is scheduled for the 15:30 UTC catch-up window","status":"passed","title":"realtime monitor is scheduled for the 15:30 UTC catch-up window","duration":3.645655999999974,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts content-generating news workflows use the claude-opus-4.8 reasoning model","status":"passed","title":"content-generating news workflows use the claude-opus-4.8 reasoning model","duration":0.7872340000000122,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts the translation workflow stays on the claude-sonnet-4.6 throughput model","status":"passed","title":"the translation workflow stays on the claude-sonnet-4.6 throughput model","duration":0.5281089999999722,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts analysis gate requires explicit full pass-2 declaration and canonical rerun schema fields","status":"passed","title":"analysis gate requires explicit full pass-2 declaration and canonical rerun schema fields","duration":0.5359439999999722,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts methodology-reflection template exposes canonical Pass-2 and Re-run log slots","status":"passed","title":"methodology-reflection template exposes canonical Pass-2 and Re-run log slots","duration":0.8027129999999829,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts time-budget self-monitoring helper is defined in 01 and consumed by 02/03/04/05/06","status":"passed","title":"time-budget self-monitoring helper is defined in 01 and consumed by 02/03/04/05/06","duration":1.125066000000004,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts early-scaffold marker is mandated in 03-data-download.md","status":"passed","title":"early-scaffold marker is mandated in 03-data-download.md","duration":0.7652630000000045,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]}],"startTime":1787953894128,"endTime":1787953894135.7654,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-workflow-pass2-budget-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding discovers all 14 news workflow sources","status":"passed","title":"discovers all 14 news workflow sources","duration":3.719404000000054,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-committee-reports.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-committee-reports.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.9581739999999854,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-election-cycle.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-election-cycle.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.537495999999976,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-evening-analysis.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-evening-analysis.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.37525300000004336,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-interpellations.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-interpellations.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4458450000000198,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-month-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-month-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4306359999999927,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-monthly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-monthly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.5082219999999893,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-motions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-motions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.38913800000000265,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-propositions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-propositions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4476179999999772,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-quarter-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-quarter-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4179430000000366,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-realtime-monitor.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-realtime-monitor.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4233729999999696,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-translate.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-translate.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.47032000000001517,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-week-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-week-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.37143599999996013,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-weekly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-weekly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.350387000000012,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-year-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-year-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4395230000000083,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action declares the IMF SDMX subscription key input"],"fullName":"news-prewarm composite action declares the IMF SDMX subscription key input exposes an `imf-sdmx-subscription-key` input AND exports it to $GITHUB_ENV","status":"passed","title":"exposes an `imf-sdmx-subscription-key` input AND exports it to $GITHUB_ENV","duration":0.8110279999999648,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action declares the IMF SDMX subscription key input"],"fullName":"news-prewarm composite action declares the IMF SDMX subscription key input does not embed `${{ ... }}` template expressions referencing `secrets` or other unsupported contexts","status":"passed","title":"does not embed `${{ ... }}` template expressions referencing `secrets` or other unsupported contexts","duration":0.5363239999999792,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]}],"startTime":1787953893216,"endTime":1787953893228.5364,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-workflows-imf-secret.test.ts"},{"assertionResults":[{"ancestorTitles":["no external CDN in runtime JavaScript"],"fullName":"no external CDN in runtime JavaScript no js runtime file loads code from an external CDN host","status":"passed","title":"no js runtime file loads code from an external CDN host","duration":9.867295000000013,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["no external CDN in runtime JavaScript"],"fullName":"no external CDN in runtime JavaScript mermaid-init.mjs imports Mermaid from the vendored same-origin path","status":"passed","title":"mermaid-init.mjs imports Mermaid from the vendored same-origin path","duration":1.0261610000000019,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["no external CDN in rendered news articles"],"fullName":"no external CDN in rendered news articles no rendered news article references an external CDN host","status":"passed","title":"no rendered news article references an external CDN host","duration":7067.9954419999995,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]}],"startTime":1787953857854,"endTime":1787953864932.9954,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/no-external-cdn.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should parse CSV with headers","status":"passed","title":"should parse CSV with headers","duration":5.808335999999997,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should return empty array for empty input","status":"passed","title":"should return empty array for empty input","duration":0.6320729999999912,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should return empty array for header-only CSV","status":"passed","title":"should return empty array for header-only CSV","duration":0.52346,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should parse CSV with headers using fallback parser","status":"passed","title":"should parse CSV with headers using fallback parser","duration":0.8495209999999815,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should return empty array for empty input","status":"passed","title":"should return empty array for empty input","duration":0.4670239999999808,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should return empty array for header-only CSV","status":"passed","title":"should return empty array for header-only CSV","duration":0.6408999999999878,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should handle quoted fields","status":"passed","title":"should handle quoted fields","duration":0.7589810000000057,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should skip empty lines","status":"passed","title":"should skip empty lines","duration":0.5470550000000003,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should not use d3.csvParse (CSP-unsafe)","status":"passed","title":"should not use d3.csvParse (CSP-unsafe)","duration":0.8317079999999919,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]}],"startTime":1787953910016,"endTime":1787953910026.8318,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parse-csv.test.ts"},{"assertionResults":[{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have party dashboard container","status":"passed","title":"should have party dashboard container","duration":11.383752999999956,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have dashboard title and description","status":"passed","title":"should have dashboard title and description","duration":5.316473999999971,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have footer with data source attribution","status":"passed","title":"should have footer with data source attribution","duration":2.5756620000000225,"failureMessages":[],"location":{"line":85,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyEffectivenessChart canvas","status":"passed","title":"should have partyEffectivenessChart canvas","duration":2.8463890000000447,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyEffectivenessChart should have ARIA role and label","status":"passed","title":"partyEffectivenessChart should have ARIA role and label","duration":3.3495210000000384,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyEffectivenessChart should have screen reader only text","status":"passed","title":"partyEffectivenessChart should have screen reader only text","duration":3.587327000000016,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyComparisonChart canvas","status":"passed","title":"should have partyComparisonChart canvas","duration":2.0675509999999804,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyComparisonChart should have ARIA role and label","status":"passed","title":"partyComparisonChart should have ARIA role and label","duration":2.521370999999988,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyComparisonChart should have screen reader only text","status":"passed","title":"partyComparisonChart should have screen reader only text","duration":2.0946119999999837,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyMomentumChart canvas","status":"passed","title":"should have partyMomentumChart canvas","duration":1.755205999999987,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyMomentumChart should have ARIA role and label","status":"passed","title":"partyMomentumChart should have ARIA role and label","duration":2.075615999999968,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyMomentumChart should have screen reader only text","status":"passed","title":"partyMomentumChart should have screen reader only text","duration":2.449025000000006,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have coalitionAlignmentChart div container","status":"passed","title":"should have coalitionAlignmentChart div container","duration":1.7208120000000235,"failureMessages":[],"location":{"line":129,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility should have semantic HTML structure","status":"passed","title":"should have semantic HTML structure","duration":4.906406000000061,"failureMessages":[],"location":{"line":143,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility all charts should have proper ARIA attributes","status":"passed","title":"all charts should have proper ARIA attributes","duration":1.802184000000011,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility should have screen reader descriptions for all charts","status":"passed","title":"should have screen reader descriptions for all charts","duration":1.7978259999999864,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility external links should have target=\"_blank\"","status":"passed","title":"external links should have target=\"_blank\"","duration":2.6344830000000456,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Party Configuration"],"fullName":"Party Dashboard Party Configuration should support all 8 Swedish parties","status":"passed","title":"should support all 8 Swedish parties","duration":2.4417009999999664,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Party Configuration"],"fullName":"Party Dashboard Party Configuration should define party colors for Chart.js","status":"passed","title":"should define party colors for Chart.js","duration":2.4102830000000495,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyEffectivenessChart should expect line chart data structure","status":"passed","title":"partyEffectivenessChart should expect line chart data structure","duration":1.5503330000000233,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyComparisonChart should expect bar chart data structure","status":"passed","title":"partyComparisonChart should expect bar chart data structure","duration":1.7314419999999018,"failureMessages":[],"location":{"line":232,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types coalitionAlignmentChart should expect matrix/heatmap structure","status":"passed","title":"coalitionAlignmentChart should expect matrix/heatmap structure","duration":1.5144149999999854,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyMomentumChart should expect doughnut/pie chart structure","status":"passed","title":"partyMomentumChart should expect doughnut/pie chart structure","duration":1.4936870000000226,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Data Loading Structure"],"fullName":"Party Dashboard Data Loading Structure dashboard should be ready for real CIA CSV data","status":"passed","title":"dashboard should be ready for real CIA CSV data","duration":1.995657000000051,"failureMessages":[],"location":{"line":262,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Empty State Handling"],"fullName":"Party Dashboard Empty State Handling should have structure to display empty state messages","status":"passed","title":"should have structure to display empty state messages","duration":1.8640199999999822,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should use dashboard-grid for responsive layout","status":"passed","title":"should use dashboard-grid for responsive layout","duration":2.227440999999999,"failureMessages":[],"location":{"line":305,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should have chart cards for consistent styling","status":"passed","title":"should have chart cards for consistent styling","duration":1.842520000000036,"failureMessages":[],"location":{"line":311,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should have grid layout structure","status":"passed","title":"should have grid layout structure","duration":1.703640000000064,"failureMessages":[],"location":{"line":320,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Multi-Language Support"],"fullName":"Party Dashboard Multi-Language Support should have structure ready for i18n translations","status":"passed","title":"should have structure ready for i18n translations","duration":1.910517000000027,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Multi-Language Support"],"fullName":"Party Dashboard Multi-Language Support should support Swedish party name translations","status":"passed","title":"should support Swedish party name translations","duration":6.142090000000053,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should convert 0-1 alignment_rate to percentage for display using real helper","status":"passed","title":"should convert 0-1 alignment_rate to percentage for display using real helper","duration":2.1821260000000393,"failureMessages":[],"location":{"line":367,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should NOT show alignment as 1% when rate is 0.84","status":"passed","title":"should NOT show alignment as 1% when rate is 0.84","duration":1.2058079999999336,"failureMessages":[],"location":{"line":375,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should handle various alignment rates correctly via real helper","status":"passed","title":"should handle various alignment rates correctly via real helper","duration":1.3018879999999626,"failureMessages":[],"location":{"line":385,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should handle momentum filter with zero values","status":"passed","title":"should handle momentum filter with zero values","duration":1.408015999999975,"failureMessages":[],"location":{"line":399,"column":5},"meta":{},"tags":[]}],"startTime":1787953686510,"endTime":1787953686600.408,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/party-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["political-context enrichment"],"fullName":"political-context enrichment expands first party abbreviation and wraps glossary first occurrence in abbr tooltip","status":"passed","title":"expands first party abbreviation and wraps glossary first occurrence in abbr tooltip","duration":20.532925999999975,"failureMessages":[],"location":{"line":7,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-context enrichment"],"fullName":"political-context enrichment uses language-aware context depth","status":"passed","title":"uses language-aware context depth","duration":5.635753000000022,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml political context block"],"fullName":"renderArticleHtml political context block renders collapsible political context on non-Swedish pages with comparative anchors","status":"passed","title":"renders collapsible political context on non-Swedish pages with comparative anchors","duration":68.87869,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml political context block"],"fullName":"renderArticleHtml political context block renders political context with reduced depth for Swedish pages","status":"passed","title":"renders political context with reduced depth for Swedish pages","duration":16.129550999999992,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953915532,"endTime":1787953915643.1296,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/political-context.test.ts"},{"assertionResults":[{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":4.22788700000001,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the en entry has non-empty title, subtitle, and section labels","status":"passed","title":"the en entry has non-empty title, subtitle, and section labels","duration":0.8054879999999685,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the sv entry has non-empty title, subtitle, and section labels","status":"passed","title":"the sv entry has non-empty title, subtitle, and section labels","duration":0.7252480000000219,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the da entry has non-empty title, subtitle, and section labels","status":"passed","title":"the da entry has non-empty title, subtitle, and section labels","duration":0.4427689999999984,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the no entry has non-empty title, subtitle, and section labels","status":"passed","title":"the no entry has non-empty title, subtitle, and section labels","duration":0.5762990000000059,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the fi entry has non-empty title, subtitle, and section labels","status":"passed","title":"the fi entry has non-empty title, subtitle, and section labels","duration":0.4696800000000394,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the de entry has non-empty title, subtitle, and section labels","status":"passed","title":"the de entry has non-empty title, subtitle, and section labels","duration":0.6559379999999919,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the fr entry has non-empty title, subtitle, and section labels","status":"passed","title":"the fr entry has non-empty title, subtitle, and section labels","duration":0.40660099999996646,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the es entry has non-empty title, subtitle, and section labels","status":"passed","title":"the es entry has non-empty title, subtitle, and section labels","duration":0.579734999999971,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the nl entry has non-empty title, subtitle, and section labels","status":"passed","title":"the nl entry has non-empty title, subtitle, and section labels","duration":0.41588899999999285,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ar entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ar entry has non-empty title, subtitle, and section labels","duration":0.5673419999999965,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the he entry has non-empty title, subtitle, and section labels","status":"passed","title":"the he entry has non-empty title, subtitle, and section labels","duration":0.3882669999999848,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ja entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ja entry has non-empty title, subtitle, and section labels","duration":0.44297000000000253,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ko entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ko entry has non-empty title, subtitle, and section labels","duration":0.49928399999998874,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the zh entry has non-empty title, subtitle, and section labels","status":"passed","title":"the zh entry has non-empty title, subtitle, and section labels","duration":0.46406899999999496,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS exposes the stat-label / a11y strings the dashboard needs","status":"passed","title":"exposes the stat-label / a11y strings the dashboard needs","duration":2.4255319999999756,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META exports a non-empty methodology catalogue","status":"passed","title":"exports a non-empty methodology catalogue","duration":0.5215469999999982,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META every methodology entry carries an icon and English description","status":"passed","title":"every methodology entry carries an icon and English description","duration":1.8342839999999683,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META English descriptions cover at least one of the catalogued methodology files","status":"passed","title":"English descriptions cover at least one of the catalogued methodology files","duration":0.4583989999999858,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/template-i18n.ts — TEMPLATE_META"],"fullName":"political-intelligence/i18n/template-i18n.ts — TEMPLATE_META exports a non-empty template catalogue","status":"passed","title":"exports a non-empty template catalogue","duration":0.4241840000000252,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/template-i18n.ts — TEMPLATE_META"],"fullName":"political-intelligence/i18n/template-i18n.ts — TEMPLATE_META every template entry carries an icon and description","status":"passed","title":"every template entry carries an icon and description","duration":3.6825450000000046,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers exports a non-empty stream catalogue","status":"passed","title":"exports a non-empty stream catalogue","duration":0.44454200000001265,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers every stream entry carries an icon and description","status":"passed","title":"every stream entry carries an icon and description","duration":0.8996549999999957,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamIcon returns the catalogued icon for known streams","status":"passed","title":"streamIcon returns the catalogued icon for known streams","duration":0.44841900000000123,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamIcon returns a non-empty fallback for unknown stream names","status":"passed","title":"streamIcon returns a non-empty fallback for unknown stream names","duration":0.535773000000006,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamDisplayName returns a non-empty string for unknown stream names","status":"passed","title":"streamDisplayName returns a non-empty string for unknown stream names","duration":0.7072039999999902,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamDescription returns a non-empty string in every language for catalogued streams","status":"passed","title":"streamDescription returns a non-empty string in every language for catalogued streams","duration":3.396179000000018,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers prettifyStream uppercases each word and replaces dashes with spaces","status":"passed","title":"prettifyStream uppercases each word and replaces dashes with spaces","duration":0.5601790000000619,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers prettifyMarkdownTitle strips .md / .json and Title-Cases the slug","status":"passed","title":"prettifyMarkdownTitle strips .md / .json and Title-Cases the slug","duration":0.6773179999999002,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers artifactTitle returns a non-empty localised string for every catalogued slug × language","status":"passed","title":"artifactTitle returns a non-empty localised string for every catalogued slug × language","duration":2.2042069999999967,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers artifactTitle prettifies unknown slugs by capitalising and replacing dashes","status":"passed","title":"artifactTitle prettifies unknown slugs by capitalising and replacing dashes","duration":0.6249399999999241,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactBaseName strips a directory prefix and returns the bare filename","status":"passed","title":"artifactBaseName strips a directory prefix and returns the bare filename","duration":0.642814000000044,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactBaseName preserves the extension and date prefix in the filename","status":"passed","title":"artifactBaseName preserves the extension and date prefix in the filename","duration":0.5248420000000351,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon returns a non-empty emoji for every common file type","status":"passed","title":"artifactIcon returns a non-empty emoji for every common file type","duration":0.8621739999999818,"failureMessages":[],"location":{"line":213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon uses the curated TEMPLATE_META icon when the slug is catalogued","status":"passed","title":"artifactIcon uses the curated TEMPLATE_META icon when the slug is catalogued","duration":0.605953999999997,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon resolves alias siblings via FILENAME_ALIASES (stakeholder-impact → stakeholder-perspectives icon)","status":"passed","title":"artifactIcon resolves alias siblings via FILENAME_ALIASES (stakeholder-impact → stakeholder-perspectives icon)","duration":0.7842990000000327,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactTitle resolves alias siblings via FILENAME_ALIASES (political-classification → classification-results title)","status":"passed","title":"artifactTitle resolves alias siblings via FILENAME_ALIASES (political-classification → classification-results title)","duration":0.5687440000000379,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive returns 0 for an empty directory","status":"passed","title":"returns 0 for an empty directory","duration":1.1085359999999582,"failureMessages":[],"location":{"line":263,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive counts .md and .json files and ignores other extensions","status":"passed","title":"counts .md and .json files and ignores other extensions","duration":1.0402779999999439,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive recursively counts artifacts in subdirectories","status":"passed","title":"recursively counts artifacts in subdirectories","duration":1.026301999999987,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts returns empty array when stream directory does not exist","status":"passed","title":"returns empty array when stream directory does not exist","duration":1.404019000000062,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts collects .md and .json files sorted by relative path","status":"passed","title":"collects .md and .json files sorted by relative path","duration":9.07146499999999,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts collects artifacts from nested subdirectories","status":"passed","title":"collects artifacts from nested subdirectories","duration":1.137880999999993,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts ignores files with unsupported extensions","status":"passed","title":"ignores files with unsupported extensions","duration":0.9814770000000408,"failureMessages":[],"location":{"line":333,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectDailyDays"],"fullName":"political-intelligence/daily-streams.ts — collectDailyDays returns empty array when analysis/daily directory does not exist","status":"passed","title":"returns empty array when analysis/daily directory does not exist","duration":1.0614470000000438,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]}],"startTime":1787953788985,"endTime":1787953789038.0615,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/political-intelligence-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch extracts a polling wave from provider HTML and computes aggregate means","status":"passed","title":"extracts a polling wave from provider HTML and computes aggregate means","duration":5.407564999999977,"failureMessages":[],"location":{"line":18,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch persists schema-valid polling context output","status":"passed","title":"persists schema-valid polling context output","duration":70.26870199999996,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch validates the committed _fixture placeholder against the schema","status":"passed","title":"validates the committed _fixture placeholder against the schema","duration":28.765860999999973,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch prefers discovered follow-up article before extracting from archive roots","status":"passed","title":"prefers discovered follow-up article before extracting from archive roots","duration":2.4534830000000056,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]}],"startTime":1787953902497,"endTime":1787953902604.4534,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/polling-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for October (start of new session)","status":"passed","title":"should return current session for October (start of new session)","duration":3.797079999999994,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for November","status":"passed","title":"should return current session for November","duration":0.6914239999999836,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for December","status":"passed","title":"should return current session for December","duration":0.4888559999999984,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for January","status":"passed","title":"should return previous session for January","duration":0.4944449999999847,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for March","status":"passed","title":"should return previous session for March","duration":0.5882510000000138,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for September (end of session)","status":"passed","title":"should return previous session for September (end of session)","duration":0.553937000000019,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistDownloadedData for full population"],"fullName":"populate-analysis-data integration persistDownloadedData for full population should persist all document types with correct directory structure","status":"passed","title":"should persist all document types with correct directory structure","duration":3.9895799999999895,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistDownloadedData for full population"],"fullName":"populate-analysis-data integration persistDownloadedData for full population should create date-stamped vote directory","status":"passed","title":"should create date-stamped vote directory","duration":1.443983000000003,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistEvents for calendar population"],"fullName":"populate-analysis-data integration persistEvents for calendar population should persist events to date-stamped directories","status":"passed","title":"should persist events to date-stamped directories","duration":1.5345729999999662,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistEvents for calendar population"],"fullName":"populate-analysis-data integration persistEvents for calendar population should handle events with \"from\" field instead of \"datum\"","status":"passed","title":"should handle events with \"from\" field instead of \"datum\"","duration":0.9003960000000006,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMPs for MP population"],"fullName":"populate-analysis-data integration persistMPs for MP population should persist MP profiles using intressent_id","status":"passed","title":"should persist MP profiles using intressent_id","duration":1.3158140000000458,"failureMessages":[],"location":{"line":165,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMPs for MP population"],"fullName":"populate-analysis-data integration persistMPs for MP population should handle large batch of MPs","status":"passed","title":"should handle large batch of MPs","duration":5.530866000000003,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","end-to-end population flow"],"fullName":"populate-analysis-data integration end-to-end population flow should persist all data types to the same root","status":"passed","title":"should persist all data types to the same root","duration":1.4347569999999905,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMCPResponse for government documents"],"fullName":"populate-analysis-data integration persistMCPResponse for government documents should persist government document to mcp-responses/riksdag-regering/search_regering/","status":"passed","title":"should persist government document to mcp-responses/riksdag-regering/search_regering/","duration":1.3687730000000329,"failureMessages":[],"location":{"line":235,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMCPResponse for government documents"],"fullName":"populate-analysis-data integration persistMCPResponse for government documents should persist voting groups to mcp-responses/riksdag-regering/get_voting_group/","status":"passed","title":"should persist voting groups to mcp-responses/riksdag-regering/get_voting_group/","duration":1.1467869999999607,"failureMessages":[],"location":{"line":256,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistWorldBankData for economic indicators"],"fullName":"populate-analysis-data integration persistWorldBankData for economic indicators should persist World Bank data under worldbank/{indicator}/","status":"passed","title":"should persist World Bank data under worldbank/{indicator}/","duration":2.0197520000000395,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistWorldBankData for economic indicators"],"fullName":"populate-analysis-data integration persistWorldBankData for economic indicators should handle multiple indicators for Sweden","status":"passed","title":"should handle multiple indicators for Sweden","duration":1.240222000000017,"failureMessages":[],"location":{"line":307,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistSCBData for Swedish statistics"],"fullName":"populate-analysis-data integration persistSCBData for Swedish statistics should persist SCB table data under scb/","status":"passed","title":"should persist SCB table data under scb/","duration":1.2035440000000222,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistSCBData for Swedish statistics"],"fullName":"populate-analysis-data integration persistSCBData for Swedish statistics should persist without query parameter","status":"passed","title":"should persist without query parameter","duration":0.8656710000000203,"failureMessages":[],"location":{"line":352,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","full end-to-end with all data types"],"fullName":"populate-analysis-data integration full end-to-end with all data types should populate all data type directories from a single root","status":"passed","title":"should populate all data type directories from a single root","duration":1.9969690000000355,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]}],"startTime":1787953785775,"endTime":1787953785807.997,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/populate-analysis-data.test.ts"},{"assertionResults":[{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath parses canonical analysis/daily/<date>/<sub>/executive-brief_<lang>.md","status":"passed","title":"parses canonical analysis/daily/<date>/<sub>/executive-brief_<lang>.md","duration":4.505525000000034,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath handles nested subfolders","status":"passed","title":"handles nested subfolders","duration":0.6513790000000199,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for the English source file (no _lang suffix)","status":"passed","title":"returns null for the English source file (no _lang suffix)","duration":0.5455910000000017,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for unrelated paths","status":"passed","title":"returns null for unrelated paths","duration":0.45824800000002597,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for an unknown language code","status":"passed","title":"returns null for an unknown language code","duration":0.4789469999999483,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips a translated Executive-Brief prefix from the H1","status":"passed","title":"strips a translated Executive-Brief prefix from the H1","duration":5.103895000000023,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips trailing date suffix from the H1","status":"passed","title":"strips trailing date suffix from the H1","duration":1.5844660000000204,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown does not rewrite an already-clean H1","status":"passed","title":"does not rewrite an already-clean H1","duration":2.215857999999969,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown preserves YAML frontmatter and locates the body H1","status":"passed","title":"preserves YAML frontmatter and locates the body H1","duration":1.063791999999978,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown preserves the H1 when the cleaned form would be too short","status":"passed","title":"preserves the H1 when the cleaned form would be too short","duration":0.7038679999999999,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown does nothing when there is no body H1","status":"passed","title":"does nothing when there is no body H1","duration":0.9917059999999651,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips translated boilerplate for DE briefs","status":"passed","title":"strips translated boilerplate for DE briefs","duration":0.8458740000000375,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (ar)","status":"passed","title":"skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (ar)","duration":1.003308000000004,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (he)","status":"passed","title":"skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (he)","duration":0.7460770000000139,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown rewrites an inline HTML <h1> as the title form","status":"passed","title":"rewrites an inline HTML <h1> as the title form","duration":0.862715000000037,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown rewrites a multi-line HTML <h1> block","status":"passed","title":"rewrites a multi-line HTML <h1> block","duration":0.7344550000000254,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips a leading hero image before the H1","status":"passed","title":"skips a leading hero image before the H1","duration":0.7798890000000256,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <center> wrapper and rewrites the inner H1","status":"passed","title":"skips leading <center> wrapper and rewrites the inner H1","duration":0.685794000000044,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips nested HTML tags from the heading text","status":"passed","title":"strips nested HTML tags from the heading text","duration":0.6938789999999813,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown returns no H1 when leading content is plain prose (no wrapper or heading)","status":"passed","title":"returns no H1 when leading content is plain prose (no wrapper or heading)","duration":0.5301130000000285,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) rewrites a brief on disk when the H1 changes","status":"passed","title":"rewrites a brief on disk when the H1 changes","duration":1.4268410000000245,"failureMessages":[],"location":{"line":269,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) reports \"unchanged\" when the H1 is already clean","status":"passed","title":"reports \"unchanged\" when the H1 is already clean","duration":0.9515010000000075,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) returns \"skipped\" for a non-canonical path","status":"passed","title":"returns \"skipped\" for a non-canonical path","duration":0.7260600000000181,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) returns \"error\" for a missing file","status":"passed","title":"returns \"error\" for a missing file","duration":0.5741350000000125,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]}],"startTime":1787953823827,"endTime":1787953823856.5742,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/postprocess-translated-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement download limit in 03-data-download.md keeps total under 100 files","status":"passed","title":"download limit in 03-data-download.md keeps total under 100 files","duration":4.334827000000018,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement 07-commit-and-pr.md contains mandatory 100-file guard","status":"passed","title":"07-commit-and-pr.md contains mandatory 100-file guard","duration":0.9375360000000228,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement all 14 news workflows have max-patch-files in safe-outputs block and ≤ 100","status":"passed","title":"all 14 news workflows have max-patch-files in safe-outputs block and ≤ 100","duration":2.527512999999999,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement existing analysis folders stay under file budget","status":"passed","title":"existing analysis folders stay under file budget","duration":14.095331999999985,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]}],"startTime":1787953855412,"endTime":1787953855434.0952,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pr-file-budget.test.ts"},{"assertionResults":[{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md derives <title> from brief H1 even when article.md frontmatter carries a different title","status":"passed","title":"derives <title> from brief H1 even when article.md frontmatter carries a different title","duration":105.15473099999997,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md works on body-only article.md (post-refactor shape) — no title/description in frontmatter","status":"passed","title":"works on body-only article.md (post-refactor shape) — no title/description in frontmatter","duration":7.09680800000001,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md gracefully falls back to article.md frontmatter when no brief markdown is supplied (legacy regenerator path)","status":"passed","title":"gracefully falls back to article.md frontmatter when no brief markdown is supplied (legacy regenerator path)","duration":4.722892999999999,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]}],"startTime":1787953889365,"endTime":1787953889481.723,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-from-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from aggregator.ts","status":"passed","title":"barrel re-exports every public symbol from aggregator.ts","duration":4.0839750000000095,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from markdown.ts","status":"passed","title":"barrel re-exports every public symbol from markdown.ts","duration":0.7063630000000103,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from chrome.ts","status":"passed","title":"barrel re-exports every public symbol from chrome.ts","duration":0.5931910000000471,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from article.ts","status":"passed","title":"barrel re-exports every public symbol from article.ts","duration":0.46386900000004516,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from url-helpers.ts","status":"passed","title":"barrel re-exports every public symbol from url-helpers.ts","duration":0.5223379999999906,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from constants.ts","status":"passed","title":"barrel re-exports every public symbol from constants.ts","duration":0.539621000000011,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubBlobUrl strips any number of leading slashes","status":"passed","title":"buildGithubBlobUrl strips any number of leading slashes","duration":0.558685999999966,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubTreeUrl preserves embedded slashes and strips leading slashes","status":"passed","title":"buildGithubTreeUrl preserves embedded slashes and strips leading slashes","duration":0.41106999999999516,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubBlobUrl handles the empty segment case gracefully","status":"passed","title":"buildGithubBlobUrl handles the empty segment case gracefully","duration":1.334969000000001,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) exposes the full __test__ escape hatch with all expected helpers","status":"passed","title":"exposes the full __test__ escape hatch with all expected helpers","duration":0.6323229999999285,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) AGGREGATION_ORDER reflects the journalist-optimal narrative arc","status":"passed","title":"AGGREGATION_ORDER reflects the journalist-optimal narrative arc","duration":0.697035000000028,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) titleForArtifact never returns an empty string for any known artifact","status":"passed","title":"titleForArtifact never returns an empty string for any known artifact","duration":1.6737840000000688,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) aggregateAnalysis produces a proper AggregationResult shape","status":"passed","title":"aggregateAnalysis produces a proper AggregationResult shape","duration":24.42297499999995,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) sanitizeSchema allowlists mermaid className on <pre>","status":"passed","title":"sanitizeSchema allowlists mermaid className on <pre>","duration":0.6412399999999252,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) sanitizeSchema allowlists id on h1..h6 (rehype-slug output)","status":"passed","title":"sanitizeSchema allowlists id on h1..h6 (rehype-slug output)","duration":0.9103450000000066,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml is async and returns HTML for a trivial paragraph","status":"passed","title":"renderMarkdownToHtml is async and returns HTML for a trivial paragraph","duration":19.32242599999995,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml strips <style> tags (not in allowlist)","status":"passed","title":"renderMarkdownToHtml strips <style> tags (not in allowlist)","duration":4.9496259999999666,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml escapes raw text inside mermaid fences","status":"passed","title":"renderMarkdownToHtml escapes raw text inside mermaid fences","duration":9.106299000000035,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) renderChromeHead is a synchronous string builder","status":"passed","title":"renderChromeHead is a synchronous string builder","duration":1.5015809999999874,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome returns head/headerHtml/footerHtml as non-empty strings","status":"passed","title":"buildChrome returns head/headerHtml/footerHtml as non-empty strings","duration":2.21396500000003,"failureMessages":[],"location":{"line":292,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome is deterministic for identical inputs within the same second","status":"passed","title":"buildChrome is deterministic for identical inputs within the same second","duration":1.2562920000000304,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome preserves all 14 LANGUAGES reference in the switcher (13 in dropdown + current)","status":"passed","title":"buildChrome preserves all 14 LANGUAGES reference in the switcher (13 in dropdown + current)","duration":1.5811610000000655,"failureMessages":[],"location":{"line":311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml composes head + header + body + sources + footer","status":"passed","title":"renderArticleHtml composes head + header + body + sources + footer","duration":29.258736999999996,"failureMessages":[],"location":{"line":344,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml omits the sources block when artifactsUsed is empty","status":"passed","title":"renderArticleHtml omits the sources block when artifactsUsed is empty","duration":5.359874999999988,"failureMessages":[],"location":{"line":364,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml emits Schema.org NewsArticle JSON-LD with correct language","status":"passed","title":"renderArticleHtml emits Schema.org NewsArticle JSON-LD with correct language","duration":4.082432999999924,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml uses the dedicated News banner image and news-article body class","status":"passed","title":"renderArticleHtml uses the dedicated News banner image and news-article body class","duration":3.1046029999999973,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml emits reader guide BETWEEN executive brief and the rest of the body","status":"passed","title":"renderArticleHtml emits reader guide BETWEEN executive brief and the rest of the body","duration":44.82121299999994,"failureMessages":[],"location":{"line":391,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 splits at the second <h2 boundary","status":"passed","title":"splits at the second <h2 boundary","duration":0.8815000000000737,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 returns the entire body as lead when only one <h2 exists","status":"passed","title":"returns the entire body as lead when only one <h2 exists","duration":0.6145910000000185,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 returns the entire body as lead when no <h2 exists","status":"passed","title":"returns the entire body as lead when no <h2 exists","duration":0.5693870000000061,"failureMessages":[],"location":{"line":442,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib boundary (no CLI side-effect imports)"],"fullName":"render-lib boundary (no CLI side-effect imports) no file under scripts/render-lib/ imports from scripts/generate-sitemap-html","status":"passed","title":"no file under scripts/render-lib/ imports from scripts/generate-sitemap-html","duration":14.647834000000103,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for a Date instance","status":"passed","title":"returns YYYY-MM-DD for a Date instance","duration":0.6035610000000133,"failureMessages":[],"location":{"line":491,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for an ISO-8601 string","status":"passed","title":"returns YYYY-MM-DD for an ISO-8601 string","duration":0.5206150000000207,"failureMessages":[],"location":{"line":495,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for a bare YYYY-MM-DD string","status":"passed","title":"returns YYYY-MM-DD for a bare YYYY-MM-DD string","duration":0.4623659999999745,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when the value is undefined / null / wrong shape","status":"passed","title":"falls back to \"now\" when the value is undefined / null / wrong shape","duration":0.6282160000000658,"failureMessages":[],"location":{"line":503,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when the string does not start with YYYY-MM-DD","status":"passed","title":"falls back to \"now\" when the string does not start with YYYY-MM-DD","duration":0.44107599999995273,"failureMessages":[],"location":{"line":510,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when given an Invalid Date instance","status":"passed","title":"falls back to \"now\" when given an Invalid Date instance","duration":0.4513050000000476,"failureMessages":[],"location":{"line":515,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate uses the live clock when no `now` is supplied","status":"passed","title":"uses the live clock when no `now` is supplied","duration":2.412465999999995,"failureMessages":[],"location":{"line":519,"column":3},"meta":{},"tags":[]}],"startTime":1787953678955,"endTime":1787953679143.4124,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-architecture.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib/article-types helper","loadArticleTypesRegistry"],"fullName":"render-lib/article-types helper loadArticleTypesRegistry loads and returns a registry with types array","status":"passed","title":"loads and returns a registry with types array","duration":4.4312269999999785,"failureMessages":[],"location":{"line":26,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","loadArticleTypesRegistry"],"fullName":"render-lib/article-types helper loadArticleTypesRegistry caches on second call","status":"passed","title":"caches on second call","duration":0.6868160000000216,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns entry for known id","status":"passed","title":"returns entry for known id","duration":0.7115119999999706,"failureMessages":[],"location":{"line":41,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns undefined for unknown id","status":"passed","title":"returns undefined for unknown id","duration":0.49588799999997946,"failureMessages":[],"location":{"line":48,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns correct label for week-ahead","status":"passed","title":"returns correct label for week-ahead","duration":0.5751670000000217,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getBySubfolder"],"fullName":"render-lib/article-types helper getBySubfolder returns entry for known subfolder","status":"passed","title":"returns entry for known subfolder","duration":0.7171030000000087,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getBySubfolder"],"fullName":"render-lib/article-types helper getBySubfolder returns undefined for unknown subfolder","status":"passed","title":"returns undefined for unknown subfolder","duration":0.4960879999999861,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only single-type entries for single-type family","status":"passed","title":"returns only single-type entries for single-type family","duration":0.6822769999999991,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only long-horizon entries for long-horizon-forecast family","status":"passed","title":"returns only long-horizon entries for long-horizon-forecast family","duration":0.8020419999999717,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only tier-c entries for tier-c-aggregation family","status":"passed","title":"returns only tier-c entries for tier-c-aggregation family","duration":0.8007789999999773,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","allTypesSortedByHorizon"],"fullName":"render-lib/article-types helper allTypesSortedByHorizon returns all types sorted by horizonDays ascending","status":"passed","title":"returns all types sorted by horizonDays ascending","duration":1.161925999999994,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","forwardLookTypes"],"fullName":"render-lib/article-types helper forwardLookTypes returns long-horizon types sorted by horizonDays ascending","status":"passed","title":"returns long-horizon types sorted by horizonDays ascending","duration":1.6269660000000385,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","forwardLookTypes"],"fullName":"render-lib/article-types helper forwardLookTypes all entries have family long-horizon-forecast","status":"passed","title":"all entries have family long-horizon-forecast","duration":0.6902919999999995,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","round-trip: type → getById → fields"],"fullName":"render-lib/article-types helper round-trip: type → getById → fields every registry type is accessible via getById","status":"passed","title":"every registry type is accessible via getById","duration":1.4026969999999892,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","round-trip: type → getById → fields"],"fullName":"render-lib/article-types helper round-trip: type → getById → fields every registry type is accessible via getBySubfolder","status":"passed","title":"every registry type is accessible via getBySubfolder","duration":1.1094269999999824,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","registry-driven band counts (horizonBands)"],"fullName":"render-lib/article-types helper registry-driven band counts (horizonBands) registry contains expected horizon bands","status":"passed","title":"registry contains expected horizon bands","duration":1.2313860000000432,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","registry-driven band counts (horizonBands)"],"fullName":"render-lib/article-types helper registry-driven band counts (horizonBands) band days are strictly increasing","status":"passed","title":"band days are strictly increasing","duration":0.7456659999999715,"failureMessages":[],"location":{"line":164,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","SEO labels match registry"],"fullName":"render-lib/article-types helper SEO labels match registry every type has a non-empty label","status":"passed","title":"every type has a non-empty label","duration":0.8723630000000071,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","SEO labels match registry"],"fullName":"render-lib/article-types helper SEO labels match registry every type has a non-empty icon","status":"passed","title":"every type has a non-empty icon","duration":0.9126090000000318,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","hypothetical new type integration"],"fullName":"render-lib/article-types helper hypothetical new type integration adding a type to registry would make it discoverable (simulation)","status":"passed","title":"adding a type to registry would make it discoverable (simulation)","duration":0.6724290000000224,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]}],"startTime":1787953853958,"endTime":1787953853979.6724,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order AGGREGATION_ORDER opens with the executive brief","status":"passed","title":"AGGREGATION_ORDER opens with the executive brief","duration":3.821553999999992,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order AGGREGATION_ORDER closes with the audit-appendix manifest","status":"passed","title":"AGGREGATION_ORDER closes with the audit-appendix manifest","duration":0.5223480000000791,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order titleForArtifact maps known files to curated titles","status":"passed","title":"titleForArtifact maps known files to curated titles","duration":0.5246220000000221,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order titleForArtifact falls back to prettifyFallbackTitle for unknown files","status":"passed","title":"titleForArtifact falls back to prettifyFallbackTitle for unknown files","duration":0.5921789999999874,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order prettifyFallbackTitle is idempotent on already-prettified input","status":"passed","title":"prettifyFallbackTitle is idempotent on already-prettified input","duration":0.48209299999996347,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper exports a non-empty admin-field whitelist","status":"passed","title":"exports a non-empty admin-field whitelist","duration":1.3246599999999944,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches structured admin fragments only","status":"passed","title":"ADMIN_FIELD_RE matches structured admin fragments only","duration":6.236195000000066,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FRAGMENT_SPLITTER does not split on em-dash","status":"passed","title":"ADMIN_FRAGMENT_SPLITTER does not split on em-dash","duration":0.9629830000000084,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes pure-admin paragraphs anywhere","status":"passed","title":"stripLeadingAdminBylines removes pure-admin paragraphs anywhere","duration":0.8593079999999418,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches Round 7 leak fields (DIW Composite, WEP, Audience)","status":"passed","title":"ADMIN_FIELD_RE matches Round 7 leak fields (DIW Composite, WEP, Audience)","duration":0.5825210000000425,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes the realtime-pulse Audience admin block","status":"passed","title":"stripLeadingAdminBylines removes the realtime-pulse Audience admin block","duration":6.395502999999962,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes the propositions DIW Composite admin block","status":"passed","title":"stripLeadingAdminBylines removes the propositions DIW Composite admin block","duration":0.46390899999994417,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines accepts pipe-separated value continuations on admin lines","status":"passed","title":"stripLeadingAdminBylines accepts pipe-separated value continuations on admin lines","duration":0.49845299999992676,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines preserves prose containing pipes that are NOT admin","status":"passed","title":"stripLeadingAdminBylines preserves prose containing pipes that are NOT admin","duration":0.41889400000002297,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches Round 8 leak fields (Horizon / Workflow / Election Proximity / IMF vintage)","status":"passed","title":"ADMIN_FIELD_RE matches Round 8 leak fields (Horizon / Workflow / Election Proximity / IMF vintage)","duration":0.6172960000000103,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/pass-two — Pass 2 self-audit stripper"],"fullName":"aggregator/cleaning/pass-two — Pass 2 self-audit stripper exports a regex matching `## Pass 2 …` and emoji variants","status":"passed","title":"exports a regex matching `## Pass 2 …` and emoji variants","duration":0.6786099999999351,"failureMessages":[],"location":{"line":250,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/pass-two — Pass 2 self-audit stripper"],"fullName":"aggregator/cleaning/pass-two — Pass 2 self-audit stripper strips Pass 2 section through end-of-file","status":"passed","title":"strips Pass 2 section through end-of-file","duration":0.5610400000000482,"failureMessages":[],"location":{"line":256,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper exports a non-empty process-metadata whitelist","status":"passed","title":"exports a non-empty process-metadata whitelist","duration":0.46896800000001804,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper strips individual `**Confidence**: …` lines but preserves prose","status":"passed","title":"strips individual `**Confidence**: …` lines but preserves prose","duration":2.6730549999999766,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper PROCESS_META_LINE_RE has the global flag (multi-line replacement)","status":"passed","title":"PROCESS_META_LINE_RE has the global flag (multi-line replacement)","duration":0.3686800000000403,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter cleanArtifactBody strips front-matter, first H1, admin bylines, Pass 2","status":"passed","title":"cleanArtifactBody strips front-matter, first H1, admin bylines, Pass 2","duration":5.35269100000005,"failureMessages":[],"location":{"line":288,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter demoteHeadings demotes inner H2 → H3, caps at H6","status":"passed","title":"demoteHeadings demotes inner H2 → H3, caps at H6","duration":0.44824900000003254,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter demoteHeadings does not affect headings inside fenced code","status":"passed","title":"demoteHeadings does not affect headings inside fenced code","duration":0.4206370000000561,"failureMessages":[],"location":{"line":318,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter stripSourcePreamble removes `_Source: file.md_` italic lines","status":"passed","title":"stripSourcePreamble removes `_Source: file.md_` italic lines","duration":0.41588899999999285,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter rewriteRelativeLinks rewrites .md links to absolute GitHub blob URLs","status":"passed","title":"rewriteRelativeLinks rewrites .md links to absolute GitHub blob URLs","duration":0.6380239999999731,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter rewriteRelativeLinks leaves absolute URLs untouched","status":"passed","title":"rewriteRelativeLinks leaves absolute URLs untouched","duration":0.5075500000000375,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers SENTENCE_END_RE matches Latin / CJK / Devanagari terminators","status":"passed","title":"SENTENCE_END_RE matches Latin / CJK / Devanagari terminators","duration":0.659144000000083,"failureMessages":[],"location":{"line":349,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers markdownInlineToText strips emphasis + links to plain text","status":"passed","title":"markdownInlineToText strips emphasis + links to plain text","duration":0.5631449999999631,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary returns input unchanged when within window","status":"passed","title":"truncateToSentenceBoundary returns input unchanged when within window","duration":0.5539570000000822,"failureMessages":[],"location":{"line":365,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary cuts at sentence end inside window","status":"passed","title":"truncateToSentenceBoundary cuts at sentence end inside window","duration":0.6253009999999222,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary handles single-token pathological input","status":"passed","title":"truncateToSentenceBoundary handles single-token pathological input","duration":1.223540000000071,"failureMessages":[],"location":{"line":377,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut mid-sentence at \"prop.\" abbreviation","status":"passed","title":"truncateToSentenceBoundary does not cut mid-sentence at \"prop.\" abbreviation","duration":0.5186609999999519,"failureMessages":[],"location":{"line":388,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut at \"art.\" / \"Mr.\" / \"etc.\" abbreviations","status":"passed","title":"truncateToSentenceBoundary does not cut at \"art.\" / \"Mr.\" / \"etc.\" abbreviations","duration":0.6082880000000159,"failureMessages":[],"location":{"line":397,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary still cuts at real sentence ends after abbreviations","status":"passed","title":"truncateToSentenceBoundary still cuts at real sentence ends after abbreviations","duration":0.4566449999999804,"failureMessages":[],"location":{"line":406,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot recognises simple abbreviations (prop., Mr., etc.)","status":"passed","title":"isAbbreviationDot recognises simple abbreviations (prop., Mr., etc.)","duration":0.6166649999998981,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot recognises multi-dot abbreviations e.g., i.e., bl.a., d.v.s.","status":"passed","title":"isAbbreviationDot recognises multi-dot abbreviations e.g., i.e., bl.a., d.v.s.","duration":0.6662579999999707,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot does not false-positive on non-abbreviation prefix before known suffix","status":"passed","title":"isAbbreviationDot does not false-positive on non-abbreviation prefix before known suffix","duration":0.5190719999999374,"failureMessages":[],"location":{"line":443,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary handles multiple consecutive abbreviations","status":"passed","title":"truncateToSentenceBoundary handles multiple consecutive abbreviations","duration":0.5887129999999843,"failureMessages":[],"location":{"line":450,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut at e.g. / i.e. / bl.a.","status":"passed","title":"truncateToSentenceBoundary does not cut at e.g. / i.e. / bl.a.","duration":0.7452749999999924,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph returns null when no BLUF heading exists","status":"passed","title":"readBlufParagraph returns null when no BLUF heading exists","duration":1.7505270000000337,"failureMessages":[],"location":{"line":473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph returns the prose paragraph after `## 🎯 BLUF`","status":"passed","title":"readBlufParagraph returns the prose paragraph after `## 🎯 BLUF`","duration":5.424385000000029,"failureMessages":[],"location":{"line":477,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readFirstParagraph skips admin paragraphs","status":"passed","title":"readFirstParagraph skips admin paragraphs","duration":1.183887000000027,"failureMessages":[],"location":{"line":482,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers stripBlufLabel removes leading BLUF: / TL;DR: / Bottom Line: prefixes and list markers","status":"passed","title":"stripBlufLabel removes leading BLUF: / TL;DR: / Bottom Line: prefixes and list markers","duration":0.9952430000000732,"failureMessages":[],"location":{"line":496,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers stripBlufLabel preserves prose without a BLUF prefix","status":"passed","title":"stripBlufLabel preserves prose without a BLUF prefix","duration":0.6250900000000001,"failureMessages":[],"location":{"line":509,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph strips BLUF: inline-label from the returned paragraph","status":"passed","title":"readBlufParagraph strips BLUF: inline-label from the returned paragraph","duration":1.0476409999999987,"failureMessages":[],"location":{"line":513,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## 📌 Sammanfattning\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## 📌 Sammanfattning\"","duration":6.367841999999996,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## 🎯 Slutsats\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## 🎯 Slutsats\"","duration":1.2852659999999787,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## 🎯 Konklusion\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## 🎯 Konklusion\"","duration":6.226917999999955,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## 📌 Sammenfatning\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## 📌 Sammenfatning\"","duration":1.399099000000092,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 🎯 Konklusjon\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 🎯 Konklusjon\"","duration":5.40041999999994,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 📌 Sammendrag\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 📌 Sammendrag\"","duration":1.3083299999999554,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## 🎯 Yhteenveto\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## 🎯 Yhteenveto\"","duration":6.015090999999984,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## 📌 Tiivistelmä\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## 📌 Tiivistelmä\"","duration":1.3027789999999868,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## 🎯 Zusammenfassung\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## 🎯 Zusammenfassung\"","duration":7.731664000000023,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## 📌 Fazit\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## 📌 Fazit\"","duration":1.9979999999999336,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## 🎯 Conclusion\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## 🎯 Conclusion\"","duration":5.5808680000000095,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## 📌 Résumé\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## 📌 Résumé\"","duration":1.8070529999999962,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## 🎯 Conclusión\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## 🎯 Conclusión\"","duration":7.303132000000005,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## 📌 Resumen ejecutivo\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## 📌 Resumen ejecutivo\"","duration":1.9217179999999416,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## 🎯 Conclusie\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## 🎯 Conclusie\"","duration":8.396849999999972,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## 📌 Samenvatting\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## 📌 Samenvatting\"","duration":1.8661130000000412,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 🎯 الملخص التنفيذي\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 🎯 الملخص التنفيذي\"","duration":5.086211999999932,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 📌 الخلاصة التنفيذية\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 📌 الخلاصة التنفيذية\"","duration":1.3257129999999506,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## 🎯 תמצית מנהלים\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## 🎯 תמצית מנהלים\"","duration":4.041557000000012,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## 📌 תקציר מנהלים\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## 📌 תקציר מנהלים\"","duration":1.3278060000000096,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 🎯 要約\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 🎯 要約\"","duration":3.506083999999987,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 📌 要旨\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 📌 要旨\"","duration":1.4051210000000083,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 🎯 핵심 요약\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 🎯 핵심 요약\"","duration":2.8821159999999963,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 📌 요약\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 📌 요약\"","duration":1.3308210000000145,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 🎯 执行摘要\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 🎯 执行摘要\"","duration":2.850586999999905,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 📌 核心摘要\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 📌 核心摘要\"","duration":1.3056950000000143,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## Övergripande bedömning\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## Övergripande bedömning\"","duration":2.5941459999999097,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## Underrättelsesummering\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## Underrättelsesummering\"","duration":1.3551969999999756,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 60-sekunders lesing (8 punkter)\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 60-sekunders lesing (8 punkter)\"","duration":2.4461690000000544,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## ⚡ Huippotason tiedustelu\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## ⚡ Huippotason tiedustelu\"","duration":1.1901889999999185,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## Beslutninger der kræves straks\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## Beslutninger der kræves straks\"","duration":2.800622999999973,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## Sofort erforderliche Entscheidungen\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## Sofort erforderliche Entscheidungen\"","duration":3.1956930000000057,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## Décisions immédiates requises\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## Décisions immédiates requises\"","duration":2.9630670000000237,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## Decisiones inmediatas requeridas\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## Decisiones inmediatas requeridas\"","duration":2.871216000000004,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## Onmiddellijk vereiste beslissingen\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## Onmiddellijk vereiste beslissingen\"","duration":2.8311499999999796,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 🎯 ملخص\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 🎯 ملخص\"","duration":1.4190770000000157,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## כותרת ראשית\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## כותרת ראשית\"","duration":1.3583129999999528,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## エグゼクティブサマリー\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## エグゼクティブサマリー\"","duration":1.6973470000000361,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 5点エグゼクティブサマリー\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 5点エグゼクティブサマリー\"","duration":1.6984300000000303,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 종합 평가\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 종합 평가\"","duration":1.3842820000000984,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 즉각적인 결정 사항\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 즉각적인 결정 사항\"","duration":1.3992499999999382,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 即刻所需决策\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 即刻所需决策\"","duration":1.4184150000000955,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 60秒阅读\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 60秒阅读\"","duration":1.4350469999999405,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph(md, \"en\") still matches the literal `BLUF` token for translated briefs that preserve the English acronym","status":"passed","title":"readBlufParagraph(md, \"en\") still matches the literal `BLUF` token for translated briefs that preserve the English acronym","duration":1.8361670000000458,"failureMessages":[],"location":{"line":584,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph(md) without a lang preserves legacy English-only behaviour","status":"passed","title":"readBlufParagraph(md) without a lang preserves legacy English-only behaviour","duration":1.48146399999996,"failureMessages":[],"location":{"line":594,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph accepts a blockquote-formatted BLUF body","status":"passed","title":"readBlufParagraph accepts a blockquote-formatted BLUF body","duration":1.6627630000000408,"failureMessages":[],"location":{"line":605,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers buildBlufHeadingRegex matches a parenthesised \"(BLUF)\" suffix variant","status":"passed","title":"buildBlufHeadingRegex matches a parenthesised \"(BLUF)\" suffix variant","duration":7.359598000000005,"failureMessages":[],"location":{"line":616,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers buildBlufHeadingRegex matches a CJK-script prefix before the keyword","status":"passed","title":"buildBlufHeadingRegex matches a CJK-script prefix before the keyword","duration":1.3548570000000382,"failureMessages":[],"location":{"line":628,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers cleanArtifactBody strips a leading Unicode bidi mark from RTL headings","status":"passed","title":"cleanArtifactBody strips a leading Unicode bidi mark from RTL headings","duration":1.4914230000000543,"failureMessages":[],"location":{"line":640,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] évaluation de situation synthétique is matched as BLUF (prevents fallthrough to Synthèse des risques)","status":"passed","title":"[fr] évaluation de situation synthétique is matched as BLUF (prevents fallthrough to Synthèse des risques)","duration":1.4729170000000522,"failureMessages":[],"location":{"line":663,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] síntesis de situación is matched as BLUF","status":"passed","title":"[es] síntesis de situación is matched as BLUF","duration":1.33147299999996,"failureMessages":[],"location":{"line":689,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] 态势简要评估 is matched as BLUF (prevents fallthrough to 风险摘要)","status":"passed","title":"[zh] 态势简要评估 is matched as BLUF (prevents fallthrough to 风险摘要)","duration":1.8426299999999856,"failureMessages":[],"location":{"line":709,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis readFirstHeading returns the H1 text without the leading `# `","status":"passed","title":"readFirstHeading returns the H1 text without the leading `# `","duration":2.43625099999997,"failureMessages":[],"location":{"line":737,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips `Executive Brief — ` prefix and trailing date","status":"passed","title":"cleanArticleTitle strips `Executive Brief — ` prefix and trailing date","duration":3.3730450000000474,"failureMessages":[],"location":{"line":742,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips Swedish brief prefix `Exekutiv sammanfattning —`","status":"passed","title":"cleanArticleTitle strips Swedish brief prefix `Exekutiv sammanfattning —`","duration":1.9314050000000407,"failureMessages":[],"location":{"line":761,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips German brief prefix `Zusammenfassung —`","status":"passed","title":"cleanArticleTitle strips German brief prefix `Zusammenfassung —`","duration":1.8206179999999677,"failureMessages":[],"location":{"line":771,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips French brief prefix `Résumé exécutif —`","status":"passed","title":"cleanArticleTitle strips French brief prefix `Résumé exécutif —`","duration":1.7945700000000215,"failureMessages":[],"location":{"line":781,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips Arabic brief prefix `ملخص تنفيذي —` (RTL)","status":"passed","title":"cleanArticleTitle strips Arabic brief prefix `ملخص تنفيذي —` (RTL)","duration":2.1750319999999874,"failureMessages":[],"location":{"line":791,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle without lang param falls back to EN strip only (legacy callers)","status":"passed","title":"cleanArticleTitle without lang param falls back to EN strip only (legacy callers)","duration":1.573515000000043,"failureMessages":[],"location":{"line":803,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle returns null when too short","status":"passed","title":"cleanArticleTitle returns null when too short","duration":2.0415719999999737,"failureMessages":[],"location":{"line":817,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf truncates at word boundary when first sentence too long","status":"passed","title":"titleFromBluf truncates at word boundary when first sentence too long","duration":2.9047580000000153,"failureMessages":[],"location":{"line":821,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf returns null on empty/null input","status":"passed","title":"titleFromBluf returns null on empty/null input","duration":1.4064329999999927,"failureMessages":[],"location":{"line":828,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle returns null when title equals prettified subfolder (boilerplate guard)","status":"passed","title":"cleanArticleTitle returns null when title equals prettified subfolder (boilerplate guard)","duration":2.9730959999999413,"failureMessages":[],"location":{"line":838,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle preserves a real story title even when subfolder is supplied","status":"passed","title":"cleanArticleTitle preserves a real story title even when subfolder is supplied","duration":1.4720350000000053,"failureMessages":[],"location":{"line":859,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading \"On <date>, \" prefix (no literal date in title)","status":"passed","title":"titleFromBluf strips a leading \"On <date>, \" prefix (no literal date in title)","duration":1.9483779999999342,"failureMessages":[],"location":{"line":868,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading weekday + date prefix when result remains grammatical","status":"passed","title":"titleFromBluf strips a leading weekday + date prefix when result remains grammatical","duration":1.6783120000000054,"failureMessages":[],"location":{"line":878,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS the date prefix when stripping would leave a verb-leading subjectless fragment","status":"passed","title":"titleFromBluf KEEPS the date prefix when stripping would leave a verb-leading subjectless fragment","duration":1.52991499999996,"failureMessages":[],"location":{"line":888,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading \"The week of <range>\" prefix","status":"passed","title":"titleFromBluf strips a leading \"The week of <range>\" prefix","duration":3.801205999999979,"failureMessages":[],"location":{"line":899,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not end on a trailing comma or coordinating connector","status":"passed","title":"titleFromBluf does not end on a trailing comma or coordinating connector","duration":1.8755210000000488,"failureMessages":[],"location":{"line":907,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf still returns null on empty input after date strip","status":"passed","title":"titleFromBluf still returns null on empty input after date strip","duration":1.6482150000000502,"failureMessages":[],"location":{"line":918,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading ordered-list marker (1. / 2) / -)","status":"passed","title":"titleFromBluf strips a leading ordered-list marker (1. / 2) / -)","duration":2.779182999999989,"failureMessages":[],"location":{"line":927,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle preserves a bare trailing uppercase `A` (live: `Tax Class A`, `Plan A`)","status":"passed","title":"cleanArticleTitle preserves a bare trailing uppercase `A` (live: `Tax Class A`, `Plan A`)","duration":1.6633640000000014,"failureMessages":[],"location":{"line":945,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips a bare trailing comma (live: `Sweden Evening Analysis,`)","status":"passed","title":"cleanArticleTitle strips a bare trailing comma (live: `Sweden Evening Analysis,`)","duration":1.6636040000000776,"failureMessages":[],"location":{"line":964,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips a bare trailing semicolon or colon","status":"passed","title":"cleanArticleTitle strips a bare trailing semicolon or colon","duration":1.6976980000000594,"failureMessages":[],"location":{"line":973,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not truncate to end on a ≤ 3-char tail word (live: `… on the Tidö`)","status":"passed","title":"titleFromBluf does not truncate to end on a ≤ 3-char tail word (live: `… on the Tidö`)","duration":1.7855829999999742,"failureMessages":[],"location":{"line":982,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not truncate to end on `two`, `has` or other ≤ 3-char filler","status":"passed","title":"titleFromBluf does not truncate to end on `two`, `has` or other ≤ 3-char filler","duration":1.8239750000000186,"failureMessages":[],"location":{"line":995,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf preserves 4+ char tail words like `bill`, `cuts`, `vote`","status":"passed","title":"titleFromBluf preserves 4+ char tail words like `bill`, `cuts`, `vote`","duration":1.84078599999998,"failureMessages":[],"location":{"line":1004,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS a leading Swedish date prefix when stripping would leave a V2 verb-leading fragment","status":"passed","title":"titleFromBluf KEEPS a leading Swedish date prefix when stripping would leave a V2 verb-leading fragment","duration":1.7690020000000004,"failureMessages":[],"location":{"line":1014,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading Swedish date prefix when result is NOT verb-leading","status":"passed","title":"titleFromBluf strips a leading Swedish date prefix when result is NOT verb-leading","duration":1.7936580000000504,"failureMessages":[],"location":{"line":1028,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS a leading German date prefix when stripping would leave a V2 verb-leading fragment","status":"passed","title":"titleFromBluf KEEPS a leading German date prefix when stripping would leave a V2 verb-leading fragment","duration":1.8267100000000482,"failureMessages":[],"location":{"line":1040,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading German date prefix when result is NOT verb-leading","status":"passed","title":"titleFromBluf strips a leading German date prefix when result is NOT verb-leading","duration":1.891841999999997,"failureMessages":[],"location":{"line":1051,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly escapeYaml escapes quotes, backslashes and newlines","status":"passed","title":"escapeYaml escapes quotes, backslashes and newlines","duration":1.8666839999999638,"failureMessages":[],"location":{"line":1062,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly escapeInlineMd escapes markdown metacharacters","status":"passed","title":"escapeInlineMd escapes markdown metacharacters","duration":1.8393330000000105,"failureMessages":[],"location":{"line":1068,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly buildFrontMatter assembles a body-only block with auto slug and omits SEO fields","status":"passed","title":"buildFrontMatter assembles a body-only block with auto slug and omits SEO fields","duration":2.005814999999984,"failureMessages":[],"location":{"line":1073,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity anchorForTitle prefixes the slug with HEADING_ID_PREFIX","status":"passed","title":"anchorForTitle prefixes the slug with HEADING_ID_PREFIX","duration":3.861799000000019,"failureMessages":[],"location":{"line":1094,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity anchorForTitle strips leading emoji before slugging","status":"passed","title":"anchorForTitle strips leading emoji before slugging","duration":2.1314200000000483,"failureMessages":[],"location":{"line":1100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide emits only rows whose artifact is available","status":"passed","title":"buildReaderGuide emits only rows whose artifact is available","duration":3.153513999999973,"failureMessages":[],"location":{"line":1104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide emits the per-document row when hasDocuments=true","status":"passed","title":"buildReaderGuide emits the per-document row when hasDocuments=true","duration":1.9478970000000118,"failureMessages":[],"location":{"line":1122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide audit row targets political-classification when classification-results is absent","status":"passed","title":"buildReaderGuide audit row targets political-classification when classification-results is absent","duration":2.4215239999999767,"failureMessages":[],"location":{"line":1127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix returns null when no artifacts were used","status":"passed","title":"returns null when no artifacts were used","duration":2.0072170000000824,"failureMessages":[],"location":{"line":1140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix emits one bullet per artifact with absolute GitHub URLs","status":"passed","title":"emits one bullet per artifact with absolute GitHub URLs","duration":2.137260999999853,"failureMessages":[],"location":{"line":1144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix links supporting JSON data artifacts without expanding them inline","status":"passed","title":"links supporting JSON data artifacts without expanding them inline","duration":2.8210209999999734,"failureMessages":[],"location":{"line":1155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix emits a supporting-data-only preamble when used is empty but supporting data exists","status":"passed","title":"emits a supporting-data-only preamble when used is empty but supporting data exists","duration":2.547117999999955,"failureMessages":[],"location":{"line":1168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport summarizes emitted, data and absent artifacts","status":"passed","title":"buildArtifactCoverageReport summarizes emitted, data and absent artifacts","duration":2.2196559999999863,"failureMessages":[],"location":{"line":1182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport surfaces alias-de-duped and present-but-empty buckets on their own lines","status":"passed","title":"buildArtifactCoverageReport surfaces alias-de-duped and present-but-empty buckets on their own lines","duration":2.1120140000000447,"failureMessages":[],"location":{"line":1196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport annotates the supporting-data count when truncation occurred","status":"passed","title":"buildArtifactCoverageReport annotates the supporting-data count when truncation occurred","duration":2.013680000000022,"failureMessages":[],"location":{"line":1213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences swaps fences for <pre class=\"mermaid\">","status":"passed","title":"preprocessMermaidFences swaps fences for <pre class=\"mermaid\">","duration":2.654549000000088,"failureMessages":[],"location":{"line":1226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences escapes HTML inside diagram source","status":"passed","title":"preprocessMermaidFences escapes HTML inside diagram source","duration":2.1642819999999574,"failureMessages":[],"location":{"line":1233,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences injects the canonical %%{init …}%% block when the diagram is unthemed","status":"passed","title":"preprocessMermaidFences injects the canonical %%{init …}%% block when the diagram is unthemed","duration":2.719101000000137,"failureMessages":[],"location":{"line":1239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences leaves an already-themed diagram untouched (no double prologue)","status":"passed","title":"preprocessMermaidFences leaves an already-themed diagram untouched (no double prologue)","duration":2.79166599999985,"failureMessages":[],"location":{"line":1248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation returns body unchanged when there are no mermaid fences","status":"passed","title":"returns body unchanged when there are no mermaid fences","duration":2.1078359999999066,"failureMessages":[],"location":{"line":1260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation recovers from an unclosed mermaid fence by terminating at the next opening fence","status":"passed","title":"recovers from an unclosed mermaid fence by terminating at the next opening fence","duration":2.2073720000000776,"failureMessages":[],"location":{"line":1265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation recovers from an unclosed mermaid fence at end-of-input","status":"passed","title":"recovers from an unclosed mermaid fence at end-of-input","duration":2.1558469999999943,"failureMessages":[],"location":{"line":1294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preserves the open/close pairing for back-to-back well-formed mermaid blocks","status":"passed","title":"preserves the open/close pairing for back-to-back well-formed mermaid blocks","duration":2.2521959999999126,"failureMessages":[],"location":{"line":1303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation hasMermaidTheme detects every Check-5 theme signal","status":"passed","title":"hasMermaidTheme detects every Check-5 theme signal","duration":2.4830289999999877,"failureMessages":[],"location":{"line":1320,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation ensureMermaidTheme is a pure function and idempotent","status":"passed","title":"ensureMermaidTheme is a pure function and idempotent","duration":2.2078030000000126,"failureMessages":[],"location":{"line":1329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation CANONICAL_MERMAID_INIT mirrors the cyberpunk dark theme baked into mermaid-init.mjs","status":"passed","title":"CANONICAL_MERMAID_INIT mirrors the cyberpunk dark theme baked into mermaid-init.mjs","duration":2.231608000000051,"failureMessages":[],"location":{"line":1337,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation CANONICAL_MERMAID_INIT satisfies Check 5 of .github/prompts/05-analysis-gate.md","status":"passed","title":"CANONICAL_MERMAID_INIT satisfies Check 5 of .github/prompts/05-analysis-gate.md","duration":2.2583380000000943,"failureMessages":[],"location":{"line":1348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation rehypeSlugWithPrefix exports a plugin function","status":"passed","title":"rehypeSlugWithPrefix exports a plugin function","duration":2.447642000000087,"failureMessages":[],"location":{"line":1358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation rehypeWrapTables exports a plugin function","status":"passed","title":"rehypeWrapTables exports a plugin function","duration":2.310224999999946,"failureMessages":[],"location":{"line":1363,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation HEADING_ID_PREFIX is the canonical `rm-` site prefix","status":"passed","title":"HEADING_ID_PREFIX is the canonical `rm-` site prefix","duration":2.4809940000000097,"failureMessages":[],"location":{"line":1368,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation sanitizeSchema preserves the `rm-` clobberPrefix","status":"passed","title":"sanitizeSchema preserves the `rm-` clobberPrefix","duration":2.811253000000079,"failureMessages":[],"location":{"line":1372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel re-exports the same `aggregateAnalysis` identity","status":"passed","title":"aggregator barrel re-exports the same `aggregateAnalysis` identity","duration":4.146363000000065,"failureMessages":[],"location":{"line":1381,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel `__test__` exposes the same regex identity as the leaf","status":"passed","title":"aggregator barrel `__test__` exposes the same regex identity as the leaf","duration":2.52776300000005,"failureMessages":[],"location":{"line":1385,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel `__test__` is frozen (no accidental mutation)","status":"passed","title":"aggregator barrel `__test__` is frozen (no accidental mutation)","duration":2.3286699999998746,"failureMessages":[],"location":{"line":1399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export markdown barrel re-exports the same `sanitizeSchema` identity","status":"passed","title":"markdown barrel re-exports the same `sanitizeSchema` identity","duration":2.395735000000059,"failureMessages":[],"location":{"line":1403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage READER_GUIDE_I18N has an entry for all 14 supported languages","status":"passed","title":"READER_GUIDE_I18N has an entry for all 14 supported languages","duration":3.330504000000019,"failureMessages":[],"location":{"line":1415,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage non-English languages have localised (non-English) heading","status":"passed","title":"non-English languages have localised (non-English) heading","duration":3.0579649999999674,"failureMessages":[],"location":{"line":1425,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage non-English languages have localised audit appendix label","status":"passed","title":"non-English languages have localised audit appendix label","duration":2.7388879999998608,"failureMessages":[],"location":{"line":1433,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage every language bundle has entries for all READER_GUIDE_ENTRIES files","status":"passed","title":"every language bundle has entries for all READER_GUIDE_ENTRIES files","duration":5.734545999999909,"failureMessages":[],"location":{"line":1441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage readerGuideI18n() returns English for unknown language","status":"passed","title":"readerGuideI18n() returns English for unknown language","duration":3.445219000000179,"failureMessages":[],"location":{"line":1452,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide with lang=sv produces Swedish heading","status":"passed","title":"buildReaderGuide with lang=sv produces Swedish heading","duration":2.597813999999971,"failureMessages":[],"location":{"line":1460,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide with lang=ja produces Japanese heading","status":"passed","title":"buildReaderGuide with lang=ja produces Japanese heading","duration":2.532079999999951,"failureMessages":[],"location":{"line":1473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide without lang defaults to English","status":"passed","title":"buildReaderGuide without lang defaults to English","duration":2.543190999999979,"failureMessages":[],"location":{"line":1482,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide slug-parity: every anchor starts with HEADING_ID_PREFIX","status":"passed","title":"buildReaderGuide slug-parity: every anchor starts with HEADING_ID_PREFIX","duration":2.9921620000000075,"failureMessages":[],"location":{"line":1490,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide completeness: row count matches available artifact count + special rows","status":"passed","title":"buildReaderGuide completeness: row count matches available artifact count + special rows","duration":2.7878890000001775,"failureMessages":[],"location":{"line":1501,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide strips an inline Reader Intelligence Guide block from artifact body","status":"passed","title":"strips an inline Reader Intelligence Guide block from artifact body","duration":2.6414149999998244,"failureMessages":[],"location":{"line":1515,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide preserves a paragraph that follows the table without intervening heading","status":"passed","title":"preserves a paragraph that follows the table without intervening heading","duration":2.5956089999999676,"failureMessages":[],"location":{"line":1539,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide returns body unchanged when no Reader Intelligence Guide is present","status":"passed","title":"returns body unchanged when no Reader Intelligence Guide is present","duration":2.555184000000054,"failureMessages":[],"location":{"line":1559,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide cleanArtifactBody invokes stripInlineReaderGuide (integration)","status":"passed","title":"cleanArtifactBody invokes stripInlineReaderGuide (integration)","duration":2.936828000000105,"failureMessages":[],"location":{"line":1564,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology rewrites BLUF heading and annotates first confidence/doc-id mention","status":"passed","title":"normalizeNarrativeTerminology rewrites BLUF heading and annotates first confidence/doc-id mention","duration":3.3007299999999304,"failureMessages":[],"location":{"line":1589,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology threads first-use state across artifact bodies (once per article)","status":"passed","title":"normalizeNarrativeTerminology threads first-use state across artifact bodies (once per article)","duration":3.0588560000001053,"failureMessages":[],"location":{"line":1610,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology leaves non-English bodies untouched","status":"passed","title":"normalizeNarrativeTerminology leaves non-English bodies untouched","duration":2.7807150000001,"failureMessages":[],"location":{"line":1624,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines collapses two identical adjacent classification rows","status":"passed","title":"collapses two identical adjacent classification rows","duration":2.717398000000003,"failureMessages":[],"location":{"line":1637,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines keeps non-adjacent duplicate lines intact","status":"passed","title":"keeps non-adjacent duplicate lines intact","duration":2.980641000000105,"failureMessages":[],"location":{"line":1651,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines preserves duplicates inside a fenced code block","status":"passed","title":"preserves duplicates inside a fenced code block","duration":3.0808680000000095,"failureMessages":[],"location":{"line":1656,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines is idempotent (applying twice equals applying once)","status":"passed","title":"is idempotent (applying twice equals applying once)","duration":2.698180999999977,"failureMessages":[],"location":{"line":1664,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks collapses repeated **ISMS** footer lines to the first occurrence","status":"passed","title":"collapses repeated **ISMS** footer lines to the first occurrence","duration":2.8069550000000163,"failureMessages":[],"location":{"line":1672,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks collapses repeated `**Classified under …**` markers","status":"passed","title":"collapses repeated `**Classified under …**` markers","duration":2.779442999999901,"failureMessages":[],"location":{"line":1688,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks leaves a single occurrence untouched","status":"passed","title":"leaves a single occurrence untouched","duration":2.7739329999999427,"failureMessages":[],"location":{"line":1698,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks does not strip legitimate content that mentions ISMS in prose","status":"passed","title":"does not strip legitimate content that mentions ISMS in prose","duration":2.8244680000000244,"failureMessages":[],"location":{"line":1703,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks cleanArtifactBody invokes the new cleaning steps (integration)","status":"passed","title":"cleanArtifactBody invokes the new cleaning steps (integration)","duration":2.982974000000013,"failureMessages":[],"location":{"line":1710,"column":3},"meta":{},"tags":[]}],"startTime":1787953659445,"endTime":1787953659869.983,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips a trailing \"## Pass 2 refinements\" section","status":"passed","title":"strips a trailing \"## Pass 2 refinements\" section","duration":15.679284999999936,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips variants: \"Pass 2 addendum\", \"🔁 Pass 2\", \"### Pass 2 review note\"","status":"passed","title":"strips variants: \"Pass 2 addendum\", \"🔁 Pass 2\", \"### Pass 2 review note\"","duration":11.589388000000099,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips leading admin-byline paragraph (Author / Run ID / Classification / Confidence)","status":"passed","title":"strips leading admin-byline paragraph (Author / Run ID / Classification / Confidence)","duration":0.7464780000000246,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips admin byline with · separators","status":"passed","title":"strips admin byline with · separators","duration":0.6456889999999476,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody keeps a paragraph that starts with a bold label but contains real prose","status":"passed","title":"keeps a paragraph that starts with a bold label but contains real prose","duration":0.5131410000001324,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody still strips the first H1, YAML front-matter, Document control, and Run ID: single-line","status":"passed","title":"still strips the first H1, YAML front-matter, Document control, and Run ID: single-line","duration":3.537554,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripPassTwoSection preserves content before and removes content after","status":"passed","title":"stripPassTwoSection preserves content before and removes content after","duration":0.6022580000001199,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines walks multiple admin paragraphs","status":"passed","title":"stripLeadingAdminBylines walks multiple admin paragraphs","duration":0.3973840000001019,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines drops admin blocks anywhere in body, not just leading","status":"passed","title":"stripLeadingAdminBylines drops admin blocks anywhere in body, not just leading","duration":0.7277830000000449,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines preserves mixed paragraphs (1 admin + analytical fragments)","status":"passed","title":"stripLeadingAdminBylines preserves mixed paragraphs (1 admin + analytical fragments)","duration":0.5270870000001651,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips workflow-process lines while preserving journalist-fact lines in the same paragraph","status":"passed","title":"strips workflow-process lines while preserving journalist-fact lines in the same paragraph","duration":0.6107140000001436,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips Admiralty Code typo \"Admiration Code\" used in some artifacts","status":"passed","title":"strips Admiralty Code typo \"Admiration Code\" used in some artifacts","duration":0.34529700000007324,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips ICD 203 / Standard / Self-audit cycle / Framework","status":"passed","title":"strips ICD 203 / Standard / Self-audit cycle / Framework","duration":0.48300499999982094,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip \"Election date\" (a journalism fact) but does strip bare \"Election\"","status":"passed","title":"does NOT strip \"Election date\" (a journalism fact) but does strip bare \"Election\"","duration":0.3581500000000233,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip per-document journalist facts (Beteckning, Minister, Response deadline, Effective date)","status":"passed","title":"does NOT strip per-document journalist facts (Beteckning, Minister, Response deadline, Effective date)","duration":0.39778499999988526,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip analytical callouts (ACH Score, ALARP, Mitigation, Evidence)","status":"passed","title":"does NOT strip analytical callouts (ACH Score, ALARP, Mitigation, Evidence)","duration":0.39707399999997506,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — AGGREGATION_ORDER"],"fullName":"render-lib — AGGREGATION_ORDER puts journalist-optimal narrative arc before technical and audit appendices","status":"passed","title":"puts journalist-optimal narrative arc before technical and audit appendices","duration":0.868987000000061,"failureMessages":[],"location":{"line":289,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — AGGREGATION_ORDER"],"fullName":"render-lib — AGGREGATION_ORDER still keeps the appendix group at the very end","status":"passed","title":"still keeps the appendix group at the very end","duration":1.0353480000001127,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings demotes every ATX heading by one level so artifact bodies nest under wrapper H2","status":"passed","title":"demotes every ATX heading by one level so artifact bodies nest under wrapper H2","duration":0.39093199999979333,"failureMessages":[],"location":{"line":356,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings caps demotion at H6 — already-deep headings are left alone","status":"passed","title":"caps demotion at H6 — already-deep headings are left alone","duration":0.37380000000007385,"failureMessages":[],"location":{"line":383,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings does not touch ATX-looking lines inside fenced code blocks","status":"passed","title":"does not touch ATX-looking lines inside fenced code blocks","duration":0.5001159999999345,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings leaves H1 alone (defensive — already stripped by upstream H1 regex)","status":"passed","title":"leaves H1 alone (defensive — already stripped by upstream H1 regex)","duration":0.5134319999999661,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings ignores `#` characters that are not the start of an ATX heading","status":"passed","title":"ignores `#` characters that are not the start of an ATX heading","duration":0.37299799999982497,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble strips a `_Source: \\`file.md\\`_` italic preamble line at the top of an artifact body","status":"passed","title":"strips a `_Source: \\`file.md\\`_` italic preamble line at the top of an artifact body","duration":0.5474850000000515,"failureMessages":[],"location":{"line":422,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble strips a bare `_Source: file.md_` italic preamble (no link)","status":"passed","title":"strips a bare `_Source: file.md_` italic preamble (no link)","duration":0.3684800000000905,"failureMessages":[],"location":{"line":435,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble leaves inline `Source:` mentions inside prose untouched","status":"passed","title":"leaves inline `Source:` mentions inside prose untouched","duration":0.4142050000000381,"failureMessages":[],"location":{"line":440,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","anchorForTitle"],"fullName":"render-lib — reader-facing HTML quality projections anchorForTitle produces stable rm-prefixed slugs for ASCII titles","status":"passed","title":"produces stable rm-prefixed slugs for ASCII titles","duration":1.1828149999998914,"failureMessages":[],"location":{"line":447,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","anchorForTitle"],"fullName":"render-lib — reader-facing HTML quality projections anchorForTitle trims leading hyphens that github-slugger emits when a title starts with a stripped character","status":"passed","title":"trims leading hyphens that github-slugger emits when a title starts with a stripped character","duration":2.0977680000000873,"failureMessages":[],"location":{"line":451,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) aggregates a minimal subfolder, strips Pass-2 and admin bylines, and picks a real description","status":"passed","title":"aggregates a minimal subfolder, strips Pass-2 and admin bylines, and picks a real description","duration":28.181482000000187,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) does NOT re-embed article.md or article.<lang>.md when re-running aggregation","status":"passed","title":"does NOT re-embed article.md or article.<lang>.md when re-running aggregation","duration":5.141636000000062,"failureMessages":[],"location":{"line":558,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) normalizes BLUF framing and adds first-use confidence/doc-id context in aggregated output","status":"passed","title":"normalizes BLUF framing and adds first-use confidence/doc-id context in aggregated output","duration":5.484328000000005,"failureMessages":[],"location":{"line":582,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) Reader Guide is built from emitted artifacts — a file cleaned to empty is NOT linked","status":"passed","title":"Reader Guide is built from emitted artifacts — a file cleaned to empty is NOT linked","duration":2.1642320000000836,"failureMessages":[],"location":{"line":617,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata uses the brief H1 and BLUF without fixed description suffixes","status":"passed","title":"uses the brief H1 and BLUF without fixed description suffixes","duration":2.687702000000172,"failureMessages":[],"location":{"line":656,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata cleans malformed HTML fragments and falls back to the story title instead of an empty meta description","status":"passed","title":"cleans malformed HTML fragments and falls back to the story title instead of an empty meta description","duration":0.7966409999999087,"failureMessages":[],"location":{"line":728,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata keeps identical-H1 EN/DE titles identical (brand suffix when budget allows) — canonical URL disambiguates per-language pages","status":"passed","title":"keeps identical-H1 EN/DE titles identical (brand suffix when budget allows) — canonical URL disambiguates per-language pages","duration":0.8054079999999431,"failureMessages":[],"location":{"line":753,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers exports stable BASE_URL / GITHUB_BLOB / GITHUB_TREE","status":"passed","title":"exports stable BASE_URL / GITHUB_BLOB / GITHUB_TREE","duration":0.7153000000000702,"failureMessages":[],"location":{"line":799,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers LANGUAGES contains all 14 supported languages with en as x-default first","status":"passed","title":"LANGUAGES contains all 14 supported languages with en as x-default first","duration":1.5210680000000139,"failureMessages":[],"location":{"line":805,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers buildGithubBlobUrl strips leading slashes and joins to GITHUB_BLOB","status":"passed","title":"buildGithubBlobUrl strips leading slashes and joins to GITHUB_BLOB","duration":0.8175400000000081,"failureMessages":[],"location":{"line":814,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers buildGithubTreeUrl strips leading slashes and joins to GITHUB_TREE","status":"passed","title":"buildGithubTreeUrl strips leading slashes and joins to GITHUB_TREE","duration":0.8200460000000476,"failureMessages":[],"location":{"line":826,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact returns the curated title for every known canonical artifact","status":"passed","title":"returns the curated title for every known canonical artifact","duration":1.0733490000000074,"failureMessages":[],"location":{"line":839,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact falls back to prettified title for unknown supplementary artifacts","status":"passed","title":"falls back to prettified title for unknown supplementary artifacts","duration":1.0148900000001504,"failureMessages":[],"location":{"line":854,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact handles a bare filename without path","status":"passed","title":"handles a bare filename without path","duration":1.0977250000000822,"failureMessages":[],"location":{"line":862,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks rewrites `./foo.md` to an absolute GitHub blob URL","status":"passed","title":"rewrites `./foo.md` to an absolute GitHub blob URL","duration":0.7589510000000246,"failureMessages":[],"location":{"line":874,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks preserves anchor on a relative link","status":"passed","title":"preserves anchor on a relative link","duration":0.6793219999999565,"failureMessages":[],"location":{"line":879,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks normalises `../` path traversal","status":"passed","title":"normalises `../` path traversal","duration":0.7053100000000541,"failureMessages":[],"location":{"line":884,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves absolute http/https URLs untouched","status":"passed","title":"leaves absolute http/https URLs untouched","duration":0.7561050000001615,"failureMessages":[],"location":{"line":891,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves pure anchor links untouched","status":"passed","title":"leaves pure anchor links untouched","duration":0.6998309999999037,"failureMessages":[],"location":{"line":900,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves mailto: links untouched","status":"passed","title":"leaves mailto: links untouched","duration":0.6713569999999436,"failureMessages":[],"location":{"line":904,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph reads the first H1 verbatim from markdown","status":"passed","title":"reads the first H1 verbatim from markdown","duration":1.0767459999999573,"failureMessages":[],"location":{"line":914,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph skips H1, admin bylines, tables, code fences, blockquotes","status":"passed","title":"readFirstParagraph skips H1, admin bylines, tables, code fences, blockquotes","duration":0.9813870000000406,"failureMessages":[],"location":{"line":920,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph returns prose without truncation (truncation is delegated to truncateToSentenceBoundary)","status":"passed","title":"readFirstParagraph returns prose without truncation (truncation is delegated to truncateToSentenceBoundary)","duration":0.8314270000000761,"failureMessages":[],"location":{"line":940,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph converts inline markdown links to plain text for article metadata","status":"passed","title":"readFirstParagraph converts inline markdown links to plain text for article metadata","duration":0.8375080000000708,"failureMessages":[],"location":{"line":948,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph returns null when markdown has no suitable paragraph","status":"passed","title":"returns null when markdown has no suitable paragraph","duration":0.8400019999999131,"failureMessages":[],"location":{"line":953,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — escape helpers"],"fullName":"render-lib — escape helpers escapeYaml escapes quotes, backslashes, and newlines","status":"passed","title":"escapeYaml escapes quotes, backslashes, and newlines","duration":0.866591999999855,"failureMessages":[],"location":{"line":963,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — escape helpers"],"fullName":"render-lib — escape helpers escapeInlineMd escapes every markdown metachar","status":"passed","title":"escapeInlineMd escapes every markdown metachar","duration":0.8876310000000558,"failureMessages":[],"location":{"line":969,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml renders GFM tables to <table>","status":"passed","title":"renders GFM tables to <table>","duration":22.401660999999876,"failureMessages":[],"location":{"line":983,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml preserves ```mermaid fences as <pre class=\"mermaid\"> blocks verbatim","status":"passed","title":"preserves ```mermaid fences as <pre class=\"mermaid\"> blocks verbatim","duration":11.081306999999924,"failureMessages":[],"location":{"line":990,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml adds id + anchor link to every heading (rehype-slug + autolink-headings)","status":"passed","title":"adds id + anchor link to every heading (rehype-slug + autolink-headings)","duration":4.170008000000053,"failureMessages":[],"location":{"line":1001,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises <script> tags out of the rendered HTML","status":"passed","title":"sanitises <script> tags out of the rendered HTML","duration":4.423281999999972,"failureMessages":[],"location":{"line":1011,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises javascript: URLs out of links","status":"passed","title":"sanitises javascript: URLs out of links","duration":5.3824469999999565,"failureMessages":[],"location":{"line":1021,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises <iframe> injections","status":"passed","title":"sanitises <iframe> injections","duration":3.0512519999999768,"failureMessages":[],"location":{"line":1026,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml produces unique heading IDs even when an emoji-prefixed heading shares a base slug with a plain heading (HTMLHint id-unique guard)","status":"passed","title":"produces unique heading IDs even when an emoji-prefixed heading shares a base slug with a plain heading (HTMLHint id-unique guard)","duration":4.46860700000002,"failureMessages":[],"location":{"line":1033,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml produces unique heading IDs across an emoji-prefixed and non-prefixed heading with mixed casing (defensive)","status":"passed","title":"produces unique heading IDs across an emoji-prefixed and non-prefixed heading with mixed casing (defensive)","duration":2.9964599999998427,"failureMessages":[],"location":{"line":1060,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead emits <title>, description, canonical, and hreflang × every supplied locale","status":"passed","title":"emits <title>, description, canonical, and hreflang × every supplied locale","duration":2.137732000000142,"failureMessages":[],"location":{"line":1073,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead sets dir=\"rtl\" for Arabic","status":"passed","title":"sets dir=\"rtl\" for Arabic","duration":1.143139999999903,"failureMessages":[],"location":{"line":1092,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead sets dir=\"ltr\" for English","status":"passed","title":"sets dir=\"ltr\" for English","duration":1.0865440000000035,"failureMessages":[],"location":{"line":1102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead embeds provided JSON-LD blobs into <head>","status":"passed","title":"embeds provided JSON-LD blobs into <head>","duration":1.145764999999983,"failureMessages":[],"location":{"line":1112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead HTML-escapes title and description","status":"passed","title":"HTML-escapes title and description","duration":1.251704000000018,"failureMessages":[],"location":{"line":1125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits skip-link, site header, nav, and footer","status":"passed","title":"emits skip-link, site header, nav, and footer","duration":2.8481219999998757,"failureMessages":[],"location":{"line":1139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome language switcher lists every language EXCEPT the current one","status":"passed","title":"language switcher lists every language EXCEPT the current one","duration":1.5598809999999048,"failureMessages":[],"location":{"line":1155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome appends bodyClass to the <body> class list","status":"passed","title":"appends bodyClass to the <body> class list","duration":1.425809000000072,"failureMessages":[],"location":{"line":1177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome omits bodyClass when not supplied (only base class on <body>)","status":"passed","title":"omits bodyClass when not supplied (only base class on <body>)","duration":1.6720310000000609,"failureMessages":[],"location":{"line":1189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders the always-visible horizontal language bar by default","status":"passed","title":"renders the always-visible horizontal language bar by default","duration":1.4980749999999716,"failureMessages":[],"location":{"line":1200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome suppresses the horizontal language bar when languageBar is false","status":"passed","title":"suppresses the horizontal language bar when languageBar is false","duration":7.125778999999966,"failureMessages":[],"location":{"line":1213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders the hero banner immediately after the site header by default","status":"passed","title":"renders the hero banner immediately after the site header by default","duration":1.412072999999964,"failureMessages":[],"location":{"line":1227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses the depth-aware prefix for the hero banner image src","status":"passed","title":"uses the depth-aware prefix for the hero banner image src","duration":1.2060080000001108,"failureMessages":[],"location":{"line":1247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome suppresses the hero banner when heroBanner is false","status":"passed","title":"suppresses the hero banner when heroBanner is false","duration":1.2196630000000823,"failureMessages":[],"location":{"line":1259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome computes the depth-prefix ../ correctly for nested canonical paths","status":"passed","title":"computes the depth-prefix ../ correctly for nested canonical paths","duration":1.740398000000141,"failureMessages":[],"location":{"line":1271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a tagline under the logo on wider viewports","status":"passed","title":"renders a tagline under the logo on wider viewports","duration":1.962242999999944,"failureMessages":[],"location":{"line":1286,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a breadcrumb row in the sub-navigation and a published-date indicator","status":"passed","title":"renders a breadcrumb row in the sub-navigation and a published-date indicator","duration":2.331965999999966,"failureMessages":[],"location":{"line":1296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a 3-column footer with brand, navigate and trust sections plus RSS link","status":"passed","title":"renders a 3-column footer with brand, navigate and trust sections plus RSS link","duration":2.290657999999894,"failureMessages":[],"location":{"line":1311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses a language-specific RSS feed for non-English articles","status":"passed","title":"uses a language-specific RSS feed for non-English articles","duration":1.9685249999999996,"failureMessages":[],"location":{"line":1335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a secondary always-visible language row in the footer","status":"passed","title":"renders a secondary always-visible language row in the footer","duration":2.3379180000001725,"failureMessages":[],"location":{"line":1343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits a header dark/light theme toggle button (id=\"theme-toggle\")","status":"passed","title":"emits a header dark/light theme toggle button (id=\"theme-toggle\")","duration":1.8372600000000148,"failureMessages":[],"location":{"line":1356,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits the anti-flash theme bootstrap inline script in <head>","status":"passed","title":"emits the anti-flash theme bootstrap inline script in <head>","duration":1.2057179999999335,"failureMessages":[],"location":{"line":1370,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome bootstraps mermaid + back-to-top + theme-toggle via inline DOM injection (Vite-bypass)","status":"passed","title":"bootstraps mermaid + back-to-top + theme-toggle via inline DOM injection (Vite-bypass)","duration":1.4281740000001264,"failureMessages":[],"location":{"line":1381,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a custom breadcrumb when `breadcrumb` is supplied (skips the legacy 3-tier default)","status":"passed","title":"renders a custom breadcrumb when `breadcrumb` is supplied (skips the legacy 3-tier default)","duration":1.4013240000001588,"failureMessages":[],"location":{"line":1396,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses `defaultAlternateBase` for the lang-switcher fallback hrefs","status":"passed","title":"uses `defaultAlternateBase` for the lang-switcher fallback hrefs","duration":1.342253000000028,"failureMessages":[],"location":{"line":1417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead `ogType`"],"fullName":"render-lib — renderChromeHead `ogType` defaults to og:type=\"article\" and emits the article:* meta block","status":"passed","title":"defaults to og:type=\"article\" and emits the article:* meta block","duration":1.2398109999999178,"failureMessages":[],"location":{"line":1435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead `ogType`"],"fullName":"render-lib — renderChromeHead `ogType` switches to og:type=\"website\" and suppresses the article:* meta block when `ogType: \"website\"`","status":"passed","title":"switches to og:type=\"website\" and suppresses the article:* meta block when `ogType: \"website\"`","duration":1.2646879999999783,"failureMessages":[],"location":{"line":1449,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) produces a complete chrome-wrapped article with rm-article wrapper + sources block","status":"passed","title":"produces a complete chrome-wrapped article with rm-article wrapper + sources block","duration":25.428805999999895,"failureMessages":[],"location":{"line":1488,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) strips <script> injected via aggregated markdown source","status":"passed","title":"strips <script> injected via aggregated markdown source","duration":4.321860999999899,"failureMessages":[],"location":{"line":1550,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) respects hreflang alternates when provided","status":"passed","title":"respects hreflang alternates when provided","duration":4.69420799999989,"failureMessages":[],"location":{"line":1576,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) renders Reader Intelligence Guide in Swedish for lang=sv","status":"passed","title":"renders Reader Intelligence Guide in Swedish for lang=sv","duration":4.47812399999998,"failureMessages":[],"location":{"line":1593,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) rewrites embedded HTML .md links to canonical GitHub blob URLs","status":"passed","title":"rewrites embedded HTML .md links to canonical GitHub blob URLs","duration":7.404342000000042,"failureMessages":[],"location":{"line":1608,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases throws a helpful error when executive-brief.md is missing","status":"passed","title":"throws a helpful error when executive-brief.md is missing","duration":2.4727589999999964,"failureMessages":[],"location":{"line":1651,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases throws when subfolder does not exist at all","status":"passed","title":"throws when subfolder does not exist at all","duration":1.5152160000000094,"failureMessages":[],"location":{"line":1666,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases expands documents/*.md inline as \"Per-document intelligence\" subsections","status":"passed","title":"expands documents/*.md inline as \"Per-document intelligence\" subsections","duration":2.99277300000017,"failureMessages":[],"location":{"line":1677,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases classifies a sibling that exists on disk + alias-suppressed as alias-de-duped (not present-but-empty) in the coverage report","status":"passed","title":"classifies a sibling that exists on disk + alias-suppressed as alias-de-duped (not present-but-empty) in the coverage report","duration":2.563950999999861,"failureMessages":[],"location":{"line":1705,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases appends unknown supplementary *.md after the core order alphabetically","status":"passed","title":"appends unknown supplementary *.md after the core order alphabetically","duration":2.6473359999999957,"failureMessages":[],"location":{"line":1733,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches the legacy admin fields","status":"passed","title":"matches the legacy admin fields","duration":1.6809180000000197,"failureMessages":[],"location":{"line":1771,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches the new contract fields that previously leaked into descriptions","status":"passed","title":"matches the new contract fields that previously leaked into descriptions","duration":1.8147369999999228,"failureMessages":[],"location":{"line":1791,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches preamble-leak fields observed 2026-04-27 (Analysis period / Pass 2 / AI-FIRST iterations / ARTICLE_TYPE)","status":"passed","title":"matches preamble-leak fields observed 2026-04-27 (Analysis period / Pass 2 / AI-FIRST iterations / ARTICLE_TYPE)","duration":3.388723999999911,"failureMessages":[],"location":{"line":1813,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches unbolded admin fields (leak case — description read back from rendered HTML)","status":"passed","title":"matches unbolded admin fields (leak case — description read back from rendered HTML)","duration":1.635962999999947,"failureMessages":[],"location":{"line":1907,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) does not match real prose that happens to start with similar words","status":"passed","title":"does not match real prose that happens to start with similar words","duration":1.4077559999998357,"failureMessages":[],"location":{"line":1913,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) splits on structural delimiters (pipe, fullwidth pipe, newline, double-space)","status":"passed","title":"splits on structural delimiters (pipe, fullwidth pipe, newline, double-space)","duration":1.5968000000000302,"failureMessages":[],"location":{"line":1920,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) does NOT split on em-dash / middle-dot (value-internal punctuation)","status":"passed","title":"does NOT split on em-dash / middle-dot (value-internal punctuation)","duration":1.5034149999999045,"failureMessages":[],"location":{"line":1928,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) handles |-separated admin blocks — whole block is admin, every fragment matches","status":"passed","title":"handles |-separated admin blocks — whole block is admin, every fragment matches","duration":1.51237100000003,"failureMessages":[],"location":{"line":1938,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b)"],"fullName":"render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b) skips a paragraph whose fragments are all admin fields, even when joined by `|`","status":"passed","title":"skips a paragraph whose fragments are all admin fields, even when joined by `|`","duration":1.6220670000000155,"failureMessages":[],"location":{"line":1949,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b)"],"fullName":"render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b) skips a multi-line admin block led by an unbolded `Brief ID`","status":"passed","title":"skips a multi-line admin block led by an unbolded `Brief ID`","duration":2.129216000000042,"failureMessages":[],"location":{"line":1962,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) returns the input unchanged when it is already within the window","status":"passed","title":"returns the input unchanged when it is already within the window","duration":1.7501360000001114,"failureMessages":[],"location":{"line":1985,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) truncates at the last sentence boundary within hardMax, not mid-word","status":"passed","title":"truncates at the last sentence boundary within hardMax, not mid-word","duration":2.6914989999997943,"failureMessages":[],"location":{"line":1990,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) never cuts mid-word when no sentence boundary is reachable","status":"passed","title":"never cuts mid-word when no sentence boundary is reachable","duration":2.7455199999999422,"failureMessages":[],"location":{"line":2003,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) respects custom windows (e.g. CJK 70-120)","status":"passed","title":"respects custom windows (e.g. CJK 70-120)","duration":1.844733000000133,"failureMessages":[],"location":{"line":2013,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) supports CJK full stop `。` as a sentence terminator","status":"passed","title":"supports CJK full stop `。` as a sentence terminator","duration":2.240885000000162,"failureMessages":[],"location":{"line":2021,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) returns the first prose paragraph after a `## 🎯 BLUF` heading","status":"passed","title":"returns the first prose paragraph after a `## 🎯 BLUF` heading","duration":1.7903120000000854,"failureMessages":[],"location":{"line":2032,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) returns null when the brief has no BLUF heading","status":"passed","title":"returns null when the brief has no BLUF heading","duration":1.6915169999999762,"failureMessages":[],"location":{"line":2050,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) skips admin paragraphs between the BLUF heading and the first prose","status":"passed","title":"skips admin paragraphs between the BLUF heading and the first prose","duration":1.7450370000001385,"failureMessages":[],"location":{"line":2055,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips `Executive Brief — ` prefix and trailing ISO date","status":"passed","title":"strips `Executive Brief — ` prefix and trailing ISO date","duration":1.9407139999998435,"failureMessages":[],"location":{"line":2070,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) returns null when the cleaned title is too short to be a real headline","status":"passed","title":"returns null when the cleaned title is too short to be a real headline","duration":1.7351679999999305,"failureMessages":[],"location":{"line":2077,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) preserves a real editorial headline that already has no boilerplate","status":"passed","title":"preserves a real editorial headline that already has no boilerplate","duration":1.6599069999999756,"failureMessages":[],"location":{"line":2086,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips trailing realtime-cycle timestamps like ` 2026-04-22 23:38`","status":"passed","title":"strips trailing realtime-cycle timestamps like ` 2026-04-22 23:38`","duration":1.671980000000076,"failureMessages":[],"location":{"line":2091,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) handles the `Realtime Monitor — ` boilerplate prefix too","status":"passed","title":"handles the `Realtime Monitor — ` boilerplate prefix too","duration":1.9069700000000012,"failureMessages":[],"location":{"line":2098,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips leading pictographs / emoji prefixes like `📋 Executive Brief — …`","status":"passed","title":"strips leading pictographs / emoji prefixes like `📋 Executive Brief — …`","duration":2.0078289999999015,"failureMessages":[],"location":{"line":2103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips mid-title ISO date ranges and dangling connectors","status":"passed","title":"strips mid-title ISO date ranges and dangling connectors","duration":2.1135069999997995,"failureMessages":[],"location":{"line":2113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) synthesises a title from the first BLUF sentence","status":"passed","title":"synthesises a title from the first BLUF sentence","duration":2.1896489999999176,"failureMessages":[],"location":{"line":2131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) returns null when there is no usable BLUF","status":"passed","title":"returns null when there is no usable BLUF","duration":2.236987999999883,"failureMessages":[],"location":{"line":2139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) truncates at word boundary when the first sentence exceeds maxLen","status":"passed","title":"truncates at word boundary when the first sentence exceeds maxLen","duration":2.151787999999897,"failureMessages":[],"location":{"line":2145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis end-to-end contract"],"fullName":"render-lib — aggregateAnalysis end-to-end contract produces a clean title + description for a realistic executive-brief with boilerplate H1","status":"passed","title":"produces a clean title + description for a realistic executive-brief with boilerplate H1","duration":8.217964999999822,"failureMessages":[],"location":{"line":2159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis end-to-end contract"],"fullName":"render-lib — aggregateAnalysis end-to-end contract synthesises a BLUF-based title when the H1 collapses to nothing useful","status":"passed","title":"synthesises a BLUF-based title when the H1 collapses to nothing useful","duration":3.775378000000046,"failureMessages":[],"location":{"line":2203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips the ## Reader Intelligence Guide section from article body","status":"passed","title":"strips the ## Reader Intelligence Guide section from article body","duration":2.2191550000000007,"failureMessages":[],"location":{"line":2235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips the ## Article Sources section from article body","status":"passed","title":"strips the ## Article Sources section from article body","duration":2.0097030000001723,"failureMessages":[],"location":{"line":2261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips both sections when present together","status":"passed","title":"strips both sections when present together","duration":2.0007359999999608,"failureMessages":[],"location":{"line":2281,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections returns body unchanged when neither section is present","status":"passed","title":"returns body unchanged when neither section is present","duration":2.0246199999999135,"failureMessages":[],"location":{"line":2311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections renders no inline Reader Guide or Article Sources in final HTML (integration)","status":"passed","title":"renders no inline Reader Guide or Article Sources in final HTML (integration)","duration":4.866269999999986,"failureMessages":[],"location":{"line":2316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections renders fully localized Reader Intelligence Guide table for all 14 languages","status":"passed","title":"renders fully localized Reader Intelligence Guide table for all 14 languages","duration":24.570138999999926,"failureMessages":[],"location":{"line":2369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections styles Reader Intelligence Guide table outside the article body","status":"passed","title":"styles Reader Intelligence Guide table outside the article body","duration":3.9773560000001,"failureMessages":[],"location":{"line":2423,"column":3},"meta":{},"tags":[]}],"startTime":1787953658260,"endTime":1787953658645.9773,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib.test.ts"},{"assertionResults":[{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers parses commands and artifact kinds","status":"passed","title":"parses commands and artifact kinds","duration":3.997064000000023,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers rejects unsafe or non-Riksbank URLs","status":"passed","title":"rejects unsafe or non-Riksbank URLs","duration":1.9847659999999792,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers builds provenance for HTML responses","status":"passed","title":"builds provenance for HTML responses","duration":6.062652000000014,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers builds provenance for JSON responses","status":"passed","title":"builds provenance for JSON responses","duration":1.6506309999999758,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers encodes PDF responses as base64 with a byte-length cap","status":"passed","title":"encodes PDF responses as base64 with a byte-length cap","duration":0.9449799999999868,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs to a no-data payload on network outage","status":"passed","title":"fail-softs to a no-data payload on network outage","duration":0.961640999999986,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs to a no-data payload on non-2xx HTTP status","status":"passed","title":"fail-softs to a no-data payload on non-2xx HTTP status","duration":0.8150170000000116,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs when Content-Length exceeds the PDF cap before downloading","status":"passed","title":"fail-softs when Content-Length exceeds the PDF cap before downloading","duration":0.6212229999999863,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers follows redirects manually and validates each Location host","status":"passed","title":"follows redirects manually and validates each Location host","duration":0.8154670000000124,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers rejects redirects to off-allowlist hosts","status":"passed","title":"rejects redirects to off-allowlist hosts","duration":0.6937490000000253,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]}],"startTime":1787953871086,"endTime":1787953871104.6938,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/riksbank-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["constants"],"fullName":"constants CONSTITUTIONAL_DEADLINE_MONTHS is 4","status":"passed","title":"CONSTITUTIONAL_DEADLINE_MONTHS is 4","duration":3.812628000000018,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["constants"],"fullName":"constants RIR_SKRIVELSE_DOKTYP is \"skr\"","status":"passed","title":"RIR_SKRIVELSE_DOKTYP is \"skr\"","duration":0.6548560000000521,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["constants"],"fullName":"constants RIR_SKRIVELSE_SUBTYP is \"rsk\"","status":"passed","title":"RIR_SKRIVELSE_SUBTYP is \"rsk\"","duration":0.5822800000000257,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline adds 4 months to a mid-month date","status":"passed","title":"adds 4 months to a mid-month date","duration":0.6427629999999454,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline adds 4 months crossing a year boundary","status":"passed","title":"adds 4 months crossing a year boundary","duration":0.5119789999999966,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline clamps to last day when target month is shorter","status":"passed","title":"clamps to last day when target month is shorter","duration":0.5676530000000071,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline handles leap year correctly","status":"passed","title":"handles leap year correctly","duration":0.598199999999963,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline uses custom month override","status":"passed","title":"uses custom month override","duration":0.4977819999999724,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline throws RangeError on invalid date","status":"passed","title":"throws RangeError on invalid date","duration":0.827619000000027,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline handles end of year wrapping correctly","status":"passed","title":"handles end of year wrapping correctly","duration":0.5528040000000374,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns 0 when not yet overdue","status":"passed","title":"returns 0 when not yet overdue","duration":0.6057739999999967,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns positive integer when overdue","status":"passed","title":"returns positive integer when overdue","duration":0.38965899999999465,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns 0 exactly on the deadline day","status":"passed","title":"returns 0 exactly on the deadline day","duration":0.4524870000000192,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue throws RangeError on invalid deadlineDate","status":"passed","title":"throws RangeError on invalid deadlineDate","duration":0.44118600000001607,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue throws RangeError on invalid asOf string","status":"passed","title":"throws RangeError on invalid asOf string","duration":0.46497099999999136,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns RESPONDED when skrivelse_id set and status RESPONDED","status":"passed","title":"returns RESPONDED when skrivelse_id set and status RESPONDED","duration":0.4770229999999742,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PARTIAL when status PARTIAL and skrivelse_id set","status":"passed","title":"returns PARTIAL when status PARTIAL and skrivelse_id set","duration":0.513089999999977,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns OVERDUE when deadline elapsed and no response","status":"passed","title":"returns OVERDUE when deadline elapsed and no response","duration":0.4037859999999682,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PENDING when deadline not yet elapsed","status":"passed","title":"returns PENDING when deadline not yet elapsed","duration":0.504413999999997,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PENDING when no deadline set","status":"passed","title":"returns PENDING when no deadline set","duration":0.6024780000000192,"failureMessages":[],"location":{"line":222,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus uses current date by default","status":"passed","title":"uses current date by default","duration":1.51108899999997,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns RESPONDED when stored status is PENDING but response_skrivelse_id is set (rule 1)","status":"passed","title":"returns RESPONDED when stored status is PENDING but response_skrivelse_id is set (rule 1)","duration":0.4885449999999878,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PARTIAL when response_skrivelse_id is set but open_recommendations > 0","status":"passed","title":"returns PARTIAL when response_skrivelse_id is set but open_recommendations > 0","duration":0.5259549999999535,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts returns alerts for OVERDUE records only","status":"passed","title":"returns alerts for OVERDUE records only","duration":1.3141009999999937,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts alert has correct days_overdue","status":"passed","title":"alert has correct days_overdue","duration":0.5347210000000473,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts returns empty array when no records are overdue","status":"passed","title":"returns empty array when no records are overdue","duration":0.5999029999999834,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts sorts alerts by days_overdue descending","status":"passed","title":"sorts alerts by days_overdue descending","duration":0.6211019999999507,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts skips records with no skrivelse_deadline","status":"passed","title":"skips records with no skrivelse_deadline","duration":0.6091199999999617,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts skips records that already have a response_skrivelse_id","status":"passed","title":"skips records that already have a response_skrivelse_id","duration":0.6282559999999648,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable renders a header row and record rows","status":"passed","title":"renders a header row and record rows","duration":0.8802180000000135,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable shows overdue emoji for overdue records","status":"passed","title":"shows overdue emoji for overdue records","duration":0.7348850000000198,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable shows pending emoji for pending records","status":"passed","title":"shows pending emoji for pending records","duration":3.1180269999999837,"failureMessages":[],"location":{"line":329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable uses riksdag_url for title link when available","status":"passed","title":"uses riksdag_url for title link when available","duration":0.5015390000000366,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable renders empty table gracefully","status":"passed","title":"renders empty table gracefully","duration":0.6177959999999985,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument appends a table block to a document without existing markers","status":"passed","title":"appends a table block to a document without existing markers","duration":0.6421320000000037,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument replaces an existing table block","status":"passed","title":"replaces an existing table block","duration":0.5057369999999537,"failureMessages":[],"location":{"line":364,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument preserves content before and after the markers","status":"passed","title":"preserves content before and after the markers","duration":0.5274480000000494,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee filters records by committee code","status":"passed","title":"filters records by committee code","duration":0.5934910000000286,"failureMessages":[],"location":{"line":402,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee is case-insensitive","status":"passed","title":"is case-insensitive","duration":1.3386059999999702,"failureMessages":[],"location":{"line":408,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee returns empty array if no match","status":"passed","title":"returns empty array if no match","duration":0.5005770000000211,"failureMessages":[],"location":{"line":414,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee handles records without committees field","status":"passed","title":"handles records without committees field","duration":0.6027290000000107,"failureMessages":[],"location":{"line":418,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters PENDING records","status":"passed","title":"filters PENDING records","duration":0.716951999999992,"failureMessages":[],"location":{"line":429,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters OVERDUE records","status":"passed","title":"filters OVERDUE records","duration":0.575347000000022,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters RESPONDED records","status":"passed","title":"filters RESPONDED records","duration":0.5709190000000035,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters PARTIAL records","status":"passed","title":"filters PARTIAL records","duration":0.5175789999999552,"failureMessages":[],"location":{"line":447,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel returns all records at or above LOW","status":"passed","title":"returns all records at or above LOW","duration":0.7876739999999813,"failureMessages":[],"location":{"line":459,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel filters to MEDIUM and above","status":"passed","title":"filters to MEDIUM and above","duration":0.9978780000000143,"failureMessages":[],"location":{"line":464,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel filters to HIGH and above","status":"passed","title":"filters to HIGH and above","duration":0.7941870000000222,"failureMessages":[],"location":{"line":473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel defaults missing risk_level to MEDIUM (shared default)","status":"passed","title":"defaults missing risk_level to MEDIUM (shared default)","duration":0.8828229999999735,"failureMessages":[],"location":{"line":479,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord passes a fully valid record","status":"passed","title":"passes a fully valid record","duration":1.079842000000042,"failureMessages":[],"location":{"line":492,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports missing rir_report_id","status":"passed","title":"reports missing rir_report_id","duration":0.7862119999999777,"failureMessages":[],"location":{"line":496,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid rir_number format","status":"passed","title":"reports invalid rir_number format","duration":0.7677569999999605,"failureMessages":[],"location":{"line":502,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid publish_date","status":"passed","title":"reports invalid publish_date","duration":0.7353469999999902,"failureMessages":[],"location":{"line":508,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid gov_response_status","status":"passed","title":"reports invalid gov_response_status","duration":0.8251750000000015,"failureMessages":[],"location":{"line":514,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports RESPONDED without response_skrivelse_id","status":"passed","title":"reports RESPONDED without response_skrivelse_id","duration":0.9906750000000102,"failureMessages":[],"location":{"line":520,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord accepts null skrivelse_deadline","status":"passed","title":"accepts null skrivelse_deadline","duration":0.8483289999999784,"failureMessages":[],"location":{"line":529,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string response_skrivelse_id","status":"passed","title":"reports non-string response_skrivelse_id","duration":0.7984149999999772,"failureMessages":[],"location":{"line":535,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string item in parliamentary_followup_doc_ids","status":"passed","title":"reports non-string item in parliamentary_followup_doc_ids","duration":1.192352000000028,"failureMessages":[],"location":{"line":541,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string item in committees","status":"passed","title":"reports non-string item in committees","duration":1.072829000000013,"failureMessages":[],"location":{"line":550,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirDataset"],"fullName":"validateRirDataset returns empty map for valid dataset","status":"passed","title":"returns empty map for valid dataset","duration":0.9257129999999734,"failureMessages":[],"location":{"line":562,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirDataset"],"fullName":"validateRirDataset returns entries for each invalid record","status":"passed","title":"returns entries for each invalid record","duration":0.902259000000015,"failureMessages":[],"location":{"line":567,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadRirDataset"],"fullName":"loadRirDataset parses a JSON string via injectable reader","status":"passed","title":"parses a JSON string via injectable reader","duration":1.1187249999999835,"failureMessages":[],"location":{"line":585,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadRirDataset"],"fullName":"loadRirDataset throws on malformed JSON","status":"passed","title":"throws on malformed JSON","duration":1.0023069999999734,"failureMessages":[],"location":{"line":593,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["saveRirDataset"],"fullName":"saveRirDataset calls writeFileFn with pretty JSON","status":"passed","title":"calls writeFileFn with pretty JSON","duration":1.3059259999999995,"failureMessages":[],"location":{"line":600,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["saveRirDataset"],"fullName":"saveRirDataset updates last_updated using injected clock (deterministic)","status":"passed","title":"updates last_updated using injected clock (deterministic)","duration":1.277131000000054,"failureMessages":[],"location":{"line":611,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/rir-followups.json integrity"],"fullName":"data/rir-followups.json integrity loads and validates the real dataset file","status":"passed","title":"loads and validates the real dataset file","duration":1.3352499999999736,"failureMessages":[],"location":{"line":629,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/rir-followups.json integrity"],"fullName":"data/rir-followups.json integrity all records in data/rir-followups.json have required fields","status":"passed","title":"all records in data/rir-followups.json have required fields","duration":1.8258189999999672,"failureMessages":[],"location":{"line":647,"column":3},"meta":{},"tags":[]}],"startTime":1787953668364,"endTime":1787953668421.826,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rir-followups-client.test.ts"},{"assertionResults":[{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should define all four risk levels","status":"passed","title":"should define all four risk levels","duration":13.573290999999983,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have non-overlapping score ranges","status":"passed","title":"should have non-overlapping score ranges","duration":4.195425,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have valid hex color codes","status":"passed","title":"should have valid hex color codes","duration":3.788742999999954,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have human-readable labels","status":"passed","title":"should have human-readable labels","duration":3.586213999999984,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should cover full 0-10 score range","status":"passed","title":"should cover full 0-10 score range","duration":4.030776000000003,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should define colors for all 8 Swedish parties","status":"passed","title":"should define colors for all 8 Swedish parties","duration":3.7004479999999944,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should include all expected party abbreviations","status":"passed","title":"should include all expected party abbreviations","duration":2.74230399999999,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should have valid hex color codes","status":"passed","title":"should have valid hex color codes","duration":2.8481720000000337,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should have distinct colors for each party","status":"passed","title":"should have distinct colors for each party","duration":2.797187000000008,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should define 8 data source URLs","status":"passed","title":"should define 8 data source URLs","duration":2.8813639999999623,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should point to GitHub raw content","status":"passed","title":"should point to GitHub raw content","duration":3.100524000000007,"failureMessages":[],"location":{"line":189,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should reference CSV files","status":"passed","title":"should reference CSV files","duration":8.402560999999935,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should reference sample-data directory","status":"passed","title":"should reference sample-data directory","duration":2.307811000000015,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include risk-related datasets","status":"passed","title":"should include risk-related datasets","duration":1.8606529999999566,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include anomaly datasets","status":"passed","title":"should include anomaly datasets","duration":1.7546950000000834,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include top-10 datasets","status":"passed","title":"should include top-10 datasets","duration":1.5724129999999832,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 8.0-10.0 as CRITICAL","status":"passed","title":"should classify scores 8.0-10.0 as CRITICAL","duration":1.7658050000000003,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 6.0-7.99 as HIGH","status":"passed","title":"should classify scores 6.0-7.99 as HIGH","duration":1.784511000000066,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 4.0-5.99 as MEDIUM","status":"passed","title":"should classify scores 4.0-5.99 as MEDIUM","duration":1.5596289999999726,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 0.0-3.99 as LOW","status":"passed","title":"should classify scores 0.0-3.99 as LOW","duration":2.1252789999999777,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should handle boundary values correctly","status":"passed","title":"should handle boundary values correctly","duration":1.708148000000051,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return red for critical scores","status":"passed","title":"should return red for critical scores","duration":1.5613429999999653,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return orange for high scores","status":"passed","title":"should return orange for high scores","duration":1.6180990000000293,"failureMessages":[],"location":{"line":289,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return yellow for medium scores","status":"passed","title":"should return yellow for medium scores","duration":1.975958999999989,"failureMessages":[],"location":{"line":293,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return green for low scores","status":"passed","title":"should return green for low scores","duration":2.0781299999999874,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 15,705 data points (349 MPs × 45 rules)","status":"passed","title":"should generate 15,705 data points (349 MPs × 45 rules)","duration":6.591660000000047,"failureMessages":[],"location":{"line":337,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should assign all 8 parties to MPs","status":"passed","title":"should assign all 8 parties to MPs","duration":6.72394799999995,"failureMessages":[],"location":{"line":342,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 349 unique politicians","status":"passed","title":"should generate 349 unique politicians","duration":7.207263000000012,"failureMessages":[],"location":{"line":348,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 45 unique rules","status":"passed","title":"should generate 45 unique rules","duration":17.428058000000078,"failureMessages":[],"location":{"line":354,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate scores within 0-10 range","status":"passed","title":"should generate scores within 0-10 range","duration":301.5770520000001,"failureMessages":[],"location":{"line":360,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should have proper data structure for each entry","status":"passed","title":"should have proper data structure for each entry","duration":5.975947000000019,"failureMessages":[],"location":{"line":368,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate realistic risk distribution (majority low)","status":"passed","title":"should generate realistic risk distribution (majority low)","duration":5.819063999999912,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should assign consistent level labels","status":"passed","title":"should assign consistent level labels","duration":308.1676000000001,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should format politician names with zero-padded index","status":"passed","title":"should format politician names with zero-padded index","duration":6.023807000000033,"failureMessages":[],"location":{"line":394,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should format rule IDs with zero-padded index","status":"passed","title":"should format rule IDs with zero-padded index","duration":5.4936649999999645,"failureMessages":[],"location":{"line":400,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P50 (median) correctly","status":"passed","title":"should calculate P50 (median) correctly","duration":1.9201540000001387,"failureMessages":[],"location":{"line":418,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P90 correctly","status":"passed","title":"should calculate P90 correctly","duration":1.717335999999932,"failureMessages":[],"location":{"line":424,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P99 correctly","status":"passed","title":"should calculate P99 correctly","duration":8.160845999999992,"failureMessages":[],"location":{"line":430,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should handle single-element arrays","status":"passed","title":"should handle single-element arrays","duration":1.826189000000113,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should handle unsorted input","status":"passed","title":"should handle unsorted input","duration":1.8020939999998973,"failureMessages":[],"location":{"line":441,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should not mutate original array","status":"passed","title":"should not mutate original array","duration":2.638879999999972,"failureMessages":[],"location":{"line":447,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have risk dashboard section","status":"passed","title":"should have risk dashboard section","duration":1.962003999999979,"failureMessages":[],"location":{"line":460,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.208554000000049,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have early warnings banner with ARIA attributes","status":"passed","title":"should have early warnings banner with ARIA attributes","duration":1.7955520000000433,"failureMessages":[],"location":{"line":469,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have risk heat map container","status":"passed","title":"should have risk heat map container","duration":1.8263389999999617,"failureMessages":[],"location":{"line":477,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have heat map legend","status":"passed","title":"should have heat map legend","duration":1.8038369999999304,"failureMessages":[],"location":{"line":483,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":1.8630880000000616,"failureMessages":[],"location":{"line":489,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have top 10 lists","status":"passed","title":"should have top 10 lists","duration":1.862547000000177,"failureMessages":[],"location":{"line":496,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have last updated span","status":"passed","title":"should have last updated span","duration":2.035219999999981,"failureMessages":[],"location":{"line":505,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have filter controls","status":"passed","title":"should have filter controls","duration":1.8822339999999258,"failureMessages":[],"location":{"line":511,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have accessible chart canvases with role=img","status":"passed","title":"should have accessible chart canvases with role=img","duration":2.524756000000025,"failureMessages":[],"location":{"line":517,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have aria-labels on chart canvases","status":"passed","title":"should have aria-labels on chart canvases","duration":2.443373999999949,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have accessible top 10 lists with aria-labels","status":"passed","title":"should have accessible top 10 lists with aria-labels","duration":2.128024000000096,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have high-risk filter checkbox","status":"passed","title":"should have high-risk filter checkbox","duration":1.9943640000001324,"failureMessages":[],"location":{"line":542,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have risk rule filter dropdown","status":"passed","title":"should have risk rule filter dropdown","duration":2.023889000000054,"failureMessages":[],"location":{"line":549,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have \"All Rules\" default option","status":"passed","title":"should have \"All Rules\" default option","duration":3.201663999999937,"failureMessages":[],"location":{"line":556,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have reset zoom button","status":"passed","title":"should have reset zoom button","duration":2.076456999999891,"failureMessages":[],"location":{"line":562,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display critical alert when critical MPs exist","status":"passed","title":"should display critical alert when critical MPs exist","duration":2.590750000000071,"failureMessages":[],"location":{"line":574,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display high alert for elevated risk","status":"passed","title":"should display high alert for elevated risk","duration":2.529444999999896,"failureMessages":[],"location":{"line":587,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display normal status when risks are acceptable","status":"passed","title":"should display normal status when risks are acceptable","duration":2.3505599999998594,"failureMessages":[],"location":{"line":596,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should set assertive aria-live for critical alerts","status":"passed","title":"should set assertive aria-live for critical alerts","duration":2.3353819999999814,"failureMessages":[],"location":{"line":605,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should set polite aria-live for non-critical alerts","status":"passed","title":"should set polite aria-live for non-critical alerts","duration":2.203866000000062,"failureMessages":[],"location":{"line":611,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle successful CSV fetch","status":"passed","title":"should handle successful CSV fetch","duration":2.6842659999999796,"failureMessages":[],"location":{"line":623,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle failed CSV fetch gracefully","status":"passed","title":"should handle failed CSV fetch gracefully","duration":2.496544999999969,"failureMessages":[],"location":{"line":638,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle network errors gracefully","status":"passed","title":"should handle network errors gracefully","duration":4.25550700000008,"failureMessages":[],"location":{"line":647,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should parse risk_level CSV columns","status":"passed","title":"should parse risk_level CSV columns","duration":13.38082200000008,"failureMessages":[],"location":{"line":655,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should parse politician_count as integer","status":"passed","title":"should parse politician_count as integer","duration":7.624414000000115,"failureMessages":[],"location":{"line":664,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should transform risk data into matrix format","status":"passed","title":"should transform risk data into matrix format","duration":5.404647999999952,"failureMessages":[],"location":{"line":675,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for risk distribution chart","status":"passed","title":"should have canvas context for risk distribution chart","duration":4.88417400000003,"failureMessages":[],"location":{"line":710,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for anomaly detection chart","status":"passed","title":"should have canvas context for anomaly detection chart","duration":4.54430699999989,"failureMessages":[],"location":{"line":716,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for crisis resilience chart","status":"passed","title":"should have canvas context for crisis resilience chart","duration":13.959614999999985,"failureMessages":[],"location":{"line":721,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for risk evolution chart","status":"passed","title":"should have canvas context for risk evolution chart","duration":3.9477999999999156,"failureMessages":[],"location":{"line":726,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create risk distribution chart with bar type","status":"passed","title":"should create risk distribution chart with bar type","duration":2.570261000000073,"failureMessages":[],"location":{"line":731,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create anomaly detection chart with scatter type","status":"passed","title":"should create anomaly detection chart with scatter type","duration":2.396266000000196,"failureMessages":[],"location":{"line":745,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create crisis resilience chart with radar type","status":"passed","title":"should create crisis resilience chart with radar type","duration":2.4960430000000997,"failureMessages":[],"location":{"line":761,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create risk evolution chart with line type","status":"passed","title":"should create risk evolution chart with line type","duration":2.5554839999999786,"failureMessages":[],"location":{"line":774,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should populate ethics concerns list with OL items","status":"passed","title":"should populate ethics concerns list with OL items","duration":3.0763590000001386,"failureMessages":[],"location":{"line":797,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should populate electoral risk list with OL items","status":"passed","title":"should populate electoral risk list with OL items","duration":2.951436000000058,"failureMessages":[],"location":{"line":812,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should sort ethics concerns by descending score","status":"passed","title":"should sort ethics concerns by descending score","duration":2.9760909999999967,"failureMessages":[],"location":{"line":825,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Heat Map Legend"],"fullName":"Risk Dashboard Heat Map Legend should render 4 legend items","status":"passed","title":"should render 4 legend items","duration":5.286736999999903,"failureMessages":[],"location":{"line":838,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should have data source link to CIA Platform","status":"passed","title":"should have data source link to CIA Platform","duration":3.235928000000058,"failureMessages":[],"location":{"line":869,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should have external link safety attributes","status":"passed","title":"should have external link safety attributes","duration":3.2236159999999927,"failureMessages":[],"location":{"line":875,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should display last updated timestamp placeholder","status":"passed","title":"should display last updated timestamp placeholder","duration":3.2278929999999946,"failureMessages":[],"location":{"line":880,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should update timestamp with locale format","status":"passed","title":"should update timestamp with locale format","duration":17.853844999999865,"failureMessages":[],"location":{"line":885,"column":5},"meta":{},"tags":[]}],"startTime":1787953660371,"endTime":1787953661301.8538,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/risk-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["addDays"],"fullName":"addDays adds days to a date string","status":"passed","title":"adds days to a date string","duration":4.0711540000000355,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["addDays"],"fullName":"addDays handles year boundary","status":"passed","title":"handles year boundary","duration":0.5034329999999727,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["addDays"],"fullName":"addDays adds 0 days returns same date","status":"passed","title":"adds 0 days returns same date","duration":0.5055259999999748,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for quarter-ahead","status":"passed","title":"returns true for quarter-ahead","duration":0.3987070000000017,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for year-ahead","status":"passed","title":"returns true for year-ahead","duration":0.41139100000003737,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for election-cycle","status":"passed","title":"returns true for election-cycle","duration":0.49675999999999476,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for month-ahead","status":"passed","title":"returns false for month-ahead","duration":0.46575200000000905,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for week-ahead","status":"passed","title":"returns false for week-ahead","duration":0.35643699999997125,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for morning cycles","status":"passed","title":"returns false for morning cycles","duration":0.5650789999999688,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd produces Markdown with correct header","status":"passed","title":"produces Markdown with correct header","duration":1.3592550000000188,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes predecessor manifest with days-since","status":"passed","title":"includes predecessor manifest with days-since","duration":0.7719050000000038,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes PIR genealogy table with correct columns","status":"passed","title":"includes PIR genealogy table with correct columns","duration":0.5851260000000025,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd stamps open PIRs with obsolescence date = targetDate + horizonDays","status":"passed","title":"stamps open PIRs with obsolescence date = targetDate + horizonDays","duration":0.6492959999999925,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks non-open PIRs with \"—\" for obsolescence date","status":"passed","title":"marks non-open PIRs with \"—\" for obsolescence date","duration":0.5653490000000261,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes section 3 with active PIR details","status":"passed","title":"includes section 3 with active PIR details","duration":0.7672059999999874,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes section 4 with archived PIRs","status":"passed","title":"includes section 4 with archived PIRs","duration":0.6361009999999965,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd uses 365 days for year-ahead cycle","status":"passed","title":"uses 365 days for year-ahead cycle","duration":0.5418249999999603,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd derives predecessor from output.inherited_from (not path.relative)","status":"passed","title":"derives predecessor from output.inherited_from (not path.relative)","duration":0.7046900000000278,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks all PIRs as inherited when sourcePirIds contains them","status":"passed","title":"marks all PIRs as inherited when sourcePirIds contains them","duration":0.7232339999999908,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks new PIRs as \"this run\" when not in sourcePirIds","status":"passed","title":"marks new PIRs as \"this run\" when not in sourcePirIds","duration":0.6599659999999972,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration auto-emits horizon-pir-rollforward.md for quarter-ahead cycle","status":"passed","title":"auto-emits horizon-pir-rollforward.md for quarter-ahead cycle","duration":2.8912650000000326,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration does NOT auto-emit for month-ahead cycle (horizonDays < 90)","status":"passed","title":"does NOT auto-emit for month-ahead cycle (horizonDays < 90)","duration":1.2447810000000459,"failureMessages":[],"location":{"line":362,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration emits when --emit-rollforward-md flag is used even for non-long-horizon","status":"passed","title":"emits when --emit-rollforward-md flag is used even for non-long-horizon","duration":1.265260000000012,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration idempotency — re-running produces identical output","status":"passed","title":"idempotency — re-running produces identical output","duration":1.4808729999999741,"failureMessages":[],"location":{"line":402,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration auto-emits for election-cycle","status":"passed","title":"auto-emits for election-cycle","duration":1.4236569999999915,"failureMessages":[],"location":{"line":433,"column":3},"meta":{},"tags":[]}],"startTime":1787953784750,"endTime":1787953784774.4236,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/roll-forward-pirs.rollforward-md.test.ts"},{"assertionResults":[{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml escapes the five XML metacharacters","status":"passed","title":"escapes the five XML metacharacters","duration":3.662286999999992,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml preserves valid pre-encoded numeric, hex, and named entities","status":"passed","title":"preserves valid pre-encoded numeric, hex, and named entities","duration":0.5732230000000413,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml escapes a stray ampersand in plain prose like \"R&D\"","status":"passed","title":"escapes a stray ampersand in plain prose like \"R&D\"","duration":0.439803999999981,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml uses XML-canonical ' for apostrophes (NOT HTML ')","status":"passed","title":"uses XML-canonical ' for apostrophes (NOT HTML ')","duration":0.41192100000000664,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode maps `no` → `nb`","status":"passed","title":"maps `no` → `nb`","duration":0.43432300000000623,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes en through unchanged","status":"passed","title":"passes en through unchanged","duration":0.41178100000001905,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes sv through unchanged","status":"passed","title":"passes sv through unchanged","duration":0.31771500000002106,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes de through unchanged","status":"passed","title":"passes de through unchanged","duration":0.37176600000003646,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes ja through unchanged","status":"passed","title":"passes ja through unchanged","duration":0.35324100000002545,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes zh through unchanged","status":"passed","title":"passes zh through unchanged","duration":0.2769079999999917,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate parses a YYYY-MM-DD prefix as 12:00 UTC for determinism","status":"passed","title":"parses a YYYY-MM-DD prefix as 12:00 UTC for determinism","duration":0.6914449999999874,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate does not consult the filesystem when the filename has a date prefix","status":"passed","title":"does not consult the filesystem when the filename has a date prefix","duration":0.351257999999973,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate falls back to the fixed sentinel when stat fails AND no date prefix","status":"passed","title":"falls back to the fixed sentinel when stat fails AND no date prefix","duration":0.3999579999999696,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate uses filesystem mtime when no date prefix but the file exists","status":"passed","title":"uses filesystem mtime when no date prefix but the file exists","duration":1.2015989999999874,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta returns sentinel defaults when the article file does not exist","status":"passed","title":"returns sentinel defaults when the article file does not exist","duration":0.7407969999999864,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta uses path.basename so the title falls back to the bare filename without .html","status":"passed","title":"uses path.basename so the title falls back to the bare filename without .html","duration":0.45067299999999477,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta uses the absolute basename of a relative path too","status":"passed","title":"uses the absolute basename of a relative path too","duration":0.4999870000000328,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss returns true on a structurally valid feed","status":"passed","title":"returns true on a structurally valid feed","duration":0.7407870000000116,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the XML declaration is missing","status":"passed","title":"throws when the XML declaration is missing","duration":1.2310849999999505,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the RSS version is wrong or missing","status":"passed","title":"throws when the RSS version is wrong or missing","duration":0.46060200000005125,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the channel envelope is missing","status":"passed","title":"throws when the channel envelope is missing","duration":0.5325970000000098,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when there are no items","status":"passed","title":"throws when there are no items","duration":0.4505829999999946,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when item count and required-tag count diverge","status":"passed","title":"throws when item count and required-tag count diverge","duration":0.62120299999998,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]}],"startTime":1787953870631,"endTime":1787953870646.621,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rss-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["rss-watch"],"fullName":"rss-watch parses RSS items and builds PIR match signals","status":"passed","title":"parses RSS items and builds PIR match signals","duration":6.5081160000000295,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss-watch"],"fullName":"rss-watch returns PIR integration note in watch output","status":"passed","title":"returns PIR integration note in watch output","duration":2.074122999999986,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss-watch"],"fullName":"rss-watch does not match dok_id prefixes against longer dok_ids","status":"passed","title":"does not match dok_id prefixes against longer dok_ids","duration":0.5937309999999911,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953934152,"endTime":1787953934161.5938,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rss-watch.test.ts"},{"assertionResults":[{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem returns true on a successful write","status":"passed","title":"returns true on a successful write","duration":4.165168999999992,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem evicts oldest same-prefix entries on quota and retries","status":"passed","title":"evicts oldest same-prefix entries on quota and retries","duration":1.0819359999999847,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem returns false (silently) when payload still exceeds quota after eviction","status":"passed","title":"returns false (silently) when payload still exceeds quota after eviction","duration":0.6754839999999831,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem does NOT evict on SecurityError (storage disabled)","status":"passed","title":"does NOT evict on SecurityError (storage disabled)","duration":0.6019370000000208,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]}],"startTime":1787953905404,"endTime":1787953905410.602,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/safe-storage.test.ts"},{"assertionResults":[{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should use default config when no options provided","status":"passed","title":"should use default config when no options provided","duration":3.860638999999992,"failureMessages":[],"location":{"line":32,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should accept custom config","status":"passed","title":"should accept custom config","duration":0.5411129999999957,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should use defaults for missing config fields","status":"passed","title":"should use defaults for missing config fields","duration":0.5368249999999648,"failureMessages":[],"location":{"line":51,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should find domain by exact key","status":"passed","title":"should find domain by exact key","duration":1.2194839999999658,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should find domain case-insensitively","status":"passed","title":"should find domain case-insensitively","duration":0.4488309999999842,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should return undefined for unknown domain","status":"passed","title":"should return undefined for unknown domain","duration":0.5411629999999832,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getDomainsWithTables"],"fullName":"SCBClient getDomainsWithTables should return only domains with non-empty tables arrays","status":"passed","title":"should return only domains with non-empty tables arrays","duration":1.066096000000016,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getDomainsWithTables"],"fullName":"SCBClient getDomainsWithTables should not include domains without tables","status":"passed","title":"should not include domains without tables","duration":0.6795529999999985,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should return null for empty data points","status":"passed","title":"should return null for empty data points","duration":0.6716279999999983,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should build indicator from single data point","status":"passed","title":"should build indicator from single data point","duration":0.6079179999999837,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"up\" trend when latest > previous","status":"passed","title":"should compute \"up\" trend when latest > previous","duration":0.43996399999997493,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"down\" trend when latest < previous","status":"passed","title":"should compute \"down\" trend when latest < previous","duration":0.3473599999999806,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"stable\" trend when values are essentially equal","status":"passed","title":"should compute \"stable\" trend when values are essentially equal","duration":0.38857699999999795,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should use fallback unit when data point has empty unit","status":"passed","title":"should use fallback unit when data point has empty unit","duration":0.33089999999998554,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","searchTables"],"fullName":"SCBClient searchTables should return empty array on network failure","status":"passed","title":"should return empty array on network failure","duration":1.5606319999999982,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getTableData"],"fullName":"SCBClient getTableData should return empty array on network failure","status":"passed","title":"should return empty array on network failure","duration":0.6181080000000065,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should contain 15 policy domains","status":"passed","title":"should contain 15 policy domains","duration":0.7947990000000118,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have unique domain names","status":"passed","title":"should have unique domain names","duration":0.46480999999999995,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should cover all expected domains","status":"passed","title":"should cover all expected domains","duration":1.1135150000000067,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have non-empty query for every domain","status":"passed","title":"should have non-empty query for every domain","duration":0.7231249999999818,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have at least one indicator per domain","status":"passed","title":"should have at least one indicator per domain","duration":0.8420869999999923,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS labour domain should have TAB5765 and TAB5616","status":"passed","title":"labour domain should have TAB5765 and TAB5616","duration":0.6221560000000181,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS migration domain should have TAB637","status":"passed","title":"migration domain should have TAB637","duration":0.5382469999999557,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getDefaultSCBClient"],"fullName":"getDefaultSCBClient should return an SCBClient instance","status":"passed","title":"should return an SCBClient instance","duration":0.60177699999997,"failureMessages":[],"location":{"line":251,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getDefaultSCBClient"],"fullName":"getDefaultSCBClient should return the same instance on repeated calls","status":"passed","title":"should return the same instance on repeated calls","duration":0.49269300000003113,"failureMessages":[],"location":{"line":256,"column":3},"meta":{},"tags":[]}],"startTime":1787953831435,"endTime":1787953831455.6018,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-client.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have 15 domain contexts","status":"passed","title":"should have 15 domain contexts","duration":4.604409999999973,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have unique domain names","status":"passed","title":"should have unique domain names","duration":0.6977959999999825,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have non-empty name and description for each context","status":"passed","title":"should have non-empty name and description for each context","duration":1.6025599999999827,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have at least one committee for each context","status":"passed","title":"should have at least one committee for each context","duration":0.7078750000000014,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have at least one indicator for each context","status":"passed","title":"should have at least one indicator for each context","duration":0.7752519999999663,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS labour domain should map to AU committee","status":"passed","title":"labour domain should map to AU committee","duration":0.8635669999999891,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS fiscal domain should map to FiU committee","status":"passed","title":"fiscal domain should map to FiU committee","duration":0.5787530000000061,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS justice domain should map to JuU committee","status":"passed","title":"justice domain should map to JuU committee","duration":0.5269270000000006,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS taxation domain should map to SkU committee","status":"passed","title":"taxation domain should map to SkU committee","duration":0.5608699999999658,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS culture domain should map to KrU committee","status":"passed","title":"culture domain should map to KrU committee","duration":0.621735000000001,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS governance domain should map to KU committee","status":"passed","title":"governance domain should map to KU committee","duration":0.49880300000000943,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS should have headings for all 14 languages","status":"passed","title":"should have headings for all 14 languages","duration":0.6535840000000235,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS should have all three section keys for each language","status":"passed","title":"should have all three section keys for each language","duration":1.3252509999999802,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS English headings should be in English","status":"passed","title":"English headings should be in English","duration":0.42629800000003115,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS Swedish headings should be in Swedish","status":"passed","title":"Swedish headings should be in Swedish","duration":0.4846469999999954,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS all data source headings should reference SCB","status":"passed","title":"all data source headings should reference SCB","duration":0.6605969999999957,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return English heading for known section","status":"passed","title":"should return English heading for known section","duration":0.47003999999998314,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return Swedish heading","status":"passed","title":"should return Swedish heading","duration":0.4192950000000337,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should fallback to English for unknown language","status":"passed","title":"should fallback to English for unknown language","duration":0.4254669999999692,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return data source heading","status":"passed","title":"should return data source heading","duration":0.4357760000000326,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty array for empty query","status":"passed","title":"should return empty array for empty query","duration":1.1991949999999747,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty array for whitespace-only query","status":"passed","title":"should return empty array for whitespace-only query","duration":0.5540380000000482,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find labour domain by domain name","status":"passed","title":"should find labour domain by domain name","duration":0.657039999999995,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find by committee abbreviation (case-insensitive)","status":"passed","title":"should find by committee abbreviation (case-insensitive)","duration":0.5245820000000094,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find by indicator name","status":"passed","title":"should find by indicator name","duration":0.631512999999984,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find fiscal domain by partial name","status":"passed","title":"should find fiscal domain by partial name","duration":0.692436999999984,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty for non-matching query","status":"passed","title":"should return empty for non-matching query","duration":0.6120249999999601,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for FiU committee","status":"passed","title":"should find tables for FiU committee","duration":0.7516779999999699,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for AU committee","status":"passed","title":"should find tables for AU committee","duration":0.5190119999999752,"failureMessages":[],"location":{"line":214,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for SkU (taxation) committee","status":"passed","title":"should find tables for SkU (taxation) committee","duration":0.5840729999999894,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for KrU (cultural affairs) committee","status":"passed","title":"should find tables for KrU (cultural affairs) committee","duration":0.7545129999999745,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should be case-insensitive","status":"passed","title":"should be case-insensitive","duration":0.6355099999999538,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should return empty array for unknown committee","status":"passed","title":"should return empty array for unknown committee","duration":0.59773899999999,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect SCB acronym","status":"passed","title":"should detect SCB acronym","duration":0.7320100000000025,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Statistiska centralbyrån","status":"passed","title":"should detect Statistiska centralbyrån","duration":0.674712999999997,"failureMessages":[],"location":{"line":249,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Statistics Sweden","status":"passed","title":"should detect Statistics Sweden","duration":0.5942420000000084,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect SCB table IDs","status":"passed","title":"should detect SCB table IDs","duration":0.7720549999999662,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Swedish statistical terms","status":"passed","title":"should detect Swedish statistical terms","duration":0.6417120000000409,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect officiell statistik","status":"passed","title":"should detect officiell statistik","duration":0.5618119999999749,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should return false for unrelated content","status":"passed","title":"should return false for unrelated content","duration":0.6399069999999938,"failureMessages":[],"location":{"line":269,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should return false for empty string","status":"passed","title":"should return false for empty string","duration":0.6024479999999812,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should return only domains with table IDs","status":"passed","title":"should return only domains with table IDs","duration":1.0467899999999872,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should include domain and query for each result","status":"passed","title":"should include domain and query for each result","duration":1.112653000000023,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should include labour domain with TAB5765","status":"passed","title":"should include labour domain with TAB5765","duration":0.7807920000000195,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should not include domains without tables (defence, healthcare, transport, governance)","status":"passed","title":"should not include domains without tables (defence, healthcare, transport, governance)","duration":0.9669000000000096,"failureMessages":[],"location":{"line":306,"column":3},"meta":{},"tags":[]}],"startTime":1787953824317,"endTime":1787953824353.9668,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-context.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers exposes KPI, AKU, household-economy and fuel-price presets","status":"passed","title":"exposes KPI, AKU, household-economy and fuel-price presets","duration":4.494055000000003,"failureMessages":[],"location":{"line":18,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers parses command flags and JSON value codes","status":"passed","title":"parses command flags and JSON value codes","duration":0.9373760000000289,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers builds a periods fallback value code","status":"passed","title":"builds a periods fallback value code","duration":0.40357599999998683,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers throws for invalid CLI input","status":"passed","title":"throws for invalid CLI input","duration":1.6710390000000075,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers emits SCB provenance and fail-soft no-data payload on outage","status":"passed","title":"emits SCB provenance and fail-soft no-data payload on outage","duration":1.4303280000000314,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953925625,"endTime":1787953925634.4304,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration copilot-mcp.json should include scb MCP server","status":"passed","title":"copilot-mcp.json should include scb MCP server","duration":5.054424999999981,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration copilot-mcp.json should include world-bank MCP server","status":"passed","title":"copilot-mcp.json should include world-bank MCP server","duration":0.9845339999999965,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should configure scb MCP server","status":"passed","title":"news-committee-reports.md should configure scb MCP server","duration":0.6835000000000377,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should configure world-bank MCP server","status":"passed","title":"news-committee-reports.md should configure world-bank MCP server","duration":0.6126470000000381,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should allow api.scb.se in network","status":"passed","title":"news-committee-reports.md should allow api.scb.se in network","duration":0.898542999999961,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should allow api.worldbank.org in network","status":"passed","title":"news-committee-reports.md should allow api.worldbank.org in network","duration":0.6779700000000162,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should include api.scb.se in safe-outputs","status":"passed","title":"news-committee-reports.md should include api.scb.se in safe-outputs","duration":0.7586810000000241,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-committee-reports.md should include api.worldbank.org in safe-outputs","duration":0.6610680000000002,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should configure scb MCP server","status":"passed","title":"news-evening-analysis.md should configure scb MCP server","duration":0.5999340000000188,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should configure world-bank MCP server","status":"passed","title":"news-evening-analysis.md should configure world-bank MCP server","duration":0.6020979999999554,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should allow api.scb.se in network","status":"passed","title":"news-evening-analysis.md should allow api.scb.se in network","duration":1.0641120000000228,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should allow api.worldbank.org in network","status":"passed","title":"news-evening-analysis.md should allow api.worldbank.org in network","duration":0.6433749999999918,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should include api.scb.se in safe-outputs","status":"passed","title":"news-evening-analysis.md should include api.scb.se in safe-outputs","duration":0.6223960000000375,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-evening-analysis.md should include api.worldbank.org in safe-outputs","duration":0.547676000000024,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should configure scb MCP server","status":"passed","title":"news-month-ahead.md should configure scb MCP server","duration":0.5221480000000156,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should configure world-bank MCP server","status":"passed","title":"news-month-ahead.md should configure world-bank MCP server","duration":0.478336000000013,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should allow api.scb.se in network","status":"passed","title":"news-month-ahead.md should allow api.scb.se in network","duration":0.6055240000000026,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should allow api.worldbank.org in network","status":"passed","title":"news-month-ahead.md should allow api.worldbank.org in network","duration":0.6530329999999935,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should include api.scb.se in safe-outputs","status":"passed","title":"news-month-ahead.md should include api.scb.se in safe-outputs","duration":0.5891829999999914,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-month-ahead.md should include api.worldbank.org in safe-outputs","duration":0.627935999999977,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should configure scb MCP server","status":"passed","title":"news-monthly-review.md should configure scb MCP server","duration":0.5508820000000014,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should configure world-bank MCP server","status":"passed","title":"news-monthly-review.md should configure world-bank MCP server","duration":0.512990000000002,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should allow api.scb.se in network","status":"passed","title":"news-monthly-review.md should allow api.scb.se in network","duration":0.6274249999999597,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should allow api.worldbank.org in network","status":"passed","title":"news-monthly-review.md should allow api.worldbank.org in network","duration":0.6252610000000232,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should include api.scb.se in safe-outputs","status":"passed","title":"news-monthly-review.md should include api.scb.se in safe-outputs","duration":0.6400480000000357,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-monthly-review.md should include api.worldbank.org in safe-outputs","duration":0.6513089999999693,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should configure scb MCP server","status":"passed","title":"news-motions.md should configure scb MCP server","duration":0.5564519999999789,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should configure world-bank MCP server","status":"passed","title":"news-motions.md should configure world-bank MCP server","duration":0.5985610000000179,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should allow api.scb.se in network","status":"passed","title":"news-motions.md should allow api.scb.se in network","duration":0.6780190000000061,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should allow api.worldbank.org in network","status":"passed","title":"news-motions.md should allow api.worldbank.org in network","duration":0.6964839999999981,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should include api.scb.se in safe-outputs","status":"passed","title":"news-motions.md should include api.scb.se in safe-outputs","duration":0.7004320000000348,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-motions.md should include api.worldbank.org in safe-outputs","duration":0.7563159999999698,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should configure scb MCP server","status":"passed","title":"news-propositions.md should configure scb MCP server","duration":0.5636360000000309,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should configure world-bank MCP server","status":"passed","title":"news-propositions.md should configure world-bank MCP server","duration":2.6650300000000016,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should allow api.scb.se in network","status":"passed","title":"news-propositions.md should allow api.scb.se in network","duration":0.5688760000000457,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should allow api.worldbank.org in network","status":"passed","title":"news-propositions.md should allow api.worldbank.org in network","duration":0.5236309999999662,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should include api.scb.se in safe-outputs","status":"passed","title":"news-propositions.md should include api.scb.se in safe-outputs","duration":0.46885800000001154,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-propositions.md should include api.worldbank.org in safe-outputs","duration":0.5217470000000048,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should configure scb MCP server","status":"passed","title":"news-realtime-monitor.md should configure scb MCP server","duration":0.44795900000002575,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should configure world-bank MCP server","status":"passed","title":"news-realtime-monitor.md should configure world-bank MCP server","duration":0.47181399999999485,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should allow api.scb.se in network","status":"passed","title":"news-realtime-monitor.md should allow api.scb.se in network","duration":0.5160469999999577,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should allow api.worldbank.org in network","status":"passed","title":"news-realtime-monitor.md should allow api.worldbank.org in network","duration":0.7479810000000384,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should include api.scb.se in safe-outputs","status":"passed","title":"news-realtime-monitor.md should include api.scb.se in safe-outputs","duration":0.5775520000000256,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-realtime-monitor.md should include api.worldbank.org in safe-outputs","duration":0.5159360000000106,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should configure scb MCP server","status":"passed","title":"news-week-ahead.md should configure scb MCP server","duration":0.5061269999999922,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should configure world-bank MCP server","status":"passed","title":"news-week-ahead.md should configure world-bank MCP server","duration":0.4914999999999736,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should allow api.scb.se in network","status":"passed","title":"news-week-ahead.md should allow api.scb.se in network","duration":0.5617419999999811,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should allow api.worldbank.org in network","status":"passed","title":"news-week-ahead.md should allow api.worldbank.org in network","duration":0.5533959999999638,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should include api.scb.se in safe-outputs","status":"passed","title":"news-week-ahead.md should include api.scb.se in safe-outputs","duration":0.7169120000000362,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-week-ahead.md should include api.worldbank.org in safe-outputs","duration":0.979865000000018,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should configure scb MCP server","status":"passed","title":"news-weekly-review.md should configure scb MCP server","duration":0.749623999999983,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should configure world-bank MCP server","status":"passed","title":"news-weekly-review.md should configure world-bank MCP server","duration":0.7428199999999947,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should allow api.scb.se in network","status":"passed","title":"news-weekly-review.md should allow api.scb.se in network","duration":0.8462649999999599,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should allow api.worldbank.org in network","status":"passed","title":"news-weekly-review.md should allow api.worldbank.org in network","duration":0.838009999999997,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should include api.scb.se in safe-outputs","status":"passed","title":"news-weekly-review.md should include api.scb.se in safe-outputs","duration":0.9100540000000024,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-weekly-review.md should include api.worldbank.org in safe-outputs","duration":1.0216629999999896,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-evening-analysis.md should document SCB enrichment as optional","status":"passed","title":"news-evening-analysis.md should document SCB enrichment as optional","duration":0.9094430000000102,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-evening-analysis.md should instruct try/catch for SCB calls","status":"passed","title":"news-evening-analysis.md should instruct try/catch for SCB calls","duration":2.523454999999956,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-monthly-review.md should document SCB enrichment as optional","status":"passed","title":"news-monthly-review.md should document SCB enrichment as optional","duration":0.9135110000000282,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-monthly-review.md should instruct try/catch for SCB calls","status":"passed","title":"news-monthly-review.md should instruct try/catch for SCB calls","duration":1.8783169999999814,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-weekly-review.md should document SCB enrichment as optional","status":"passed","title":"news-weekly-review.md should document SCB enrichment as optional","duration":0.8750989999999774,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-weekly-review.md should instruct try/catch for SCB calls","status":"passed","title":"news-weekly-review.md should instruct try/catch for SCB calls","duration":2.069033999999988,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-propositions.md should document SCB enrichment as optional","status":"passed","title":"news-propositions.md should document SCB enrichment as optional","duration":0.9289400000000114,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-propositions.md should instruct try/catch for SCB calls","status":"passed","title":"news-propositions.md should instruct try/catch for SCB calls","duration":1.9241830000000277,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-motions.md should document SCB enrichment as optional","status":"passed","title":"news-motions.md should document SCB enrichment as optional","duration":0.9093720000000189,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-motions.md should instruct try/catch for SCB calls","status":"passed","title":"news-motions.md should instruct try/catch for SCB calls","duration":1.8920630000000074,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Data Types"],"fullName":"SCB Data Types types.ts should export SCBContext and SCBIndicator","status":"passed","title":"types.ts should export SCBContext and SCBIndicator","duration":1.6202639999999633,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB Data Types"],"fullName":"SCB Data Types ArticleContentData should include scbContext field","status":"passed","title":"ArticleContentData should include scbContext field","duration":3.5342579999999657,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]}],"startTime":1787953831907,"endTime":1787953831970.5342,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-mcp-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle returns a non-empty localised title for every mapped slug × language","status":"passed","title":"returns a non-empty localised title for every mapped slug × language","duration":40.296100999999965,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle keeps English titles byte-identical to the journalist body headings","status":"passed","title":"keeps English titles byte-identical to the journalist body headings","duration":0.8627549999999928,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle reuses the vetted artifact translation for delegated sections","status":"passed","title":"reuses the vetted artifact translation for delegated sections","duration":0.3844100000000026,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle localises journalist-framed and Deep Dive sections","status":"passed","title":"localises journalist-framed and Deep Dive sections","duration":0.3409189999999853,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle localises recurring journalist topical sections (Korean regression)","status":"passed","title":"localises recurring journalist topical sections (Korean regression)","duration":0.5245519999999715,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle reuses the vetted artifact translation for the stakeholder-map slug","status":"passed","title":"reuses the vetted artifact translation for the stakeholder-map slug","duration":0.38703499999996893,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle returns undefined for slugs without a curated localisation","status":"passed","title":"returns undefined for slugs without a curated localisation","duration":0.4612329999999929,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]}],"startTime":1787953856312,"endTime":1787953856355.4612,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/section-title-i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages declares every supported language in LANG_TITLE_WINDOWS","status":"passed","title":"declares every supported language in LANG_TITLE_WINDOWS","duration":4.141754999999989,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages declares every supported language in LANG_DESCRIPTION_WINDOWS","status":"passed","title":"declares every supported language in LANG_DESCRIPTION_WINDOWS","duration":1.0225750000000176,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for en (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for en (55-70 / 140-200)","duration":1.2908459999999877,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for sv (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for sv (55-70 / 140-200)","duration":0.43969300000003386,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for da (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for da (55-70 / 140-200)","duration":0.5302530000000161,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for no (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for no (55-70 / 140-200)","duration":0.49886500000002343,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for fi (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for fi (55-70 / 140-200)","duration":0.6164740000000393,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for de (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for de (55-70 / 140-200)","duration":0.42825099999998884,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for fr (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for fr (55-70 / 140-200)","duration":0.5781419999999571,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for es (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for es (55-70 / 140-200)","duration":0.37767800000000307,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for nl (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for nl (55-70 / 140-200)","duration":0.6572310000000243,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the RTL contract for ar (45-60 / 120-170)","status":"passed","title":"honours the RTL contract for ar (45-60 / 120-170)","duration":0.4393620000000169,"failureMessages":[],"location":{"line":82,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the RTL contract for he (45-60 / 120-170)","status":"passed","title":"honours the RTL contract for he (45-60 / 120-170)","duration":0.4707910000000197,"failureMessages":[],"location":{"line":82,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for ja (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for ja (30-45 / 70-120)","duration":0.5104550000000359,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for ko (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for ko (30-45 / 70-120)","duration":0.47859600000003866,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for zh (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for zh (30-45 / 70-120)","duration":0.37637399999999843,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises zh-CN → zh","status":"passed","title":"normalises zh-CN → zh","duration":0.6484050000000252,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises zh-Hans-CN → zh","status":"passed","title":"normalises zh-Hans-CN → zh","duration":0.41040900000001557,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises JA → ja","status":"passed","title":"normalises JA → ja","duration":0.3890480000000025,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises Ar → ar","status":"passed","title":"normalises Ar → ar","duration":0.3503160000000207,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises de → de","status":"passed","title":"normalises de → de","duration":0.5541479999999979,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises nb-NO → nb","status":"passed","title":"normalises nb-NO → nb","duration":0.38987000000003036,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises en_US → en","status":"passed","title":"normalises en_US → en","duration":0.6416419999999903,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag returns null for null / undefined / whitespace","status":"passed","title":"returns null for null / undefined / whitespace","duration":0.5855169999999816,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["titleWindowForLanguage / descriptionWindowForLanguage — fallback"],"fullName":"titleWindowForLanguage / descriptionWindowForLanguage — fallback falls back to EN window for null / undefined / unknown lang","status":"passed","title":"falls back to EN window for null / undefined / unknown lang","duration":0.726269000000002,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["titleWindowForLanguage / descriptionWindowForLanguage — fallback"],"fullName":"titleWindowForLanguage / descriptionWindowForLanguage — fallback resolves BCP-47 region variants to the primary-subtag window","status":"passed","title":"resolves BCP-47 region variants to the primary-subtag window","duration":0.5144629999999779,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=en","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=en","duration":4.586506999999983,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=sv","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=sv","duration":0.40787400000004936,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=da","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=da","duration":0.3483019999999897,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=no","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=no","duration":0.3704840000000331,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=fi","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=fi","duration":0.3652139999999804,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=de","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=de","duration":0.3462279999999964,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=fr","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=fr","duration":2.2168910000000324,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=es","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=es","duration":0.4017420000000129,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=nl","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=nl","duration":0.3875859999999989,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ar","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ar","duration":0.5333380000000147,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=he","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=he","duration":0.571610000000021,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ja","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ja","duration":0.47690299999999297,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ko","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ko","duration":0.5350819999999885,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=zh","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=zh","duration":0.5381579999999531,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax CJK ja: 50-glyph H1 clamps to ≤ 45 glyphs and drops brand suffix","status":"passed","title":"CJK ja: 50-glyph H1 clamps to ≤ 45 glyphs and drops brand suffix","duration":0.8307050000000231,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax RTL ar: a 100-char Arabic H1 clamps to ≤ 60 chars","status":"passed","title":"RTL ar: a 100-char Arabic H1 clamps to ≤ 60 chars","duration":0.8334900000000403,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax Latin LTR: existing 70-char SERP budget unchanged for EN","status":"passed","title":"Latin LTR: existing 70-char SERP budget unchanged for EN","duration":0.5795049999999833,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=en","status":"passed","title":"clamps a long description to ≤ hardMax for lang=en","duration":1.2025409999999965,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=sv","status":"passed","title":"clamps a long description to ≤ hardMax for lang=sv","duration":0.610102999999981,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=da","status":"passed","title":"clamps a long description to ≤ hardMax for lang=da","duration":0.6517299999999864,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=no","status":"passed","title":"clamps a long description to ≤ hardMax for lang=no","duration":0.6581719999999791,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=fi","status":"passed","title":"clamps a long description to ≤ hardMax for lang=fi","duration":0.6295390000000225,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=de","status":"passed","title":"clamps a long description to ≤ hardMax for lang=de","duration":0.7165620000000104,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=fr","status":"passed","title":"clamps a long description to ≤ hardMax for lang=fr","duration":0.6889400000000023,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=es","status":"passed","title":"clamps a long description to ≤ hardMax for lang=es","duration":0.654184999999984,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=nl","status":"passed","title":"clamps a long description to ≤ hardMax for lang=nl","duration":0.7277529999999501,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ar","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ar","duration":1.2853769999999827,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=he","status":"passed","title":"clamps a long description to ≤ hardMax for lang=he","duration":0.8011599999999817,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ja","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ja","duration":0.7965829999999983,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ko","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ko","duration":0.7921729999999911,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=zh","status":"passed","title":"clamps a long description to ≤ hardMax for lang=zh","duration":0.7901089999999726,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax falls back to EN 200-char budget when lang is omitted","status":"passed","title":"falls back to EN 200-char budget when lang is omitted","duration":0.9889120000000275,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax synthesises a non-empty description from the title when description is empty","status":"passed","title":"synthesises a non-empty description from the title when description is empty","duration":1.0737600000000498,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax synthesises from the localized article-type label when both description and title are empty","status":"passed","title":"synthesises from the localized article-type label when both description and title are empty","duration":0.896959000000038,"failureMessages":[],"location":{"line":285,"column":3},"meta":{},"tags":[]}],"startTime":1787953736137,"endTime":1787953736184.897,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/seo-budget-windows.test.ts"},{"assertionResults":[{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 9 Latin LTR languages with 140-200 windows","status":"passed","title":"declares the 9 Latin LTR languages with 140-200 windows","duration":4.814464999999984,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 2 RTL languages (ar, he) with 120-170 windows","status":"passed","title":"declares the 2 RTL languages (ar, he) with 120-170 windows","duration":0.6239489999999819,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 3 CJK languages (ja, ko, zh) with 70-120 windows","status":"passed","title":"declares the 3 CJK languages (ja, ko, zh) with 70-120 windows","duration":0.6020269999999641,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares exactly 14 languages (the supported set)","status":"passed","title":"declares exactly 14 languages (the supported set)","duration":0.5598679999999945,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage returns the canonical window for known languages","status":"passed","title":"returns the canonical window for known languages","duration":0.7020650000000046,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage falls back to the EN window for unknown languages","status":"passed","title":"falls back to the EN window for unknown languages","duration":0.699610000000007,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage is case-insensitive — upper / mixed-case BCP-47 codes resolve to the canonical window","status":"passed","title":"is case-insensitive — upper / mixed-case BCP-47 codes resolve to the canonical window","duration":0.7002720000000409,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage handles BCP-47 region subtags (zh-CN, zh-TW, nb-NO, …) by collapsing to the primary subtag","status":"passed","title":"handles BCP-47 region subtags (zh-CN, zh-TW, nb-NO, …) by collapsing to the primary subtag","duration":0.5775709999999776,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Aggregator barrel — W2 description-window API is re-exported"],"fullName":"Aggregator barrel — W2 description-window API is re-exported exposes LANG_DESCRIPTION_WINDOWS and descriptionWindowForLanguage from the aggregator barrel","status":"passed","title":"exposes LANG_DESCRIPTION_WINDOWS and descriptionWindowForLanguage from the aggregator barrel","duration":57.99179299999997,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates a CJK description within the 70-120 char window","status":"passed","title":"truncates a CJK description within the 70-120 char window","duration":0.9326159999999959,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates an RTL (Arabic) description within the 120-170 char window","status":"passed","title":"truncates an RTL (Arabic) description within the 120-170 char window","duration":0.883685000000014,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates a Latin LTR description within the 140-200 char window (unchanged)","status":"passed","title":"truncates a Latin LTR description within the 140-200 char window (unchanged)","duration":0.8518649999999752,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the CJK 70-120 window when lang=\"ja\"","status":"passed","title":"honors the CJK 70-120 window when lang=\"ja\"","duration":25.752087999999958,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window falls back to the EN 140-200 window when lang is omitted (back-compat)","status":"passed","title":"falls back to the EN 140-200 window when lang is omitted (back-compat)","duration":10.069023000000016,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the RTL 120-170 window when lang=\"ar\"","status":"passed","title":"honors the RTL 120-170 window when lang=\"ar\"","duration":6.167467999999985,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the Latin LTR 140-200 window when lang=\"de\" (unchanged behaviour)","status":"passed","title":"honors the Latin LTR 140-200 window when lang=\"de\" (unchanged behaviour)","duration":16.091088000000013,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection flags a 5-name comma-separated MP roster","status":"passed","title":"flags a 5-name comma-separated MP roster","duration":0.9915869999999813,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection flags a roster with parenthetical party suffixes","status":"passed","title":"flags a roster with parenthetical party suffixes","duration":0.4885550000000194,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a prose paragraph with a single comma","status":"passed","title":"does NOT flag a prose paragraph with a single comma","duration":0.4163389999999936,"failureMessages":[],"location":{"line":250,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a list of 2 names (below threshold)","status":"passed","title":"does NOT flag a list of 2 names (below threshold)","duration":0.47111199999994824,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a list that contains a sentence terminator early","status":"passed","title":"does NOT flag a list that contains a sentence terminator early","duration":0.5893539999999575,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection readFirstParagraph skips an entity-roster lead in favour of the next prose paragraph","status":"passed","title":"readFirstParagraph skips an entity-roster lead in favour of the next prose paragraph","duration":4.030977999999891,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]}],"startTime":1787953792010,"endTime":1787953792146.031,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/seo-description-windows.test.ts"},{"assertionResults":[{"ancestorTitles":["service worker (public/sw.js)","source integrity"],"fullName":"service worker (public/sw.js) source integrity public/sw.js retains the __BUILD_ID__ placeholder for the build plugin","status":"passed","title":"public/sw.js retains the __BUILD_ID__ placeholder for the build plugin","duration":4.969985000000008,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration registers install, activate, fetch, and message handlers","status":"passed","title":"registers install, activate, fetch, and message handlers","duration":1.284604999999999,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration install handler calls skipWaiting (no synchronous pre-cache work)","status":"passed","title":"install handler calls skipWaiting (no synchronous pre-cache work)","duration":1.4624290000000428,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration message handler calls skipWaiting on { type: \"SKIP_WAITING\" }","status":"passed","title":"message handler calls skipWaiting on { type: \"SKIP_WAITING\" }","duration":1.0914129999999886,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration message handler ignores unrelated messages","status":"passed","title":"message handler ignores unrelated messages","duration":1.357531999999992,"failureMessages":[],"location":{"line":220,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation keeps current build HTML cache and cia-data; evicts every other cache","status":"passed","title":"keeps current build HTML cache and cia-data; evicts every other cache","duration":2.3624530000000163,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation different BUILD_ID yields different HTML cache name","status":"passed","title":"different BUILD_ID yields different HTML cache name","duration":3.3548720000000003,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation build N activate evicts build N-1 HTML cache","status":"passed","title":"build N activate evicts build N-1 HTML cache","duration":2.9756509999999707,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing non-GET requests are not intercepted","status":"passed","title":"non-GET requests are not intercepted","duration":2.081075999999996,"failureMessages":[],"location":{"line":294,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing CSS requests are NOT intercepted (HTTP cache + must-revalidate handle them)","status":"passed","title":"CSS requests are NOT intercepted (HTTP cache + must-revalidate handle them)","duration":1.2795550000000162,"failureMessages":[],"location":{"line":303,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing script/image/font requests bypass the SW","status":"passed","title":"script/image/font requests bypass the SW","duration":1.3513000000000375,"failureMessages":[],"location":{"line":314,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing navigation requests with mode=\"navigate\" are handled even without destination=document","status":"passed","title":"navigation requests with mode=\"navigate\" are handled even without destination=document","duration":2.8194990000000075,"failureMessages":[],"location":{"line":327,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate populates the cache on first fetch","status":"passed","title":"populates the cache on first fetch","duration":4.98414200000002,"failureMessages":[],"location":{"line":341,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate returns cached response immediately on second fetch","status":"passed","title":"returns cached response immediately on second fetch","duration":3.455209000000025,"failureMessages":[],"location":{"line":366,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate falls back to cache when network fails","status":"passed","title":"falls back to cache when network fails","duration":2.4089099999999917,"failureMessages":[],"location":{"line":386,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback serves the network response when available and populates the cache","status":"passed","title":"serves the network response when available and populates the cache","duration":6.777169000000015,"failureMessages":[],"location":{"line":414,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback returns latest network response even when a cached copy exists (network-first)","status":"passed","title":"returns latest network response even when a cached copy exists (network-first)","duration":6.741401999999994,"failureMessages":[],"location":{"line":439,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback falls back to the cached response when the network throws (offline)","status":"passed","title":"falls back to the cached response when the network throws (offline)","duration":5.553217000000018,"failureMessages":[],"location":{"line":461,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback returns an inline 503 offline page when both network and cache fail","status":"passed","title":"returns an inline 503 offline page when both network and cache fail","duration":6.847320000000025,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback falls back to cache when the network hangs longer than the timeout","status":"passed","title":"falls back to cache when the network hangs longer than the timeout","duration":5.22218799999996,"failureMessages":[],"location":{"line":504,"column":5},"meta":{},"tags":[]}],"startTime":1787953682823,"endTime":1787953682892.2222,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/service-worker.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should generate valid XML string","status":"passed","title":"should generate valid XML string","duration":3.6591000000000804,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should be valid XML","status":"passed","title":"should be valid XML","duration":40.48187000000007,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should have URL entries","status":"passed","title":"should have URL entries","duration":3.3404839999999467,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should have hreflang support","status":"passed","title":"should have hreflang support","duration":0.4955080000000862,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include main index page","status":"passed","title":"should include main index page","duration":0.4598009999999704,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include all 14 language index pages","status":"passed","title":"should include all 14 language index pages","duration":0.9006060000000389,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include politician dashboard","status":"passed","title":"should include politician dashboard","duration":0.5919580000000906,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Dashboard Pages Coverage"],"fullName":"Sitemap Generation Dashboard Pages Coverage should include English dashboard","status":"passed","title":"should include English dashboard","duration":0.3462090000000444,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Dashboard Pages Coverage"],"fullName":"Sitemap Generation Dashboard Pages Coverage should include dashboard pages for all languages","status":"passed","title":"should include dashboard pages for all languages","duration":3.2649829999999156,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include news index page","status":"passed","title":"should include news index page","duration":0.39907800000003135,"failureMessages":[],"location":{"line":109,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include news articles","status":"passed","title":"should include news articles","duration":3.2926049999999805,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include articles in multiple languages","status":"passed","title":"should include articles in multiple languages","duration":1.250069999999937,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include hreflang alternates for news articles","status":"passed","title":"should include hreflang alternates for news articles","duration":0.44541400000002795,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include API index page if api directory exists","status":"passed","title":"should include API index page if api directory exists","duration":0.34913299999993797,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include API documentation files if api directory exists","status":"passed","title":"should include API documentation files if api directory exists","duration":0.39174400000001697,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include module documentation if api directory exists","status":"passed","title":"should include module documentation if api directory exists","duration":0.41329399999995076,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include script documentation if api directory exists","status":"passed","title":"should include script documentation if api directory exists","duration":0.3930960000000141,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Generated Documentation (docs/) Coverage"],"fullName":"Sitemap Generation Generated Documentation (docs/) Coverage should include docs index page if docs directory exists","status":"passed","title":"should include docs index page if docs directory exists","duration":5.182753000000048,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Generated Documentation (docs/) Coverage"],"fullName":"Sitemap Generation Generated Documentation (docs/) Coverage should include docs documentation files if docs directory exists","status":"passed","title":"should include docs documentation files if docs directory exists","duration":2.903756000000044,"failureMessages":[],"location":{"line":205,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Sitemap HTML Pages Coverage"],"fullName":"Sitemap Generation Sitemap HTML Pages Coverage should include sitemap HTML pages","status":"passed","title":"should include sitemap HTML pages","duration":0.40681100000006154,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Sitemap HTML Pages Coverage"],"fullName":"Sitemap Generation Sitemap HTML Pages Coverage should include sitemap pages for multiple languages","status":"passed","title":"should include sitemap pages for multiple languages","duration":0.5757380000000012,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have proper lastmod dates","status":"passed","title":"should have proper lastmod dates","duration":5.714959000000022,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have changefreq values","status":"passed","title":"should have changefreq values","duration":5.393697999999972,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have priority values","status":"passed","title":"should have priority values","duration":5.358011000000033,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should use proper base URL","status":"passed","title":"should use proper base URL","duration":113.28882699999997,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should not have duplicate URLs","status":"passed","title":"should not have duplicate URLs","duration":13.926934000000074,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","File Size and Performance"],"fullName":"Sitemap Generation File Size and Performance should be under 50MB (sitemap limit)","status":"passed","title":"should be under 50MB (sitemap limit)","duration":2.1938969999999927,"failureMessages":[],"location":{"line":269,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","File Size and Performance"],"fullName":"Sitemap Generation File Size and Performance should have less than 50,000 URLs (sitemap limit)","status":"passed","title":"should have less than 50,000 URLs (sitemap limit)","duration":2.9178929999999355,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates for the main index page covering all 14 languages","status":"passed","title":"should have hreflang alternates for the main index page covering all 14 languages","duration":1.115589,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have individual entries for all 14 language index pages","status":"passed","title":"should have individual entries for all 14 language index pages","duration":0.6437550000000556,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have entries for all 14 dashboard language pages","status":"passed","title":"should have entries for all 14 dashboard language pages","duration":0.8351529999999912,"failureMessages":[],"location":{"line":310,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have sitemap HTML pages for all 14 languages","status":"passed","title":"should have sitemap HTML pages for all 14 languages","duration":0.6848329999999123,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates on sitemap HTML pages","status":"passed","title":"should have hreflang alternates on sitemap HTML pages","duration":0.5077509999999847,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have news articles with matching hreflang alternates for every language variant","status":"passed","title":"should have news articles with matching hreflang alternates for every language variant","duration":7.933652999999936,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have news index pages for available languages","status":"passed","title":"should have news index pages for available languages","duration":0.5746350000000575,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates in news index entry","status":"passed","title":"should have hreflang alternates in news index entry","duration":0.49148999999999887,"failureMessages":[],"location":{"line":402,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should include politician dashboard","status":"passed","title":"should include politician dashboard","duration":0.45724600000005466,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have x-default hreflang pointing to English for main pages","status":"passed","title":"should have x-default hreflang pointing to English for main pages","duration":0.5635950000000776,"failureMessages":[],"location":{"line":419,"column":5},"meta":{},"tags":[]}],"startTime":1787953682133,"endTime":1787953682366.5635,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-generation.test.ts"},{"assertionResults":[{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml escapes the five HTML metacharacters","status":"passed","title":"escapes the five HTML metacharacters","duration":3.7297739999999635,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml preserves valid pre-encoded entities (named, numeric, hex)","status":"passed","title":"preserves valid pre-encoded entities (named, numeric, hex)","duration":0.5123890000000415,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml escapes a stray ampersand in slogans like \"R&D\"","status":"passed","title":"escapes a stray ampersand in slogans like \"R&D\"","duration":0.46937900000000354,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml uses HTML-canonical ' for apostrophes (NOT XML ')","status":"passed","title":"uses HTML-canonical ' for apostrophes (NOT XML ')","duration":0.37441100000000915,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":0.7768250000000307,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the en entry has a non-empty native name and flag","status":"passed","title":"the en entry has a non-empty native name and flag","duration":0.5472239999999715,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the sv entry has a non-empty native name and flag","status":"passed","title":"the sv entry has a non-empty native name and flag","duration":0.539289999999994,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the da entry has a non-empty native name and flag","status":"passed","title":"the da entry has a non-empty native name and flag","duration":0.31244499999996833,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the no entry has a non-empty native name and flag","status":"passed","title":"the no entry has a non-empty native name and flag","duration":0.4460849999999823,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the fi entry has a non-empty native name and flag","status":"passed","title":"the fi entry has a non-empty native name and flag","duration":0.4124219999999923,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the de entry has a non-empty native name and flag","status":"passed","title":"the de entry has a non-empty native name and flag","duration":0.36506400000001804,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the fr entry has a non-empty native name and flag","status":"passed","title":"the fr entry has a non-empty native name and flag","duration":0.3303280000000086,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the es entry has a non-empty native name and flag","status":"passed","title":"the es entry has a non-empty native name and flag","duration":0.2906939999999736,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the nl entry has a non-empty native name and flag","status":"passed","title":"the nl entry has a non-empty native name and flag","duration":0.35570599999999786,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ar entry has a non-empty native name and flag","status":"passed","title":"the ar entry has a non-empty native name and flag","duration":0.40788300000002664,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the he entry has a non-empty native name and flag","status":"passed","title":"the he entry has a non-empty native name and flag","duration":0.31885699999997996,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ja entry has a non-empty native name and flag","status":"passed","title":"the ja entry has a non-empty native name and flag","duration":0.30434999999999945,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ko entry has a non-empty native name and flag","status":"passed","title":"the ko entry has a non-empty native name and flag","duration":0.3360500000000002,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the zh entry has a non-empty native name and flag","status":"passed","title":"the zh entry has a non-empty native name and flag","duration":0.30708500000002914,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META uses BCP-47 hreflang `nb` for the `no` entry (Norwegian Bokmål)","status":"passed","title":"uses BCP-47 hreflang `nb` for the `no` entry (Norwegian Bokmål)","duration":0.3463979999999651,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META uses RTL direction for Arabic and Hebrew, LTR for everything else","status":"passed","title":"uses RTL direction for Arabic and Hebrew, LTR for everything else","duration":0.6473119999999994,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META every entry exposes the translations bundle used by the renderer","status":"passed","title":"every entry exposes the translations bundle used by the renderer","duration":1.576010999999994,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]}],"startTime":1787953914847,"endTime":1787953914861.576,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-html-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode maps the legacy `no` file-suffix to BCP-47 `nb` (Norwegian Bokmål)","status":"passed","title":"maps the legacy `no` file-suffix to BCP-47 `nb` (Norwegian Bokmål)","duration":4.48357500000003,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes en through unchanged","status":"passed","title":"passes en through unchanged","duration":0.671196000000009,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes sv through unchanged","status":"passed","title":"passes sv through unchanged","duration":0.49871400000000676,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes da through unchanged","status":"passed","title":"passes da through unchanged","duration":0.363851000000011,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes fi through unchanged","status":"passed","title":"passes fi through unchanged","duration":0.4687279999999987,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes de through unchanged","status":"passed","title":"passes de through unchanged","duration":0.4496819999999957,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes fr through unchanged","status":"passed","title":"passes fr through unchanged","duration":0.46205500000002075,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes es through unchanged","status":"passed","title":"passes es through unchanged","duration":0.3291760000000181,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes nl through unchanged","status":"passed","title":"passes nl through unchanged","duration":0.3112930000000347,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ar through unchanged","status":"passed","title":"passes ar through unchanged","duration":0.2870980000000145,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes he through unchanged","status":"passed","title":"passes he through unchanged","duration":0.5403419999999528,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ja through unchanged","status":"passed","title":"passes ja through unchanged","duration":0.2847239999999829,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ko through unchanged","status":"passed","title":"passes ko through unchanged","duration":0.29939999999999145,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes zh through unchanged","status":"passed","title":"passes zh through unchanged","duration":0.35919300000000476,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes unknown codes through unchanged (does not throw on unexpected input)","status":"passed","title":"passes unknown codes through unchanged (does not throw on unexpected input)","duration":0.36655700000000024,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry emits a minimal `<url>` block without alternates","status":"passed","title":"emits a minimal `<url>` block without alternates","duration":0.8529369999999972,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry emits one `<xhtml:link rel=\"alternate\">` per alternate, normalising `no` → `nb`","status":"passed","title":"emits one `<xhtml:link rel=\"alternate\">` per alternate, normalising `no` → `nb`","duration":0.6712770000000319,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry always prefixes the canonical absolute base URL","status":"passed","title":"always prefixes the canonical absolute base URL","duration":0.4659520000000157,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/scanners/api.ts — getApiDocs"],"fullName":"sitemap-xml/scanners/api.ts — getApiDocs returns an empty array when the API directory does not exist","status":"passed","title":"returns an empty array when the API directory does not exist","duration":3.931701999999973,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/scanners/api.ts — getApiDocs"],"fullName":"sitemap-xml/scanners/api.ts — getApiDocs scans a mocked directory tree and returns ApiDoc entries","status":"passed","title":"scans a mocked directory tree and returns ApiDoc entries","duration":60.618682999999976,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap returns true on a valid sitemap","status":"passed","title":"returns true on a valid sitemap","duration":0.9285589999999502,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws on missing XML declaration","status":"passed","title":"throws on missing XML declaration","duration":1.5680259999999748,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws on missing or wrong sitemap namespace","status":"passed","title":"throws on missing or wrong sitemap namespace","duration":0.6490949999999884,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws when there are zero URL entries","status":"passed","title":"throws when there are zero URL entries","duration":0.6509990000000698,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws when `<url>` blocks lack `<loc>` tags","status":"passed","title":"throws when `<url>` blocks lack `<loc>` tags","duration":0.5917180000000144,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]}],"startTime":1787953854899,"endTime":1787953854980.651,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-xml-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=home)","status":"passed","title":"returns a 7-token native keyword string for every language (family=home)","duration":4.256792000000019,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=dashboard)","status":"passed","title":"returns a 7-token native keyword string for every language (family=dashboard)","duration":0.9827300000000037,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=politician)","status":"passed","title":"returns a 7-token native keyword string for every language (family=politician)","duration":0.5502900000000182,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns DISTINCT keyword strings across languages for the same family","status":"passed","title":"returns DISTINCT keyword strings across languages for the same family","duration":0.5195529999999735,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix keeps the platform brand \"Riksdagsmonitor\" in every home-family entry (proper noun)","status":"passed","title":"keeps the platform brand \"Riksdagsmonitor\" in every home-family entry (proper noun)","duration":0.799165999999957,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix keeps the acronym \"OSINT\" in every home-family entry (international term)","status":"passed","title":"keeps the acronym \"OSINT\" in every home-family entry (international term)","duration":0.5799759999999878,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for German (no English leakage)","status":"passed","title":"uses native vocabulary for German (no English leakage)","duration":1.152058000000011,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for Arabic (no English leakage; RTL script)","status":"passed","title":"uses native vocabulary for Arabic (no English leakage; RTL script)","duration":0.4135350000000244,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for Japanese (CJK script)","status":"passed","title":"uses native vocabulary for Japanese (CJK script)","duration":0.5751260000000116,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock emits one og:locale for the page and 13 og:locale:alternate siblings","status":"passed","title":"emits one og:locale for the page and 13 og:locale:alternate siblings","duration":0.40401699999995344,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock uses the canonical territory code for each language","status":"passed","title":"uses the canonical territory code for each language","duration":0.6791719999999941,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock uses nb_NO for Norwegian (BCP-47 convention)","status":"passed","title":"uses nb_NO for Norwegian (BCP-47 convention)","duration":0.4674449999999979,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageTwitterCardBlock"],"fullName":"buildStaticPageTwitterCardBlock emits a complete summary_large_image Twitter Card","status":"passed","title":"emits a complete summary_large_image Twitter Card","duration":0.5548789999999713,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageTwitterCardBlock"],"fullName":"buildStaticPageTwitterCardBlock HTML-escapes special characters in title / description","status":"passed","title":"HTML-escapes special characters in title / description","duration":0.6309510000000387,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a WebSite + Organization + WebPage graph with Speakable for h1","status":"passed","title":"emits a WebSite + Organization + WebPage graph with Speakable for h1","duration":1.9022619999999506,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd uses `nb` for Norwegian inLanguage (BCP-47)","status":"passed","title":"uses `nb` for Norwegian inLanguage (BCP-47)","duration":0.5418439999999691,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a BreadcrumbList node with two items for dashboard / politician families","status":"passed","title":"emits a BreadcrumbList node with two items for dashboard / politician families","duration":1.2216980000000035,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a single-item BreadcrumbList for the home family (EN home URL)","status":"passed","title":"emits a single-item BreadcrumbList for the home family (EN home URL)","duration":0.7923540000000457,"failureMessages":[],"location":{"line":259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd localises BreadcrumbList Home label per language (ar / ja / zh)","status":"passed","title":"localises BreadcrumbList Home label per language (ar / ja / zh)","duration":0.8774540000000002,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) replaces the EN keyword string with native German keywords","status":"passed","title":"replaces the EN keyword string with native German keywords","duration":0.5407030000000077,"failureMessages":[],"location":{"line":306,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits a full og:locale matrix (de_DE primary, 13 alternates)","status":"passed","title":"emits a full og:locale matrix (de_DE primary, 13 alternates)","duration":0.6006249999999795,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) adds the Twitter Card block (was missing on politician-dashboard*)","status":"passed","title":"adds the Twitter Card block (was missing on politician-dashboard*)","duration":0.5157959999999662,"failureMessages":[],"location":{"line":320,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) adds the JSON-LD WebSite + WebPage + Speakable block","status":"passed","title":"adds the JSON-LD WebSite + WebPage + Speakable block","duration":0.6122169999999869,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) preserves the original <title> and <meta name=\"description\"> verbatim","status":"passed","title":"preserves the original <title> and <meta name=\"description\"> verbatim","duration":0.49836399999998093,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) is idempotent — running twice yields the same output as once","status":"passed","title":"is idempotent — running twice yields the same output as once","duration":0.6616290000000049,"failureMessages":[],"location":{"line":339,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly one <meta name=\"keywords\"> tag (no duplication on re-run)","status":"passed","title":"emits exactly one <meta name=\"keywords\"> tag (no duplication on re-run)","duration":0.6043220000000247,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly one og:locale primary tag","status":"passed","title":"emits exactly one og:locale primary tag","duration":0.648144000000002,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly 13 og:locale:alternate tags","status":"passed","title":"emits exactly 13 og:locale:alternate tags","duration":0.5877510000000257,"failureMessages":[],"location":{"line":363,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=home)","status":"passed","title":"rewrites keywords for every language (family=home)","duration":3.5181479999999965,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=dashboard)","status":"passed","title":"rewrites keywords for every language (family=dashboard)","duration":2.501564999999971,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=politician)","status":"passed","title":"rewrites keywords for every language (family=politician)","duration":2.2649810000000343,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]}],"startTime":1787953783499,"endTime":1787953783531.265,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/static-pages-seo.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret link discovery"],"fullName":"Statskontoret link discovery extracts Excel and CSV ZIP GetFile links with provenance parameters","status":"passed","title":"extracts Excel and CSV ZIP GetFile links with provenance parameters","duration":7.917693999999983,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret workbook parsing"],"fullName":"Statskontoret workbook parsing parses XLSX rows and builds department headcount time series","status":"passed","title":"parses XLSX rows and builds department headcount time series","duration":20.54657700000007,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret workbook parsing"],"fullName":"Statskontoret workbook parsing aggregates records with Swedish decimal comma values","status":"passed","title":"aggregates records with Swedish decimal comma values","duration":0.8426069999999299,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CSV ZIP parsing"],"fullName":"Statskontoret CSV ZIP parsing extracts CSV files from ZIP archives","status":"passed","title":"extracts CSV files from ZIP archives","duration":1.7137380000000348,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient uses injected fetch for source discovery","status":"passed","title":"uses injected fetch for source discovery","duration":1.8229230000000598,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient allows custom HTTPS baseURL hosts through the fetch guard","status":"passed","title":"allows custom HTTPS baseURL hosts through the fetch guard","duration":1.5462440000000015,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient wraps network failures in typed http errors with the original cause","status":"passed","title":"wraps network failures in typed http errors with the original cause","duration":1.05126800000005,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient densifies sparse worksheet rows so column alignment is preserved","status":"passed","title":"densifies sparse worksheet rows so column alignment is preserved","duration":2.751822000000061,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses annual income outturn records (årsutfall Inkomst)","status":"passed","title":"parses annual income outturn records (årsutfall Inkomst)","duration":1.2740250000000515,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses annual expenditure outturn records (årsutfall Utgift)","status":"passed","title":"parses annual expenditure outturn records (årsutfall Utgift)","duration":0.6657559999999876,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses monthly outturn records (månadsutfall) with month column","status":"passed","title":"parses monthly outturn records (månadsutfall) with month column","duration":0.6251300000000128,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows uses fallback year when the record has no year column","status":"passed","title":"uses fallback year when the record has no year column","duration":0.5767590000000382,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows skips records missing an outturn value","status":"passed","title":"skips records missing an outturn value","duration":0.6195490000000063,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows normalises Swedish decimal commas","status":"passed","title":"normalises Swedish decimal commas","duration":0.6994489999999587,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries derives documentType from sheet name and parses all sheets","status":"passed","title":"derives documentType from sheet name and parses all sheets","duration":5.325068999999985,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries sorts output by year then month then documentType","status":"passed","title":"sorts output by year then month then documentType","duration":0.8023520000000417,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries forces documentType when options.documentType overrides sheet-name inference","status":"passed","title":"forces documentType when options.documentType overrides sheet-name inference","duration":0.4501030000000128,"failureMessages":[],"location":{"line":303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn aggregates rows into per-year/documentType totals with variance","status":"passed","title":"aggregates rows into per-year/documentType totals with variance","duration":0.9362320000000182,"failureMessages":[],"location":{"line":313,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn omits totalBudget and variance when any row lacks a budget value","status":"passed","title":"omits totalBudget and variance when any row lacks a budget value","duration":0.5570920000000115,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn returns results sorted by year then documentType","status":"passed","title":"returns results sorted by year then documentType","duration":0.5669619999999895,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn returns empty array for empty input","status":"passed","title":"returns empty array for empty input","duration":0.4891660000000684,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource returns the source definition for a valid key","status":"passed","title":"returns the source definition for a valid key","duration":0.44822899999996935,"failureMessages":[],"location":{"line":361,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource throws a typed StatskontoretError for an unknown key","status":"passed","title":"throws a typed StatskontoretError for an unknown key","duration":0.6976360000001023,"failureMessages":[],"location":{"line":367,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource exposes StatskontoretError.kind on thrown errors","status":"passed","title":"exposes StatskontoretError.kind on thrown errors","duration":0.42800099999999475,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options uses sheetNamePattern to pick the correct sheet","status":"passed","title":"uses sheetNamePattern to pick the correct sheet","duration":2.2859700000000203,"failureMessages":[],"location":{"line":384,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options returns empty array when sheetNamePattern matches no sheet","status":"passed","title":"returns empty array when sheetNamePattern matches no sheet","duration":1.709840999999983,"failureMessages":[],"location":{"line":390,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options returns empty array when workbook has no sheets","status":"passed","title":"returns empty array when workbook has no sheets","duration":0.48642099999995025,"failureMessages":[],"location":{"line":396,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options uses explicit headerRowIndex to skip auto-detection","status":"passed","title":"uses explicit headerRowIndex to skip auto-detection","duration":0.5207349999999451,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options returns empty array when rows are empty","status":"passed","title":"returns empty array when rows are empty","duration":0.442297999999937,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options uses fallback column names for blank headers","status":"passed","title":"uses fallback column names for blank headers","duration":0.44932200000005196,"failureMessages":[],"location":{"line":417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows additional paths"],"fullName":"parseBudgetRows additional paths uses fallbackMonth when the record has no month column","status":"passed","title":"uses fallbackMonth when the record has no month column","duration":0.5242620000000215,"failureMessages":[],"location":{"line":426,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows additional paths"],"fullName":"parseBudgetRows additional paths skips records with no year and no fallbackYear","status":"passed","title":"skips records with no year and no fallbackYear","duration":0.5558510000000751,"failureMessages":[],"location":{"line":432,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractStatskontoretDownloadLinks deduplication"],"fullName":"extractStatskontoretDownloadLinks deduplication deduplicates links with identical resolved URLs","status":"passed","title":"deduplicates links with identical resolved URLs","duration":0.5874500000001035,"failureMessages":[],"location":{"line":439,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractStatskontoretDownloadLinks deduplication"],"fullName":"extractStatskontoretDownloadLinks deduplication keeps links with different query parameters","status":"passed","title":"keeps links with different query parameters","duration":0.6656769999999597,"failureMessages":[],"location":{"line":449,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient HTTP error path"],"fullName":"StatskontoretClient HTTP error path throws a typed http error when the server returns a non-OK response","status":"passed","title":"throws a typed http error when the server returns a non-OK response","duration":1.137599000000023,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]}],"startTime":1787953675496,"endTime":1787953675560.1377,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-client.test.ts"},{"assertionResults":[{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json declares source as Statskontoret with Public classification","status":"passed","title":"declares source as Statskontoret with Public classification","duration":3.924088999999981,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json specifies a 30-day cache TTL","status":"passed","title":"specifies a 30-day cache TTL","duration":0.5349319999999693,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json contains at least one entry","status":"passed","title":"contains at least one entry","duration":0.5976499999999874,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json each entry has required fields with valid formats","status":"passed","title":"each entry has required fields with valid formats","duration":1.8881259999999997,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json covers known high-priority agencies","status":"passed","title":"covers known high-priority agencies","duration":0.6140399999999886,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json entries with named agencies target recognised Swedish authorities","status":"passed","title":"entries with named agencies target recognised Swedish authorities","duration":0.6057240000000093,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md includes a Statskontoret relevance field in the Feasibility Context table","status":"passed","title":"includes a Statskontoret relevance field in the Feasibility Context table","duration":0.7092489999999998,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md includes a Statskontoret overlay instruction in the Administrative section","status":"passed","title":"includes a Statskontoret overlay instruction in the Administrative section","duration":0.465191999999945,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md references statskontoret in at least one evidence guidance note","status":"passed","title":"references statskontoret in at least one evidence guidance note","duration":0.7464979999999741,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n returns null when flag is absent","status":"passed","title":"returns null when flag is absent","duration":1.0717970000000037,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses integer value correctly","status":"passed","title":"parses integer value correctly","duration":0.6760869999999954,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses 0 (graceful-degradation: disable enrichment)","status":"passed","title":"parses 0 (graceful-degradation: disable enrichment)","duration":0.41529800000000705,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses larger values","status":"passed","title":"parses larger values","duration":0.47983899999996993,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for non-integer float value","status":"passed","title":"throws for non-integer float value","duration":1.3396589999999833,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for negative value","status":"passed","title":"throws for negative value","duration":0.594664000000023,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for non-numeric string","status":"passed","title":"throws for non-numeric string","duration":0.5206150000000207,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n does not affect other parsed fields","status":"passed","title":"does not affect other parsed fields","duration":0.5514329999999745,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses --full-text-for-all as an explicit override","status":"passed","title":"parses --full-text-for-all as an explicit override","duration":0.41093000000000757,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["graceful degradation: --auto-full-text-top-n=0"],"fullName":"graceful degradation: --auto-full-text-top-n=0 parseArgs returns autoFullTextTopN=0 which maps to enrichLimit=0 (no enrichment)","status":"passed","title":"parseArgs returns autoFullTextTopN=0 which maps to enrichLimit=0 (no enrichment)","duration":0.4749289999999746,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["graceful degradation: --auto-full-text-top-n=0"],"fullName":"graceful degradation: --auto-full-text-top-n=0 default (no flag) leaves autoFullTextTopN null, meaning downloadAllDocuments uses MAX_ENRICHMENT_PER_TYPE","status":"passed","title":"default (no flag) leaves autoFullTextTopN null, meaning downloadAllDocuments uses MAX_ENRICHMENT_PER_TYPE","duration":0.41267299999998386,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]}],"startTime":1787953847750,"endTime":1787953847767.4126,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-enrichment-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory has myndighetsforteckning dataset for government-body coverage","status":"passed","title":"inventory has myndighetsforteckning dataset for government-body coverage","duration":3.767304000000024,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract myndighetsforteckning is classified A1 (highest data quality)","status":"passed","title":"myndighetsforteckning is classified A1 (highest data quality)","duration":0.6583430000000021,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract at least one implementation-feasibility.md file in the analysis tree mentions a known Swedish agency (otherwise the per-file coverage test is vacuous)","status":"passed","title":"at least one implementation-feasibility.md file in the analysis tree mentions a known Swedish agency (otherwise the per-file coverage test is vacuous)","duration":5.942907999999932,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract every implementation-feasibility.md mentioning a known agency resolves to a Statskontoret dataset that covers it via myndighetsforteckning","status":"passed","title":"every implementation-feasibility.md mentioning a known agency resolves to a Statskontoret dataset that covers it via myndighetsforteckning","duration":7.16565700000001,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory globally covers FiU and KU committees in at least one Statskontoret dataset","status":"passed","title":"inventory globally covers FiU and KU committees in at least one Statskontoret dataset","duration":0.5790840000000799,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory providerDecisionMatrix maps governmentBodiesHeadcount to statskontoret","status":"passed","title":"inventory providerDecisionMatrix maps governmentBodiesHeadcount to statskontoret","duration":0.611964999999941,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract found at least one implementation-feasibility.md file in the analysis tree","status":"passed","title":"found at least one implementation-feasibility.md file in the analysis tree","duration":0.486391000000026,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract exports CACHE_TTL_MS equal to 30 days","status":"passed","title":"exports CACHE_TTL_MS equal to 30 days","duration":0.4948060000000396,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract statskontoretSourceKeys() returns all built-in source keys","status":"passed","title":"statskontoretSourceKeys() returns all built-in source keys","duration":1.4008230000000594,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns false when no cache file exists","status":"passed","title":"isStatskontoretCacheFresh returns false when no cache file exists","duration":0.9672809999999572,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns true when a fresh cache file exists","status":"passed","title":"isStatskontoretCacheFresh returns true when a fresh cache file exists","duration":1.145954999999958,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns false when cache entry is older than TTL","status":"passed","title":"isStatskontoretCacheFresh returns false when cache entry is older than TTL","duration":0.669563999999923,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached returns cached payload from disk without network call","status":"passed","title":"fetchStatskontoretCached returns cached payload from disk without network call","duration":1.3181879999999637,"failureMessages":[],"location":{"line":262,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached falls back to stale cache on network error","status":"passed","title":"fetchStatskontoretCached falls back to stale cache on network error","duration":1.6590569999999616,"failureMessages":[],"location":{"line":301,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached throws StatskontoretError when network fails and no cache exists","status":"passed","title":"fetchStatskontoretCached throws StatskontoretError when network fails and no cache exists","duration":2.177077000000054,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]}],"startTime":1787953792682,"endTime":1787953792712.177,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-feasibility-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing parses flags and boolean options without executing the CLI","status":"passed","title":"parses flags and boolean options without executing the CLI","duration":4.211945999999955,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing throws typed CLI errors for invalid input","status":"passed","title":"throws typed CLI errors for invalid input","duration":1.8443439999999782,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing accepts built-in source keys","status":"passed","title":"accepts built-in source keys","duration":0.5370259999999689,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret parsing primitives"],"fullName":"Statskontoret parsing primitives classifies common downloadable resources","status":"passed","title":"classifies common downloadable resources","duration":0.9440179999999714,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret parsing primitives"],"fullName":"Statskontoret parsing primitives normalises Swedish numeric and integer values defensively","status":"passed","title":"normalises Swedish numeric and integer values defensively","duration":0.8765909999999622,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard accepts the allowlisted Statskontoret HTTPS host","status":"passed","title":"accepts the allowlisted Statskontoret HTTPS host","duration":0.8920199999999454,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects non-HTTPS schemes","status":"passed","title":"rejects non-HTTPS schemes","duration":0.5927099999999541,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects hosts outside the allowlist","status":"passed","title":"rejects hosts outside the allowlist","duration":0.5602289999999925,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects malformed URLs with a typed error","status":"passed","title":"rejects malformed URLs with a typed error","duration":0.8812800000000038,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard blocks fetchText calls that target other hosts","status":"passed","title":"blocks fetchText calls that target other hosts","duration":2.101654999999994,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses budget-outturn command with required flags","status":"passed","title":"parses budget-outturn command with required flags","duration":0.6012359999999717,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses optional --doc-type flag","status":"passed","title":"parses optional --doc-type flag","duration":0.4701400000000149,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses --persist boolean alongside budget-outturn","status":"passed","title":"parses --persist boolean alongside budget-outturn","duration":0.4401540000000068,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn source guard"],"fullName":"Statskontoret CLI budget-outturn source guard rejects myndighetsforteckning as a source for budget-outturn","status":"passed","title":"rejects myndighetsforteckning as a source for budget-outturn","duration":0.4610630000000242,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]}],"startTime":1787953891845,"endTime":1787953891861.4612,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json identifies Statskontoret as the public source","status":"passed","title":"identifies Statskontoret as the public source","duration":3.865848000000028,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json covers every built-in TypeScript source definition","status":"passed","title":"covers every built-in TypeScript source definition","duration":0.8597589999999968,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json declares key provider-decision routes","status":"passed","title":"declares key provider-decision routes","duration":0.435937000000024,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json documents the client, CLI, cachedFetch and persistence surfaces","status":"passed","title":"documents the client, CLI, cachedFetch and persistence surfaces","duration":0.6711770000000001,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953923427,"endTime":1787953923432.6711,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-inventory.test.ts"},{"assertionResults":[{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd produces a BreadcrumbList with correct positions and structure","status":"passed","title":"produces a BreadcrumbList with correct positions and structure","duration":6.747594000000049,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd handles a single entry","status":"passed","title":"handles a single entry","duration":0.650047000000086,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd throws when an intermediate entry is missing `item`","status":"passed","title":"throws when an intermediate entry is missing `item`","duration":1.1479290000000901,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd throws when entries array is empty","status":"passed","title":"throws when entries array is empty","duration":0.585456000000022,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildNewsArticleLd"],"fullName":"jsonld — buildNewsArticleLd produces a NewsArticle with all required fields","status":"passed","title":"produces a NewsArticle with all required fields","duration":1.2018699999999853,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildNewsArticleLd"],"fullName":"jsonld — buildNewsArticleLd omits isBasedOn when no artifacts are provided","status":"passed","title":"omits isBasedOn when no artifacts are provided","duration":0.5762690000000248,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd produces a WebPage with SpeakableSpecification","status":"passed","title":"produces a WebPage with SpeakableSpecification","duration":0.9441280000000916,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd throws when cssSelectors is empty","status":"passed","title":"throws when cssSelectors is empty","duration":0.4736359999999422,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd throws when all selectors are blank","status":"passed","title":"throws when all selectors are blank","duration":0.6945709999999963,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd filters out blank selectors while keeping valid ones","status":"passed","title":"filters out blank selectors while keeping valid ones","duration":0.44130599999994047,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits NewsArticle JSON-LD","status":"passed","title":"emits NewsArticle JSON-LD","duration":48.59561000000008,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits BreadcrumbList JSON-LD","status":"passed","title":"emits BreadcrumbList JSON-LD","duration":3.7306449999999813,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits SpeakableSpecification JSON-LD via WebPage","status":"passed","title":"emits SpeakableSpecification JSON-LD via WebPage","duration":3.4218779999999924,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits correct hreflang set including x-default","status":"passed","title":"emits correct hreflang set including x-default","duration":3.352245999999923,"failureMessages":[],"location":{"line":275,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits Open Graph and Twitter Card meta tags","status":"passed","title":"emits Open Graph and Twitter Card meta tags","duration":3.226590999999985,"failureMessages":[],"location":{"line":293,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits correct lang attribute and dir for Arabic RTL","status":"passed","title":"emits correct lang attribute and dir for Arabic RTL","duration":3.5914450000000215,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration uses BCP-47 nb for Norwegian hreflang","status":"passed","title":"uses BCP-47 nb for Norwegian hreflang","duration":2.701738999999975,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration truncates BreadcrumbList title with ellipsis when longer than limit","status":"passed","title":"truncates BreadcrumbList title with ellipsis when longer than limit","duration":3.1824589999999944,"failureMessages":[],"location":{"line":340,"column":3},"meta":{},"tags":[]}],"startTime":1787953794244,"endTime":1787953794329.1824,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/structured-data.test.ts"},{"assertionResults":[{"ancestorTitles":["AGENCY_ACRONYM_MAP"],"fullName":"AGENCY_ACRONYM_MAP contains every high-frequency Swedish agency","status":"passed","title":"contains every high-frequency Swedish agency","duration":4.270305999999948,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["AGENCY_ACRONYM_MAP"],"fullName":"AGENCY_ACRONYM_MAP uses non-empty acronyms with sensible length","status":"passed","title":"uses non-empty acronyms with sensible length","duration":1.7050319999999601,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms emits the acronym when the full name is mentioned","status":"passed","title":"emits the acronym when the full name is mentioned","duration":1.1578379999999697,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms emits the full name when the acronym is mentioned","status":"passed","title":"emits the full name when the acronym is mentioned","duration":0.4632880000000341,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms skips unknown agencies","status":"passed","title":"skips unknown agencies","duration":0.4598609999999894,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms does not duplicate when both forms are already in input","status":"passed","title":"does not duplicate when both forms are already in input","duration":0.46288700000002336,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms preserves order of input entities","status":"passed","title":"preserves order of input entities","duration":0.5172279999999887,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms is case-insensitive on the lookup key","status":"passed","title":"is case-insensitive on the lookup key","duration":0.3780179999999973,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["COMMITTEE_DOMAIN_MAP"],"fullName":"COMMITTEE_DOMAIN_MAP covers every Riksdag committee code","status":"passed","title":"covers every Riksdag committee code","duration":0.8980210000000284,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["COMMITTEE_DOMAIN_MAP"],"fullName":"COMMITTEE_DOMAIN_MAP emits a localized lemma in every supported language","status":"passed","title":"emits a localized lemma in every supported language","duration":0.6410100000000511,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the English domain word for JuU when lang=en","status":"passed","title":"emits the English domain word for JuU when lang=en","duration":0.5823399999999879,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the Swedish lemma when lang=sv","status":"passed","title":"emits the Swedish lemma when lang=sv","duration":0.4074929999999881,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the Japanese lemma for FiU when lang=ja","status":"passed","title":"emits the Japanese lemma for FiU when lang=ja","duration":0.4065909999999917,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains de-duplicates when the same code appears twice","status":"passed","title":"de-duplicates when the same code appears twice","duration":0.36505299999998897,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains preserves input order across distinct codes","status":"passed","title":"preserves input order across distinct codes","duration":0.36760800000001836,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains silently skips unknown committee codes","status":"passed","title":"silently skips unknown committee codes","duration":0.45706599999999753,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]}],"startTime":1787953904411,"endTime":1787953904425.457,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sv-keyword-mappings.test.ts"},{"assertionResults":[{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization exposes labels for every supported site language","status":"passed","title":"exposes labels for every supported site language","duration":5.809728000000007,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization returns Swedish labels for `sv` (case-insensitive)","status":"passed","title":"returns Swedish labels for `sv` (case-insensitive)","duration":0.7486020000000053,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization returns Arabic labels including a non-empty dismiss aria-label","status":"passed","title":"returns Arabic labels including a non-empty dismiss aria-label","duration":0.43017500000001974,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization matches on the BCP-47 primary subtag (e.g. `en-GB` → en, `zh-Hans` → zh)","status":"passed","title":"matches on the BCP-47 primary subtag (e.g. `en-GB` → en, `zh-Hans` → zh)","duration":0.37430100000000266,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization falls back to English for unsupported languages and empty input","status":"passed","title":"falls back to English for unsupported languages and empty input","duration":0.5572940000000131,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]}],"startTime":1787953918491,"endTime":1787953918499.5574,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sw-update-toast-labels.test.ts"},{"assertionResults":[{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) exports a non-empty inline string","status":"passed","title":"exports a non-empty inline string","duration":3.8461110000000076,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) wraps the inline script in a <script> tag","status":"passed","title":"wraps the inline script in a <script> tag","duration":0.770702999999969,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output uses the same storage key as the canonical source","status":"passed","title":"minified output uses the same storage key as the canonical source","duration":0.48280399999998735,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output preserves all semantic tokens from the canonical source","status":"passed","title":"minified output preserves all semantic tokens from the canonical source","duration":0.5118679999999927,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output is syntactically valid JavaScript (IIFE executes)","status":"passed","title":"minified output is syntactically valid JavaScript (IIFE executes)","duration":1.465533999999991,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output is substantially smaller than the canonical source","status":"passed","title":"minified output is substantially smaller than the canonical source","duration":0.489736999999991,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]}],"startTime":1787953912224,"endTime":1787953912231.4897,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/theme-init-ssot.test.ts"},{"assertionResults":[{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns stored \"dark\" from localStorage (overrides light system pref)","status":"passed","title":"returns stored \"dark\" from localStorage (overrides light system pref)","duration":4.626511999999991,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns stored \"light\" from localStorage (overrides dark system pref)","status":"passed","title":"returns stored \"light\" from localStorage (overrides dark system pref)","duration":0.8225699999999847,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() ignores an invalid stored value and uses system preference (dark)","status":"passed","title":"ignores an invalid stored value and uses system preference (dark)","duration":0.8677840000000288,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() ignores an invalid stored value and uses system preference (light)","status":"passed","title":"ignores an invalid stored value and uses system preference (light)","duration":0.6724790000000098,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"dark\" from system preference when localStorage is empty","status":"passed","title":"returns \"dark\" from system preference when localStorage is empty","duration":0.7886970000000133,"failureMessages":[],"location":{"line":128,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"light\" from system preference when localStorage is empty","status":"passed","title":"returns \"light\" from system preference when localStorage is empty","duration":0.6561990000000151,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"light\" when matchMedia is unavailable and no stored value","status":"passed","title":"returns \"light\" when matchMedia is unavailable and no stored value","duration":0.5213360000000193,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() sets data-theme=\"dark\" on <html>","status":"passed","title":"sets data-theme=\"dark\" on <html>","duration":1.66353399999997,"failureMessages":[],"location":{"line":146,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() sets data-theme=\"light\" on <html>","status":"passed","title":"sets data-theme=\"light\" on <html>","duration":0.8865900000000124,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() persists to localStorage when persist flag is true","status":"passed","title":"persists to localStorage when persist flag is true","duration":0.8888940000000503,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() does not persist to localStorage when persist flag is false","status":"passed","title":"does not persist to localStorage when persist flag is false","duration":0.5867380000000253,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() persists by default when persist is omitted","status":"passed","title":"persists by default when persist is omitted","duration":0.5782820000000015,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-pressed=\"true\" for dark theme","status":"passed","title":"sets aria-pressed=\"true\" for dark theme","duration":4.988989999999944,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-pressed=\"false\" for light theme","status":"passed","title":"sets aria-pressed=\"false\" for light theme","duration":1.1143160000000307,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-label to data-label-dark value when theme is dark","status":"passed","title":"sets aria-label to data-label-dark value when theme is dark","duration":0.9133400000000051,"failureMessages":[],"location":{"line":187,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-label to data-label-light value when theme is light","status":"passed","title":"sets aria-label to data-label-light value when theme is light","duration":0.9019589999999766,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets title to match aria-label","status":"passed","title":"sets title to match aria-label","duration":1.0464590000000271,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets icon to ☀️ for dark theme","status":"passed","title":"sets icon to ☀️ for dark theme","duration":1.2417749999999614,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets icon to 🌙 for light theme","status":"passed","title":"sets icon to 🌙 for light theme","duration":0.9873079999999845,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() does nothing gracefully when button is absent","status":"passed","title":"does nothing gracefully when button is absent","duration":1.5748780000000124,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() falls back to default label strings when data-label-* attrs are absent","status":"passed","title":"falls back to default label strings when data-label-* attrs are absent","duration":1.0248790000000554,"failureMessages":[],"location":{"line":222,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic switches from dark to light","status":"passed","title":"switches from dark to light","duration":1.105119000000002,"failureMessages":[],"location":{"line":247,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic switches from light to dark","status":"passed","title":"switches from light to dark","duration":0.9384860000000117,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic persists the new theme to localStorage","status":"passed","title":"persists the new theme to localStorage","duration":0.8902569999999628,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic updates button aria-pressed after toggle","status":"passed","title":"updates button aria-pressed after toggle","duration":0.986567999999977,"failureMessages":[],"location":{"line":268,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic treats absent data-theme as \"light\" and switches to dark","status":"passed","title":"treats absent data-theme as \"light\" and switches to dark","duration":0.9129989999999566,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic does not apply new theme when valid \"dark\" is stored (explicit choice wins)","status":"passed","title":"does not apply new theme when valid \"dark\" is stored (explicit choice wins)","duration":0.8834339999999656,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic does not apply new theme when valid \"light\" is stored","status":"passed","title":"does not apply new theme when valid \"light\" is stored","duration":0.7880059999999958,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic clears invalid stored value and follows system preference","status":"passed","title":"clears invalid stored value and follows system preference","duration":1.1100779999999872,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic follows system preference when localStorage is empty","status":"passed","title":"follows system preference when localStorage is empty","duration":1.057649999999967,"failureMessages":[],"location":{"line":332,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class adds theme-transition class on toggle","status":"passed","title":"adds theme-transition class on toggle","duration":4.434802999999988,"failureMessages":[],"location":{"line":376,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class removes theme-transition class after timeout","status":"passed","title":"removes theme-transition class after timeout","duration":1.9777730000000133,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class handles rapid toggles without premature class removal","status":"passed","title":"handles rapid toggles without premature class removal","duration":2.008609999999976,"failureMessages":[],"location":{"line":399,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic uses stored \"dark\" without clearing or overriding","status":"passed","title":"uses stored \"dark\" without clearing or overriding","duration":0.8607419999999593,"failureMessages":[],"location":{"line":426,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic uses stored \"light\" without clearing","status":"passed","title":"uses stored \"light\" without clearing","duration":0.8770420000000172,"failureMessages":[],"location":{"line":438,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic clears invalid stored value and falls back","status":"passed","title":"clears invalid stored value and falls back","duration":0.8427980000000161,"failureMessages":[],"location":{"line":449,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic falls back to \"light\" when localStorage throws","status":"passed","title":"falls back to \"light\" when localStorage throws","duration":0.8607010000000059,"failureMessages":[],"location":{"line":460,"column":5},"meta":{},"tags":[]}],"startTime":1787953685423,"endTime":1787953685471.8606,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/theme-toggle.test.js"},{"assertionResults":[{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a single dok_id reference","status":"passed","title":"counts a single dok_id reference","duration":4.372235999999987,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts mixed-case Riksdag committee report identifiers","status":"passed","title":"counts mixed-case Riksdag committee report identifiers","duration":0.656519000000003,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts two-uppercase-letter committee betänkande codes","status":"passed","title":"counts two-uppercase-letter committee betänkande codes","duration":0.4645399999999995,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts parliamentary doc references","status":"passed","title":"counts parliamentary doc references","duration":0.4883340000000089,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts Riksrevisionen audit references","status":"passed","title":"counts Riksrevisionen audit references","duration":0.499795000000006,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a primary-source URL without any embedded dok_id","status":"passed","title":"counts a primary-source URL without any embedded dok_id","duration":0.5737039999999638,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a riksdagen.se URL without doubling the count","status":"passed","title":"counts a riksdagen.se URL without doubling the count","duration":0.48123099999997976,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors returns zero for narrative prose without anchors","status":"passed","title":"returns zero for narrative prose without anchors","duration":0.40534900000000107,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors does NOT count ordinary English words as dok_ids","status":"passed","title":"does NOT count ordinary English words as dok_ids","duration":0.5670620000000213,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts multiple anchors of mixed types","status":"passed","title":"counts multiple anchors of mixed types","duration":0.44538399999999,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns null for a non-existent directory","status":"passed","title":"returns null for a non-existent directory","duration":0.8064800000000218,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns valid phrases from the real JSON","status":"passed","title":"returns valid phrases from the real JSON","duration":2.123816999999974,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns de-duplicated phrases","status":"passed","title":"returns de-duplicated phrases","duration":0.7041980000000194,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countArticleEvidenceAnchors"],"fullName":"validate-article — countArticleEvidenceAnchors counts dok_id and URL anchors","status":"passed","title":"counts dok_id and URL anchors","duration":0.6199910000000273,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countArticleEvidenceAnchors"],"fullName":"validate-article — countArticleEvidenceAnchors does NOT count #rm- internal links","status":"passed","title":"does NOT count #rm- internal links","duration":0.5160170000000335,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases detects a banned phrase (case-insensitive)","status":"passed","title":"detects a banned phrase (case-insensitive)","duration":0.6294879999999807,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases detects multiple occurrences of the same phrase","status":"passed","title":"detects multiple occurrences of the same phrase","duration":0.48322500000000446,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases returns empty array for clean text","status":"passed","title":"returns empty array for clean text","duration":1.3916150000000016,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases matches case-insensitively","status":"passed","title":"matches case-insensitively","duration":0.5315559999999664,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases skips empty and whitespace-only phrases without hanging","status":"passed","title":"skips empty and whitespace-only phrases without hanging","duration":0.5532559999999762,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords counts words in plain text","status":"passed","title":"counts words in plain text","duration":0.9855660000000057,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords excludes fenced code blocks","status":"passed","title":"excludes fenced code blocks","duration":0.4818920000000162,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords excludes fenced code blocks with language tag","status":"passed","title":"excludes fenced code blocks with language tag","duration":0.5857970000000137,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords strips markdown links but keeps link text","status":"passed","title":"strips markdown links but keeps link text","duration":0.4764319999999884,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords strips markdown table pipes and alignment rows","status":"passed","title":"strips markdown table pipes and alignment rows","duration":0.4964200000000005,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords handles table-heavy content without inflated counts","status":"passed","title":"handles table-heavy content without inflated counts","duration":0.49435599999998203,"failureMessages":[],"location":{"line":214,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity returns Infinity for text with no anchors","status":"passed","title":"returns Infinity for text with no anchors","duration":0.5652980000000412,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity computes density for text with anchors","status":"passed","title":"computes density for text with anchors","duration":0.6323639999999955,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity does not count #rm- internal links as evidence anchors","status":"passed","title":"does not count #rm- internal links as evidence anchors","duration":0.5037929999999733,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance flags entries older than 6 months","status":"passed","title":"flags entries older than 6 months","duration":0.9417940000000158,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance ignores entries within 6 months","status":"passed","title":"ignores entries within 6 months","duration":0.8762009999999805,"failureMessages":[],"location":{"line":255,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance ignores entries with stale-vintage annotation on immediately preceding line","status":"passed","title":"ignores entries with stale-vintage annotation on immediately preceding line","duration":0.8342419999999606,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance does NOT exempt entries when annotation is too far away","status":"passed","title":"does NOT exempt entries when annotation is too far away","duration":0.5933600000000183,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings returns 0 when no mermaid fences are present","status":"passed","title":"returns 0 when no mermaid fences are present","duration":0.6108239999999796,"failureMessages":[],"location":{"line":286,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings counts one opening fence per `\\`\\`\\`mermaid` line","status":"passed","title":"counts one opening fence per `\\`\\`\\`mermaid` line","duration":0.643304999999998,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings does not count `\\`\\`\\`mermaid` inside a fenced code block prose example","status":"passed","title":"does not count `\\`\\`\\`mermaid` inside a fenced code block prose example","duration":0.5938820000000078,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings counts even when an opening has no matching close (raw count)","status":"passed","title":"counts even when an opening has no matching close (raw count)","duration":0.598590999999999,"failureMessages":[],"location":{"line":302,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences returns an empty array when every fence is properly closed","status":"passed","title":"returns an empty array when every fence is properly closed","duration":0.8065300000000093,"failureMessages":[],"location":{"line":311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences flags a single unclosed fence","status":"passed","title":"flags a single unclosed fence","duration":0.7726370000000315,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences flags an unclosed fence followed by a properly closed one","status":"passed","title":"flags an unclosed fence followed by a properly closed one","duration":0.6867859999999837,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences detects every unclosed fence in a chain of unclosed mermaid openings (regression: no loop-skip)","status":"passed","title":"detects every unclosed fence in a chain of unclosed mermaid openings (regression: no loop-skip)","duration":0.8685159999999996,"failureMessages":[],"location":{"line":345,"column":3},"meta":{},"tags":[]}],"startTime":1787953791508,"endTime":1787953791539.8684,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-article.test.ts"},{"assertionResults":[{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countHeadings counts all #-headings outside fences","status":"passed","title":"countHeadings counts all #-headings outside fences","duration":3.8885910000000194,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countCodeFences counts fenced blocks (pairs of ```)","status":"passed","title":"countCodeFences counts fenced blocks (pairs of ```)","duration":0.6300989999999729,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countCodeFences reports malformed unpaired fences","status":"passed","title":"countCodeFences reports malformed unpaired fences","duration":0.4740279999999757,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countMermaidBlocks counts only ```mermaid blocks","status":"passed","title":"countMermaidBlocks counts only ```mermaid blocks","duration":0.4784559999999942,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countTableRows counts every line of every markdown table","status":"passed","title":"countTableRows counts every line of every markdown table","duration":0.5762589999999932,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractDokIds picks up Riksdag dok_ids","status":"passed","title":"extractDokIds picks up Riksdag dok_ids","duration":0.7267410000000041,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractDokIds ignores plain English / translated words that start with H (no digit)","status":"passed","title":"extractDokIds ignores plain English / translated words that start with H (no digit)","duration":0.623738000000003,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractUrls returns absolute URLs in link targets and bare text","status":"passed","title":"extractUrls returns absolute URLs in link targets and bare text","duration":0.6502369999999473,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractSourceShaMarker returns the 40-hex sha when present","status":"passed","title":"extractSourceShaMarker returns the 40-hex sha when present","duration":0.7609240000000455,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractSourceShaMarker only accepts the marker as the trailing non-empty line","status":"passed","title":"extractSourceShaMarker only accepts the marker as the trailing non-empty line","duration":0.4813819999999964,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters hasRtlMarker only matches when within the first 1KB","status":"passed","title":"hasRtlMarker only matches when within the first 1KB","duration":0.567592999999988,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countWords returns a reasonable approximation","status":"passed","title":"countWords returns a reasonable approximation","duration":1.6405720000000201,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters TRANSLATION_LANGS lists exactly the 13 non-English target languages","status":"passed","title":"TRANSLATION_LANGS lists exactly the 13 non-English target languages","duration":1.0355689999999527,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases returns empty array when translation has no banned English phrases","status":"passed","title":"returns empty array when translation has no banned English phrases","duration":0.8437999999999874,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases flags a translation that left \"Executive Brief\" untranslated","status":"passed","title":"flags a translation that left \"Executive Brief\" untranslated","duration":1.3353200000000243,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases flags a translation that left \"BLUF\" in the body","status":"passed","title":"flags a translation that left \"BLUF\" in the body","duration":0.5993520000000103,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end passes every check for a valid Swedish translation","status":"passed","title":"passes every check for a valid Swedish translation","duration":1.0582919999999945,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end passes every check (including RTL marker) for a valid Arabic translation","status":"passed","title":"passes every check (including RTL marker) for a valid Arabic translation","duration":0.7350059999999985,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails dok-id-preservation when the translation drops an identifier","status":"passed","title":"fails dok-id-preservation when the translation drops an identifier","duration":0.7524980000000028,"failureMessages":[],"location":{"line":254,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails url-preservation when the translation drops an external URL","status":"passed","title":"fails url-preservation when the translation drops an external URL","duration":0.690021999999999,"failureMessages":[],"location":{"line":268,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails rtl-marker when an Arabic translation is missing the marker","status":"passed","title":"fails rtl-marker when an Arabic translation is missing the marker","duration":0.874888999999996,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags source-sha-marker as stale when trailer does not match current source SHA","status":"passed","title":"flags source-sha-marker as stale when trailer does not match current source SHA","duration":0.6786710000000085,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags source-sha-marker as missing when trailer is absent","status":"passed","title":"flags source-sha-marker as missing when trailer is absent","duration":0.7526090000000067,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags code-fence-count when the translation has an unpaired fence","status":"passed","title":"flags code-fence-count when the translation has an unpaired fence","duration":0.7551249999999641,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags word-count-drift when the translation is more than 25% shorter","status":"passed","title":"flags word-count-drift when the translation is more than 25% shorter","duration":1.1232229999999959,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end skips word-count-drift for CJK scripts (ja, zh) — whitespace tokeniser systematically undercounts","status":"passed","title":"skips word-count-drift for CJK scripts (ja, zh) — whitespace tokeniser systematically undercounts","duration":0.9130899999999542,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]}],"startTime":1787953814613,"endTime":1787953814636.913,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-executive-brief-translations.test.ts"},{"assertionResults":[{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown extracts the language code from an executive-brief_<lang>.md path","status":"passed","title":"extracts the language code from an executive-brief_<lang>.md path","duration":3.924149,"failureMessages":[],"location":{"line":11,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown returns null for the English-master executive-brief.md (no suffix)","status":"passed","title":"returns null for the English-master executive-brief.md (no suffix)","duration":0.5720010000000002,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown still works for news/<slug>-<lang>.html paths","status":"passed","title":"still works for news/<slug>-<lang>.html paths","duration":0.42831200000000536,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown English-master executive-brief.md is owned by the content category","status":"passed","title":"English-master executive-brief.md is owned by the content category","duration":0.5952449999999772,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown Swedish executive-brief_sv.md is owned by the translation category","status":"passed","title":"Swedish executive-brief_sv.md is owned by the translation category","duration":0.5601389999999924,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown Arabic and Chinese briefs are owned by the translation category","status":"passed","title":"Arabic and Chinese briefs are owned by the translation category","duration":0.4549519999999916,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown does not affect non-executive-brief markdown files outside analysis/daily","status":"passed","title":"does not affect non-executive-brief markdown files outside analysis/daily","duration":0.45595400000001973,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown still enforces the existing news/*.html ownership rules","status":"passed","title":"still enforces the existing news/*.html ownership rules","duration":0.40357599999998683,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches flags a translation batch that touches the English-master brief","status":"passed","title":"flags a translation batch that touches the English-master brief","duration":1.5131739999999922,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches flags a content batch that touches translated briefs","status":"passed","title":"flags a content batch that touches translated briefs","duration":0.40639099999998507,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches passes a pure translation batch (all 13 non-EN briefs)","status":"passed","title":"passes a pure translation batch (all 13 non-EN briefs)","duration":0.679792999999961,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches ignores unrelated markdown files","status":"passed","title":"ignores unrelated markdown files","duration":0.35022499999996626,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns null when no ownership-surface files are present","status":"passed","title":"returns null when no ownership-surface files are present","duration":0.6053640000000087,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"translation\" when any executive-brief_<lang>.md is present","status":"passed","title":"returns \"translation\" when any executive-brief_<lang>.md is present","duration":0.47287500000004457,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when any news/*.html is present (all langs are content-owned)","status":"passed","title":"returns \"content\" when any news/*.html is present (all langs are content-owned)","duration":0.45745600000003606,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when only news/*.html and/or executive-brief.md are present","status":"passed","title":"returns \"content\" when only news/*.html and/or executive-brief.md are present","duration":0.41850299999998697,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns null for mixed content + translation surfaces (skip enforcement)","status":"passed","title":"returns null for mixed content + translation surfaces (skip enforcement)","duration":0.4491909999999848,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when only article.<lang>.md is present (forbidden but detected)","status":"passed","title":"returns \"content\" when only article.<lang>.md is present (forbidden but detected)","duration":0.3564079999999876,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseWorkflowCategoryArg"],"fullName":"parseWorkflowCategoryArg accepts long-form and short CLI category aliases","status":"passed","title":"accepts long-form and short CLI category aliases","duration":0.4820530000000076,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects article.sv.md in content category","status":"passed","title":"rejects article.sv.md in content category","duration":1.467138000000034,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects article.sv.md in translation category","status":"passed","title":"rejects article.sv.md in translation category","duration":0.7097190000000069,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files allows article.md (English source)","status":"passed","title":"allows article.md (English source)","duration":0.5414940000000001,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects multiple localized article files","status":"passed","title":"rejects multiple localized article files","duration":0.6721589999999651,"failureMessages":[],"location":{"line":225,"column":3},"meta":{},"tags":[]}],"startTime":1787953826891,"endTime":1787953826908.672,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-file-ownership-exec-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["Canonical schema constants"],"fullName":"Canonical schema constants declares exactly 7 canonical columns in order","status":"passed","title":"declares exactly 7 canonical columns in order","duration":3.8393279999999663,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Canonical schema constants"],"fullName":"Canonical schema constants lists riksdag-regering as a required server","status":"passed","title":"lists riksdag-regering as a required server","duration":1.2767200000000116,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection extracts the MCP Reliability section body","status":"passed","title":"extracts the MCP Reliability section body","duration":0.8495199999999841,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection returns null when the section is absent","status":"passed","title":"returns null when the section is absent","duration":0.4079039999999736,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection accepts the section header with an emoji preamble","status":"passed","title":"accepts the section header with an emoji preamble","duration":0.42613700000003973,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable parses header + data rows correctly","status":"passed","title":"parses header + data rows correctly","duration":2.4565190000000143,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable returns empty arrays when no table is present","status":"passed","title":"returns empty arrays when no table is present","duration":0.5411040000000185,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable preserves row order (rowIndex is 1-based)","status":"passed","title":"preserves row order (rowIndex is 1-based)","duration":0.4139350000000377,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — happy path"],"fullName":"validateMCPReliability — happy path PASSES a canonical manifest with riksdag-regering coverage","status":"passed","title":"PASSES a canonical manifest with riksdag-regering coverage","duration":2.5644609999999943,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — file-exists"],"fullName":"validateMCPReliability — file-exists reports error when manifest is missing","status":"passed","title":"reports error when manifest is missing","duration":0.5915480000000457,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — section-missing"],"fullName":"validateMCPReliability — section-missing reports error when §MCP Reliability heading is absent","status":"passed","title":"reports error when §MCP Reliability heading is absent","duration":1.0889890000000264,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — table-missing"],"fullName":"validateMCPReliability — table-missing reports error when section exists but no table is present","status":"passed","title":"reports error when section exists but no table is present","duration":0.8466350000000489,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — column-order"],"fullName":"validateMCPReliability — column-order reports error when columns are in the wrong order","status":"passed","title":"reports error when columns are in the wrong order","duration":0.9118870000000356,"failureMessages":[],"location":{"line":238,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — extra-columns (warning only)"],"fullName":"validateMCPReliability — extra-columns (warning only) warns but does not fail when extra columns are present","status":"passed","title":"warns but does not fail when extra columns are present","duration":0.9737729999999942,"failureMessages":[],"location":{"line":249,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — no-rows"],"fullName":"validateMCPReliability — no-rows reports error when the table has header but no data rows","status":"passed","title":"reports error when the table has header but no data rows","duration":0.9056860000000029,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — non-numeric-cell"],"fullName":"validateMCPReliability — non-numeric-cell reports error when a numeric cell is not an integer","status":"passed","title":"reports error when a numeric cell is not an integer","duration":0.9920470000000137,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — arithmetic-consistency"],"fullName":"validateMCPReliability — arithmetic-consistency reports error when successes + failures exceeds calls","status":"passed","title":"reports error when successes + failures exceeds calls","duration":0.9047239999999874,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — arithmetic-consistency"],"fullName":"validateMCPReliability — arithmetic-consistency accepts successes + failures < calls (pending-outcome case)","status":"passed","title":"accepts successes + failures < calls (pending-outcome case)","duration":0.8595490000000154,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — required-server"],"fullName":"validateMCPReliability — required-server reports error when riksdag-regering has no rows","status":"passed","title":"reports error when riksdag-regering has no rows","duration":0.9104950000000258,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]}],"startTime":1787953822829,"endTime":1787953822850.9104,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-mcp-reliability.test.ts"},{"assertionResults":[{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 0.8 for realtime-* folders","status":"passed","title":"returns 0.8 for realtime-* folders","duration":3.365111000000013,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 0.9 for evening-analysis","status":"passed","title":"returns 0.9 for evening-analysis","duration":0.4925819999999703,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 1.0 for week-ahead / weekly-review baselines","status":"passed","title":"returns 1.0 for week-ahead / weekly-review baselines","duration":0.5490379999999959,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 1.3 for month-ahead, 1.5 for monthly-review","status":"passed","title":"returns 1.3 for month-ahead, 1.5 for monthly-review","duration":0.37845900000002075,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier defaults to 1.0 for unknown subfolders","status":"passed","title":"defaults to 1.0 for unknown subfolders","duration":0.4316580000000272,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder recognises all documented Tier-C folder names","status":"passed","title":"recognises all documented Tier-C folder names","duration":0.7102499999999736,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder recognises realtime-HHMM subfolders as Tier-C","status":"passed","title":"recognises realtime-HHMM subfolders as Tier-C","duration":0.415157000000022,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder rejects doc-type leaf folders","status":"passed","title":"rejects doc-type leaf folders","duration":0.5397800000000075,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — happy paths"],"fullName":"validateMethodologyReflection — happy paths PASSES a full Tier-C fixture that satisfies every rule","status":"passed","title":"PASSES a full Tier-C fixture that satisfies every rule","duration":4.697534999999959,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — happy paths"],"fullName":"validateMethodologyReflection — happy paths PASSES a minimal doc-type fixture (Pipeline Overview + References)","status":"passed","title":"PASSES a minimal doc-type fixture (Pipeline Overview + References)","duration":0.9932900000000018,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — file-exists rule"],"fullName":"validateMethodologyReflection — file-exists rule reports error when file is missing","status":"passed","title":"reports error when file is missing","duration":0.7513659999999618,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule flags files below the scaled minimum","status":"passed","title":"flags files below the scaled minimum","duration":1.3021980000000326,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule applies the 1.3× multiplier for month-ahead folders","status":"passed","title":"applies the 1.3× multiplier for month-ahead folders","duration":2.1561679999999797,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule applies the 1.5× multiplier for monthly-review","status":"passed","title":"applies the 1.5× multiplier for monthly-review","duration":0.9485050000000115,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule flags missing §Known Limitations in Tier-C","status":"passed","title":"flags missing §Known Limitations in Tier-C","duration":1.180059999999969,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"What Would Strengthen Future Runs\" for Pass-1 → Pass-2","status":"passed","title":"accepts synonym H2 \"What Would Strengthen Future Runs\" for Pass-1 → Pass-2","duration":1.0157520000000204,"failureMessages":[],"location":{"line":255,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"Recommendations for Codification\" for Recommendations","status":"passed","title":"accepts synonym H2 \"Recommendations for Codification\" for Recommendations","duration":1.0567890000000375,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"Cross-References\" for References","status":"passed","title":"accepts synonym H2 \"Cross-References\" for References","duration":1.0302189999999882,"failureMessages":[],"location":{"line":275,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule flags missing §Data Source Connectivity Audit in Tier-C","status":"passed","title":"flags missing §Data Source Connectivity Audit in Tier-C","duration":1.1672159999999963,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule does NOT require §Data Source Connectivity Audit in doc-type folders","status":"passed","title":"does NOT require §Data Source Connectivity Audit in doc-type folders","duration":0.918610000000001,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) flags Upstream Watchpoint Reconciliation section without a table","status":"passed","title":"flags Upstream Watchpoint Reconciliation section without a table","duration":1.086714000000029,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) flags Watchpoint section with table but no disposition keywords","status":"passed","title":"flags Watchpoint section with table but no disposition keywords","duration":1.1725359999999796,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) does NOT apply watchpoint rules to doc-type folders","status":"passed","title":"does NOT apply watchpoint rules to doc-type folders","duration":0.8868309999999724,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — sibling-cross-reference rule (Tier-C only)"],"fullName":"validateMethodologyReflection — sibling-cross-reference rule (Tier-C only) flags a Tier-C file with no sibling-run links","status":"passed","title":"flags a Tier-C file with no sibling-run links","duration":0.9961950000000002,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — sibling-cross-reference rule (Tier-C only)"],"fullName":"validateMethodologyReflection — sibling-cross-reference rule (Tier-C only) does NOT require sibling links on doc-type folders","status":"passed","title":"does NOT require sibling links on doc-type folders","duration":0.9636539999999627,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — confidence-label rule (universal)"],"fullName":"validateMethodologyReflection — confidence-label rule (universal) flags any file without [HIGH] / [MEDIUM] / [LOW] tokens","status":"passed","title":"flags any file without [HIGH] / [MEDIUM] / [LOW] tokens","duration":0.9915260000000217,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — confidence-label rule (universal)"],"fullName":"validateMethodologyReflection — confidence-label rule (universal) accepts [VERY HIGH] as a valid confidence variant","status":"passed","title":"accepts [VERY HIGH] as a valid confidence variant","duration":0.9734429999999747,"failureMessages":[],"location":{"line":349,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — imf-primary-violation rule"],"fullName":"validateMethodologyReflection — imf-primary-violation rule warns when World Bank is used for GDP data (economic substitution)","status":"passed","title":"warns when World Bank is used for GDP data (economic substitution)","duration":1.0861740000000282,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — imf-primary-violation rule"],"fullName":"validateMethodologyReflection — imf-primary-violation rule does not warn when World Bank is used for governance data","status":"passed","title":"does not warn when World Bank is used for governance data","duration":0.9447890000000143,"failureMessages":[],"location":{"line":370,"column":3},"meta":{},"tags":[]}],"startTime":1787953785234,"endTime":1787953785268.9448,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-methodology-reflection.test.ts"},{"assertionResults":[{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders exposes a non-empty PLACEHOLDER_PATTERNS array","status":"passed","title":"exposes a non-empty PLACEHOLDER_PATTERNS array","duration":3.5539440000000013,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders scanPlaceholders returns the matched literal for every hit","status":"passed","title":"scanPlaceholders returns the matched literal for every hit","duration":1.5008699999999635,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders checkPlaceholders emits one violation per pattern hit with stable code","status":"passed","title":"checkPlaceholders emits one violation per pattern hit with stable code","duration":0.7826450000000023,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders checkPlaceholders returns empty array for clean text","status":"passed","title":"checkPlaceholders returns empty array for clean text","duration":1.0181059999999889,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks REQUIRED_LANDMARKS includes Reader Intelligence Guide, Executive Brief, BLUF, Article Sources","status":"passed","title":"REQUIRED_LANDMARKS includes Reader Intelligence Guide, Executive Brief, BLUF, Article Sources","duration":0.6250410000000102,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks passes a complete fixture","status":"passed","title":"checkLandmarks passes a complete fixture","duration":1.078439000000003,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks reports every missing landmark for a stub document","status":"passed","title":"checkLandmarks reports every missing landmark for a stub document","duration":0.7611960000000408,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks flags duplicate Reader Intelligence Guide headings","status":"passed","title":"checkLandmarks flags duplicate Reader Intelligence Guide headings","duration":0.5208849999999643,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks flags an empty Reader Intelligence Guide table","status":"passed","title":"checkLandmarks flags an empty Reader Intelligence Guide table","duration":0.5688350000000355,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers FOOTER_MARKER_PATTERNS covers ISMS / Classified under / Hack23 ISMS / Article-Generation / Provenance / GDPR","status":"passed","title":"FOOTER_MARKER_PATTERNS covers ISMS / Classified under / Hack23 ISMS / Article-Generation / Provenance / GDPR","duration":0.4631069999999795,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers checkFooterMarkers flags exact-duplicate footer lines","status":"passed","title":"checkFooterMarkers flags exact-duplicate footer lines","duration":1.047031000000004,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers checkFooterMarkers does NOT flag distinct footer lines with the same prefix","status":"passed","title":"checkFooterMarkers does NOT flag distinct footer lines with the same prefix","duration":0.36942200000004277,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document extractPerDocumentSections returns each ### dok_id heading with its body","status":"passed","title":"extractPerDocumentSections returns each ### dok_id heading with its body","duration":0.768447999999978,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document checkPerDocument flags sections lacking any dok_id","status":"passed","title":"checkPerDocument flags sections lacking any dok_id","duration":0.6908540000000016,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document DOK_ID_TOKEN_RE matches both H… and short-prefix codes","status":"passed","title":"DOK_ID_TOKEN_RE matches both H… and short-prefix codes","duration":0.49700999999998885,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document MIN_PER_DOC_DOK_ID_HITS is at least 1","status":"passed","title":"MIN_PER_DOC_DOK_ID_HITS is at least 1","duration":0.3886669999999981,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug permissiveSlug produces lowercased hyphen-separated tokens","status":"passed","title":"permissiveSlug produces lowercased hyphen-separated tokens","duration":0.9452299999999809,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug permissiveSlug returns empty string for symbol-only headings","status":"passed","title":"permissiveSlug returns empty string for symbol-only headings","duration":0.3656349999999975,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug checkHeadingSlugs flags a heading that produces an empty slug","status":"passed","title":"checkHeadingSlugs flags a heading that produces an empty slug","duration":0.538408000000004,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug checkHeadingSlugs is silent on well-formed headings","status":"passed","title":"checkHeadingSlugs is silent on well-formed headings","duration":0.44324000000000296,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — mermaid fences"],"fullName":"article rules — mermaid fences checkUnclosedMermaidFences returns empty for balanced fences","status":"passed","title":"checkUnclosedMermaidFences returns empty for balanced fences","duration":0.7630089999999541,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — mermaid fences"],"fullName":"article rules — mermaid fences checkUnclosedMermaidFences reports unclosed openings with line numbers in the message","status":"passed","title":"checkUnclosedMermaidFences reports unclosed openings with line numbers in the message","duration":0.9915270000000191,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]}],"startTime":1787953839200,"endTime":1787953839219.9915,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators-article-rules.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics writes the key metrics into matching DOM elements","status":"passed","title":"writes the key metrics into matching DOM elements","duration":20.982471000000032,"failureMessages":[],"location":{"line":393,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics warns and is a no-op when overview is missing","status":"passed","title":"warns and is a no-op when overview is missing","duration":1.5793069999999716,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics skips alert elements when riskAlerts.last90Days is missing","status":"passed","title":"skips alert elements when riskAlerts.last90Days is missing","duration":1.1289539999999647,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance builds bar + line charts with correct labels and party count","status":"passed","title":"builds bar + line charts with correct labels and party count","duration":3.968980999999985,"failureMessages":[],"location":{"line":443,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance warns and is a no-op when parties array is missing","status":"passed","title":"warns and is a no-op when parties array is missing","duration":1.4691209999999728,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance does not call Chart when Chart is undefined","status":"passed","title":"does not call Chart when Chart is undefined","duration":1.152417000000014,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance replaces invalid numeric metrics with 0 and unnamed shortName with \"Unknown\"","status":"passed","title":"replaces invalid numeric metrics with 0 and unnamed shortName with \"Unknown\"","duration":1.4169730000000413,"failureMessages":[],"location":{"line":486,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings renders one ranking-item per MP with name, party and influence score","status":"passed","title":"renders one ranking-item per MP with name, party and influence score","duration":5.898993999999959,"failureMessages":[],"location":{"line":508,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings renders \"N/A\" when influenceScore is NaN","status":"passed","title":"renders \"N/A\" when influenceScore is NaN","duration":2.065607,"failureMessages":[],"location":{"line":519,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings does nothing when the container is missing","status":"passed","title":"does nothing when the container is missing","duration":1.833923000000027,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings warns and clears when rankings is invalid","status":"passed","title":"warns and clears when rankings is invalid","duration":1.9078820000000292,"failureMessages":[],"location":{"line":537,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns produces a stacked bar chart with one dataset per party row","status":"passed","title":"produces a stacked bar chart with one dataset per party row","duration":1.4283250000000294,"failureMessages":[],"location":{"line":553,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns returns silently when canvas is missing","status":"passed","title":"returns silently when canvas is missing","duration":0.8928210000000263,"failureMessages":[],"location":{"line":563,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns warns when votingMatrix structure is invalid","status":"passed","title":"warns when votingMatrix structure is invalid","duration":1.1403349999999932,"failureMessages":[],"location":{"line":569,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork renders one committee-card per committee and a network note","status":"passed","title":"renders one committee-card per committee and a network note","duration":3.3599309999999605,"failureMessages":[],"location":{"line":585,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork formats missing/invalid stats as \"N/A\"","status":"passed","title":"formats missing/invalid stats as \"N/A\"","duration":2.273005000000012,"failureMessages":[],"location":{"line":598,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork warns and bails when committees is invalid","status":"passed","title":"warns and bails when committees is invalid","duration":1.0582410000000095,"failureMessages":[],"location":{"line":609,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork does nothing when container is missing","status":"passed","title":"does nothing when container is missing","duration":1.0004829999999743,"failureMessages":[],"location":{"line":617,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance renders one card per ministry with assessment tag","status":"passed","title":"renders one card per ministry with assessment tag","duration":2.1588919999999803,"failureMessages":[],"location":{"line":630,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance warns when ministry list is empty","status":"passed","title":"warns when ministry list is empty","duration":1.1065009999999802,"failureMessages":[],"location":{"line":638,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance falls back to \"N/A\" when effectiveness is missing","status":"passed","title":"falls back to \"N/A\" when effectiveness is missing","duration":2.016444999999976,"failureMessages":[],"location":{"line":648,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics builds gender + experience charts indexed by Riksdag party order","status":"passed","title":"builds gender + experience charts indexed by Riksdag party order","duration":10.217317999999977,"failureMessages":[],"location":{"line":663,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics warns and is a no-op when demographics arrays are missing","status":"passed","title":"warns and is a no-op when demographics arrays are missing","duration":1.1560249999999996,"failureMessages":[],"location":{"line":685,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics does not crash when canvases are missing from DOM","status":"passed","title":"does not crash when canvases are missing from DOM","duration":1.0922939999999812,"failureMessages":[],"location":{"line":693,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDocumentActivity"],"fullName":"CIADashboardRenderer renderDocumentActivity produces a line chart with motions/bet/prop datasets in recent years","status":"passed","title":"produces a line chart with motions/bet/prop datasets in recent years","duration":1.6568120000000022,"failureMessages":[],"location":{"line":707,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDocumentActivity"],"fullName":"CIADashboardRenderer renderDocumentActivity warns and is a no-op when document activity is malformed","status":"passed","title":"warns and is a no-op when document activity is malformed","duration":1.1970010000000002,"failureMessages":[],"location":{"line":719,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution groups entries by YYYY-MM and renders sorted descending","status":"passed","title":"groups entries by YYYY-MM and renders sorted descending","duration":2.5353870000000143,"failureMessages":[],"location":{"line":734,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution warns and is a no-op for empty entries","status":"passed","title":"warns and is a no-op for empty entries","duration":1.2687250000000176,"failureMessages":[],"location":{"line":747,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution does nothing when the container is missing","status":"passed","title":"does nothing when the container is missing","duration":1.066255999999953,"failureMessages":[],"location":{"line":757,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","destroy"],"fullName":"CIADashboardRenderer destroy calls destroy() on every chart instance and clears the map","status":"passed","title":"calls destroy() on every chart instance and clears the map","duration":1.628088000000048,"failureMessages":[],"location":{"line":770,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","destroy"],"fullName":"CIADashboardRenderer destroy is a safe no-op when no charts have been created","status":"passed","title":"is a safe no-op when no charts have been created","duration":3.350885999999946,"failureMessages":[],"location":{"line":786,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer"],"fullName":"CIADashboardRenderer drives all 9 renderers end-to-end without throwing","status":"passed","title":"drives all 9 renderers end-to-end without throwing","duration":4.82669599999997,"failureMessages":[],"location":{"line":797,"column":3},"meta":{},"tags":[]}],"startTime":1787953661774,"endTime":1787953661864.8267,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/visualizations.test.ts"},{"assertionResults":[{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the news-articles page set (recurse: true)","status":"passed","title":"registers the news-articles page set (recurse: true)","duration":3.813729999999964,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the sitemaps page set with all 14 language variants","status":"passed","title":"registers the sitemaps page set with all 14 language variants","duration":1.6471940000000131,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the political-intelligence page set with all 14 language variants","status":"passed","title":"registers the political-intelligence page set with all 14 language variants","duration":1.7255309999999895,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the dashboards page set so /dashboards/*.html is served by vite preview","status":"passed","title":"registers the dashboards page set so /dashboards/*.html is served by vite preview","duration":0.5464430000000107,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets every directory listed in build-dashboard-pages.py output exists on disk","status":"passed","title":"every directory listed in build-dashboard-pages.py output exists on disk","duration":0.9513120000000299,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]}],"startTime":1787953906384,"endTime":1787953906392.9514,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-config-page-sets.test.ts"},{"assertionResults":[{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites root-level styles.css href to the stable bundle path (no SRI)","status":"passed","title":"rewrites root-level styles.css href to the stable bundle path (no SRI)","duration":7.474053000000026,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites ../styles.css references for one-level-deep pages","status":"passed","title":"rewrites ../styles.css references for one-level-deep pages","duration":1.7830890000000181,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages emits every HTML file in a directory page set and creates parent directories","status":"passed","title":"emits every HTML file in a directory page set and creates parent directories","duration":2.539484000000016,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages leaves pages without a styles.css link unchanged but still emits them","status":"passed","title":"leaves pages without a styles.css link unchanged but still emits them","duration":1.2886829999999918,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages falls back to scanning dist/assets/ when the manifest lacks a styles.css entry","status":"passed","title":"falls back to scanning dist/assets/ when the manifest lacks a styles.css entry","duration":1.0981859999999983,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages discovers a legacy hashed styles-*.css when the stable bundle is absent","status":"passed","title":"discovers a legacy hashed styles-*.css when the stable bundle is absent","duration":1.4320109999999886,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages throws a descriptive error when the bundled styles.css cannot be located","status":"passed","title":"throws a descriptive error when the bundled styles.css cannot be located","duration":2.4716869999999744,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages skips missing source entries silently rather than failing the build","status":"passed","title":"skips missing source entries silently rather than failing the build","duration":1.1527879999999868,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages preserves pre-existing attributes on the <link rel=\"stylesheet\"> tag","status":"passed","title":"preserves pre-existing attributes on the <link rel=\"stylesheet\"> tag","duration":1.6243709999999965,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages exposes the Vite plugin contract (apply, enforce, name, closeBundle hook)","status":"passed","title":"exposes the Vite plugin contract (apply, enforce, name, closeBundle hook)","duration":0.9381060000000048,"failureMessages":[],"location":{"line":274,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites <script type=\"module\" src=\"/src/browser/main.ts\"> → hashed bundle from manifest","status":"passed","title":"rewrites <script type=\"module\" src=\"/src/browser/main.ts\"> → hashed bundle from manifest","duration":2.2010310000000004,"failureMessages":[],"location":{"line":317,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages falls back to scanning dist/assets/js/ when manifest lacks a src/browser/<name>.ts entry","status":"passed","title":"falls back to scanning dist/assets/js/ when manifest lacks a src/browser/<name>.ts entry","duration":1.4021949999999492,"failureMessages":[],"location":{"line":348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages leaves the dev script tag untouched when no hashed bundle can be resolved","status":"passed","title":"leaves the dev script tag untouched when no hashed bundle can be resolved","duration":1.148239999999987,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not rewrite script tags whose src does not match /src/browser/<name>.ts","status":"passed","title":"does not rewrite script tags whose src does not match /src/browser/<name>.ts","duration":1.209103999999968,"failureMessages":[],"location":{"line":394,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not duplicate the crossorigin attribute when the source tag already has one","status":"passed","title":"does not duplicate the crossorigin attribute when the source tag already has one","duration":1.4629679999999894,"failureMessages":[],"location":{"line":421,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not rewrite a non-module <script> tag whose src points at /src/browser/<name>.ts","status":"passed","title":"does not rewrite a non-module <script> tag whose src points at /src/browser/<name>.ts","duration":1.3695839999999748,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites the dev script tag across many pages but resolves the manifest only once per entry","status":"passed","title":"rewrites the dev script tag across many pages but resolves the manifest only once per entry","duration":1.6498589999999922,"failureMessages":[],"location":{"line":487,"column":3},"meta":{},"tags":[]}],"startTime":1787953681302,"endTime":1787953681334.65,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-plugin-static-pages.test.ts"},{"assertionResults":[{"ancestorTitles":["vite-plugin-sw-build-id — plugin shape"],"fullName":"vite-plugin-sw-build-id — plugin shape exports a factory that returns the expected Vite plugin shape","status":"passed","title":"exports a factory that returns the expected Vite plugin shape","duration":10.034611999999981,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler substitutes __BUILD_ID__ with a GITHUB_SHA-derived value","status":"passed","title":"substitutes __BUILD_ID__ with a GITHUB_SHA-derived value","duration":1.603652000000011,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler substitutes __BUILD_ID__ via git fallback when GITHUB_SHA is not set","status":"passed","title":"substitutes __BUILD_ID__ via git fallback when GITHUB_SHA is not set","duration":7.125664000000029,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler replaces ALL occurrences of __BUILD_ID__ in the source file","status":"passed","title":"replaces ALL occurrences of __BUILD_ID__ in the source file","duration":1.0141990000000192,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler supports a custom outDir option","status":"passed","title":"supports a custom outDir option","duration":0.860320999999999,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — error paths"],"fullName":"vite-plugin-sw-build-id — error paths throws when public/sw.js does not exist","status":"passed","title":"throws when public/sw.js does not exist","duration":1.79283700000002,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — error paths"],"fullName":"vite-plugin-sw-build-id — error paths throws when sw.js is missing the __BUILD_ID__ placeholder","status":"passed","title":"throws when sw.js is missing the __BUILD_ID__ placeholder","duration":0.9704380000000015,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]}],"startTime":1787953849178,"endTime":1787953849201.9705,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-plugin-sw-build-id.test.ts"},{"assertionResults":[{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should create client with default configuration","status":"passed","title":"should create client with default configuration","duration":4.414615999999967,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should accept custom configuration","status":"passed","title":"should accept custom configuration","duration":0.8693380000000275,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should use default values for partial config","status":"passed","title":"should use default values for partial config","duration":0.6595649999999864,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should sort results by date descending","status":"passed","title":"should sort results by date descending","duration":2.414009999999962,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return data points for valid API response","status":"passed","title":"should return data points for valid API response","duration":1.4006630000000087,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should filter out null values","status":"passed","title":"should filter out null values","duration":0.8028120000000172,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return empty array for invalid API response","status":"passed","title":"should return empty array for invalid API response","duration":0.7106410000000096,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return empty array for non-array response","status":"passed","title":"should return empty array for non-array response","duration":0.7366200000000163,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should construct correct URL","status":"passed","title":"should construct correct URL","duration":3.5657959999999775,"failureMessages":[],"location":{"line":187,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should retry on failure","status":"passed","title":"should retry on failure","duration":1002.3510030000001,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should throw after max retries","status":"passed","title":"should throw after max retries","duration":2.678863000000092,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should handle HTTP error responses","status":"passed","title":"should handle HTTP error responses","duration":0.7566369999999552,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getLatestIndicator"],"fullName":"WorldBankClient getLatestIndicator should return the first data point","status":"passed","title":"should return the first data point","duration":0.8096160000000054,"failureMessages":[],"location":{"line":253,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getLatestIndicator"],"fullName":"WorldBankClient getLatestIndicator should return null when no data available","status":"passed","title":"should return null when no data available","duration":0.6784800000000359,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","compareCountries"],"fullName":"WorldBankClient compareCountries should return comparison map for multiple countries","status":"passed","title":"should return comparison map for multiple countries","duration":0.8772819999999228,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","compareCountries"],"fullName":"WorldBankClient compareCountries should handle errors for individual countries gracefully","status":"passed","title":"should handle errors for individual countries gracefully","duration":0.8800979999998617,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have Sweden","status":"passed","title":"should have Sweden","duration":0.5875500000001921,"failureMessages":[],"location":{"line":351,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have all Nordic countries","status":"passed","title":"should have all Nordic countries","duration":0.5843139999999494,"failureMessages":[],"location":{"line":355,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have Germany for EU comparison","status":"passed","title":"should have Germany for EU comparison","duration":0.543327999999974,"failureMessages":[],"location":{"line":361,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have EU aggregate","status":"passed","title":"should have EU aggregate","duration":0.589813999999933,"failureMessages":[],"location":{"line":365,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdp\" (NY.GDP.MKTP.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdp\" (NY.GDP.MKTP.CD) — IMF supplies that context","duration":0.6778090000000248,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdpGrowth\" (NY.GDP.MKTP.KD.ZG) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdpGrowth\" (NY.GDP.MKTP.KD.ZG) — IMF supplies that context","duration":0.5375359999998182,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdpPerCapita\" (NY.GDP.PCAP.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdpPerCapita\" (NY.GDP.PCAP.CD) — IMF supplies that context","duration":0.49398500000006607,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"unemployment\" (SL.UEM.TOTL.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"unemployment\" (SL.UEM.TOTL.ZS) — IMF supplies that context","duration":0.5231800000001385,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"inflation\" (FP.CPI.TOTL.ZG) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"inflation\" (FP.CPI.TOTL.ZG) — IMF supplies that context","duration":0.5122890000000098,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"consumerPriceIndex\" (FP.CPI.TOTL) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"consumerPriceIndex\" (FP.CPI.TOTL) — IMF supplies that context","duration":0.5354119999999511,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"govExpenditure\" (GC.XPN.TOTL.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"govExpenditure\" (GC.XPN.TOTL.GD.ZS) — IMF supplies that context","duration":0.4881639999998697,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"govRevenue\" (GC.REV.XGRT.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"govRevenue\" (GC.REV.XGRT.GD.ZS) — IMF supplies that context","duration":0.5668410000000677,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"taxRevenue\" (GC.TAX.TOTL.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"taxRevenue\" (GC.TAX.TOTL.GD.ZS) — IMF supplies that context","duration":0.5958659999998872,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"currentAccountBalance\" (BN.CAB.XOKA.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"currentAccountBalance\" (BN.CAB.XOKA.GD.ZS) — IMF supplies that context","duration":0.5417740000000322,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"exportsGdpPct\" (NE.EXP.GNFS.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"exportsGdpPct\" (NE.EXP.GNFS.ZS) — IMF supplies that context","duration":0.6411600000001272,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"importsGdpPct\" (NE.IMP.GNFS.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"importsGdpPct\" (NE.IMP.GNFS.ZS) — IMF supplies that context","duration":0.9431460000000698,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"fdiNet\" (BN.KLT.DINV.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"fdiNet\" (BN.KLT.DINV.CD) — IMF supplies that context","duration":0.6130679999998847,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"realInterestRate\" (FR.INR.RINR) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"realInterestRate\" (FR.INR.RINR) — IMF supplies that context","duration":0.6472429999998894,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"lendingRate\" (FR.INR.LEND) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"lendingRate\" (FR.INR.LEND) — IMF supplies that context","duration":2.527462000000014,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"laborForceParticipation\" (SL.TLF.CACT.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"laborForceParticipation\" (SL.TLF.CACT.ZS) — IMF supplies that context","duration":0.6244690000000901,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope includes the World Bank coverage areas (military, environment, governance, demographics, health, education)","status":"passed","title":"includes the World Bank coverage areas (military, environment, governance, demographics, health, education)","duration":0.7048399999998765,"failureMessages":[],"location":{"line":396,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope defines a meaningful number of World Bank indicators","status":"passed","title":"defines a meaningful number of World Bank indicators","duration":0.6671389999999064,"failureMessages":[],"location":{"line":405,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope uses a valid World Bank indicator ID format for every entry","status":"passed","title":"uses a valid World Bank indicator ID format for every entry","duration":1.801812999999811,"failureMessages":[],"location":{"line":409,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope must cover every non-economic Riksdag-relevant domain","status":"passed","title":"must cover every non-economic Riksdag-relevant domain","duration":1.094128999999839,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope should stay in sync with JSON inventory (single source of truth)","status":"passed","title":"should stay in sync with JSON inventory (single source of truth)","duration":4.245097999999871,"failureMessages":[],"location":{"line":437,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should contain 6 governance indicator IDs","status":"passed","title":"should contain 6 governance indicator IDs","duration":0.802122000000054,"failureMessages":[],"location":{"line":469,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should include all WGI estimate indicators","status":"passed","title":"should include all WGI estimate indicators","duration":0.870209000000159,"failureMessages":[],"location":{"line":473,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should match governance indicators in INDICATOR_IDS","status":"passed","title":"should match governance indicators in INDICATOR_IDS","duration":1.1315089999998236,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WB_SOURCES"],"fullName":"WorldBankClient WB_SOURCES should have WDI source as 2","status":"passed","title":"should have WDI source as 2","duration":0.8523559999998724,"failureMessages":[],"location":{"line":493,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WB_SOURCES"],"fullName":"WorldBankClient WB_SOURCES should have WGI source as 75","status":"passed","title":"should have WGI source as 75","duration":0.9991410000000087,"failureMessages":[],"location":{"line":497,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI source parameter in URL"],"fullName":"WorldBankClient WGI source parameter in URL should add source=75 for WGI indicators","status":"passed","title":"should add source=75 for WGI indicators","duration":1.0981259999998656,"failureMessages":[],"location":{"line":503,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI source parameter in URL"],"fullName":"WorldBankClient WGI source parameter in URL should NOT add source parameter for WDI indicators","status":"passed","title":"should NOT add source parameter for WDI indicators","duration":1.0102810000000773,"failureMessages":[],"location":{"line":513,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getDefaultWorldBankClient"],"fullName":"WorldBankClient getDefaultWorldBankClient should return a singleton instance","status":"passed","title":"should return a singleton instance","duration":0.9003459999998995,"failureMessages":[],"location":{"line":525,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getDefaultWorldBankClient"],"fullName":"WorldBankClient getDefaultWorldBankClient should have default configuration","status":"passed","title":"should have default configuration","duration":0.8592289999999139,"failureMessages":[],"location":{"line":531,"column":5},"meta":{},"tags":[]}],"startTime":1787953683913,"endTime":1787953684969.8591,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/world-bank-client.test.ts"},{"assertionResults":[{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only should define at least 8 indicators","status":"passed","title":"should define at least 8 indicators","duration":3.7755989999999997,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only should have required fields for each indicator","status":"passed","title":"should have required fields for each indicator","duration":11.793150999999966,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.MKTP.KD.ZG\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.MKTP.KD.ZG\" because economic context routes through IMF","duration":0.656819999999982,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.MKTP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.MKTP.CD\" because economic context routes through IMF","duration":0.3772870000000239,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.PCAP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.PCAP.CD\" because economic context routes through IMF","duration":0.5584759999999847,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GNP.MKTP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GNP.MKTP.CD\" because economic context routes through IMF","duration":0.3920840000000112,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GNP.PCAP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GNP.PCAP.CD\" because economic context routes through IMF","duration":0.48194200000000365,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FP.CPI.TOTL.ZG\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FP.CPI.TOTL.ZG\" because economic context routes through IMF","duration":0.35533500000002505,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FP.CPI.TOTL\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FP.CPI.TOTL\" because economic context routes through IMF","duration":0.5191020000000321,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"SL.UEM.TOTL.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"SL.UEM.TOTL.ZS\" because economic context routes through IMF","duration":0.3743610000000217,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"SL.TLF.CACT.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"SL.TLF.CACT.ZS\" because economic context routes through IMF","duration":0.4190240000000358,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.XPN.TOTL.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.XPN.TOTL.GD.ZS\" because economic context routes through IMF","duration":0.35330099999998765,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.REV.XGRT.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.REV.XGRT.GD.ZS\" because economic context routes through IMF","duration":0.32436799999999266,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.DOD.TOTL.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.DOD.TOTL.GD.ZS\" because economic context routes through IMF","duration":0.4722840000000019,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"BN.CAB.XOKA.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"BN.CAB.XOKA.GD.ZS\" because economic context routes through IMF","duration":0.35246000000000777,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"BN.KLT.DINV.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"BN.KLT.DINV.CD\" because economic context routes through IMF","duration":0.4005700000000161,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NE.EXP.GNFS.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NE.EXP.GNFS.ZS\" because economic context routes through IMF","duration":0.3380939999999555,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NE.IMP.GNFS.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NE.IMP.GNFS.ZS\" because economic context routes through IMF","duration":0.3786190000000147,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"TX.VAL.MRCH.CD.WT\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"TX.VAL.MRCH.CD.WT\" because economic context routes through IMF","duration":0.3784379999999601,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FR.INR.RINR\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FR.INR.RINR\" because economic context routes through IMF","duration":0.37654500000002145,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FR.INR.LEND\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FR.INR.LEND\" because economic context routes through IMF","duration":0.40990799999997307,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include military expenditure (defence historicals — non-economic residue)","status":"passed","title":"must include military expenditure (defence historicals — non-economic residue)","duration":1.5688580000000343,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include CO₂ emissions (environment residue)","status":"passed","title":"must include CO₂ emissions (environment residue)","duration":0.8228200000000356,"failureMessages":[],"location":{"line":90,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include WGI governance indicators (residue)","status":"passed","title":"must include WGI governance indicators (residue)","duration":0.802643000000046,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must map every indicator to a valid Riksdag committee","status":"passed","title":"must map every indicator to a valid Riksdag committee","duration":5.68397200000004,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have all 14 supported languages","status":"passed","title":"should have all 14 supported languages","duration":1.3072879999999714,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have all 5 section headings per language","status":"passed","title":"should have all 5 section headings per language","duration":1.082407000000046,"failureMessages":[],"location":{"line":128,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have non-empty strings for all headings","status":"passed","title":"should have non-empty strings for all headings","duration":2.427886000000001,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have correct English headings","status":"passed","title":"should have correct English headings","duration":0.5602989999999863,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have correct Swedish headings","status":"passed","title":"should have correct Swedish headings","duration":0.5734630000000038,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","NORDIC_COMPARISON"],"fullName":"world-bank-context NORDIC_COMPARISON should include Sweden and 4 comparison countries","status":"passed","title":"should include Sweden and 4 comparison countries","duration":1.5170309999999745,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","NORDIC_COMPARISON"],"fullName":"world-bank-context NORDIC_COMPARISON should have country names for all countries","status":"passed","title":"should have country names for all countries","duration":0.6488650000000007,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should return correct English heading","status":"passed","title":"should return correct English heading","duration":0.5057369999999537,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should return correct Swedish heading","status":"passed","title":"should return correct Swedish heading","duration":0.3923449999999775,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should fallback to English for unsupported language","status":"passed","title":"should fallback to English for unsupported language","duration":0.39031099999999697,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should fallback to English for null language","status":"passed","title":"should fallback to English for null language","duration":0.443300000000022,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should handle all 14 languages","status":"passed","title":"should handle all 14 languages","duration":0.7204790000000116,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","duration":1.2477859999999623,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","duration":0.7204690000000369,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","duration":0.6528319999999894,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","duration":0.6972350000000347,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","duration":0.7238360000000057,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","duration":0.6592640000000074,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FP.CPI.TOTL\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FP.CPI.TOTL\" (IMF-routed)","duration":0.8462139999999749,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","duration":0.7218519999999558,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","duration":0.718213999999989,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","duration":0.6877179999999612,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","duration":0.9005860000000325,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","duration":0.7893169999999827,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","duration":0.7353269999999839,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","duration":0.7351170000000025,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","duration":0.7525290000000382,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","duration":0.8407240000000229,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","duration":0.8142739999999549,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FR.INR.RINR\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FR.INR.RINR\" (IMF-routed)","duration":0.8045460000000162,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FR.INR.LEND\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FR.INR.LEND\" (IMF-routed)","duration":0.8485089999999786,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must find defence indicators for NATO queries (defence historicals — non-economic residue)","status":"passed","title":"must find defence indicators for NATO queries (defence historicals — non-economic residue)","duration":0.7479910000000132,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must find climate indicators (environment residue)","status":"passed","title":"must find climate indicators (environment residue)","duration":0.9680619999999749,"failureMessages":[],"location":{"line":231,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return an array (never undefined) for any committee query","status":"passed","title":"must return an array (never undefined) for any committee query","duration":1.1793279999999982,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return empty for unrelated queries","status":"passed","title":"must return empty for unrelated queries","duration":0.7163210000000504,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return empty for empty / whitespace queries","status":"passed","title":"must return empty for empty / whitespace queries","duration":0.7676379999999767,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must be case-insensitive","status":"passed","title":"must be case-insensitive","duration":0.7224420000000009,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries must return queries for all configured indicators","status":"passed","title":"must return queries for all configured indicators","duration":0.7982749999999896,"failureMessages":[],"location":{"line":257,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries must use SWE country code for all queries","status":"passed","title":"must use SWE country code for all queries","duration":1.7319630000000075,"failureMessages":[],"location":{"line":262,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","duration":0.7989960000000451,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","duration":0.8320180000000619,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","duration":0.9461509999999862,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","duration":0.829091999999946,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","duration":0.8700390000000198,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","duration":0.8444610000000239,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FP.CPI.TOTL\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FP.CPI.TOTL\" (IMF-routed)","duration":0.9360530000000153,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","duration":0.9498780000000124,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","duration":0.9731820000000653,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","duration":0.990224000000012,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","duration":1.174227999999971,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","duration":1.029728000000091,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","duration":2.0371939999999995,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","duration":0.8933329999999842,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","duration":1.061868000000004,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","duration":1.040789000000018,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","duration":0.9594559999999319,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FR.INR.RINR\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FR.INR.RINR\" (IMF-routed)","duration":0.9731520000000273,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FR.INR.LEND\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FR.INR.LEND\" (IMF-routed)","duration":1.172354999999925,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect GDP / unemployment / inflation in English","status":"passed","title":"must detect GDP / unemployment / inflation in English","duration":1.8837670000000344,"failureMessages":[],"location":{"line":278,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect IMF as the primary economic data source","status":"passed","title":"must detect IMF as the primary economic data source","duration":1.2098949999999604,"failureMessages":[],"location":{"line":284,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect canonical IMF citation strings (DATABASE:INDICATOR_ID)","status":"passed","title":"must detect canonical IMF citation strings (DATABASE:INDICATOR_ID)","duration":1.7913029999999708,"failureMessages":[],"location":{"line":289,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect IMF projection vintage tags","status":"passed","title":"must detect IMF projection vintage tags","duration":1.2184710000000223,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect Swedish economic terms","status":"passed","title":"must detect Swedish economic terms","duration":1.1818630000000212,"failureMessages":[],"location":{"line":306,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect non-economic WB residue indicator IDs (defence, environment, governance)","status":"passed","title":"must detect non-economic WB residue indicator IDs (defence, environment, governance)","duration":1.1285930000000235,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must return false for content without economic context","status":"passed","title":"must return false for content without economic context","duration":1.5357460000000174,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage WORLD_BANK_INDICATORS is a non-empty array (inventory loaded successfully)","status":"passed","title":"WORLD_BANK_INDICATORS is a non-empty array (inventory loaded successfully)","duration":1.6509020000000874,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getSwedishIndicatorQueries returns a non-empty array with countryCode and indicatorId","status":"passed","title":"getSwedishIndicatorQueries returns a non-empty array with countryCode and indicatorId","duration":5.789711000000011,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage findRelevantIndicators matches by committee abbreviation (case-insensitive)","status":"passed","title":"findRelevantIndicators matches by committee abbreviation (case-insensitive)","duration":2.6178820000000087,"failureMessages":[],"location":{"line":351,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getEconomicHeading returns undefined for an unknown section key","status":"passed","title":"getEconomicHeading returns undefined for an unknown section key","duration":2.0176380000000336,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getEconomicHeading returns all 5 sections for every supported language","status":"passed","title":"getEconomicHeading returns all 5 sections for every supported language","duration":4.53244600000005,"failureMessages":[],"location":{"line":365,"column":3},"meta":{},"tags":[]}],"startTime":1787953786279,"endTime":1787953786394.5325,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/world-bank-context.test.ts"},{"assertionResults":[{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory defines exactly 23 required artifacts","status":"passed","title":"defines exactly 23 required artifacts","duration":5.405281000000059,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family A has 9 artifacts","status":"passed","title":"Family A has 9 artifacts","duration":1.0946489999998903,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family B has 2 artifacts","status":"passed","title":"Family B has 2 artifacts","duration":0.7374509999999646,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family C has 5 artifacts","status":"passed","title":"Family C has 5 artifacts","duration":0.7362590000000182,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family D has 7 artifacts","status":"passed","title":"Family D has 7 artifacts","duration":0.8112390000000005,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory all artifact filenames end with .md","status":"passed","title":"all artifact filenames end with .md","duration":1.599544999999921,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory REQUIRED_ARTIFACT_FILENAMES matches ALL_REQUIRED_ARTIFACTS count","status":"passed","title":"REQUIRED_ARTIFACT_FILENAMES matches ALL_REQUIRED_ARTIFACTS count","duration":0.8262470000000803,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory MERMAID_REQUIRED_ARTIFACTS is a subset of all artifacts","status":"passed","title":"MERMAID_REQUIRED_ARTIFACTS is a subset of all artifacts","duration":1.864661999999953,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory PASS2_REQUIRED_ARTIFACTS excludes data-download-manifest.md","status":"passed","title":"PASS2_REQUIRED_ARTIFACTS excludes data-download-manifest.md","duration":0.818012000000067,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory STUB_PLACEHOLDERS contains expected markers","status":"passed","title":"STUB_PLACEHOLDERS contains expected markers","duration":0.7645819999999048,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory RECOGNISED_AGENCIES contains known Swedish agencies","status":"passed","title":"RECOGNISED_AGENCIES contains known Swedish agencies","duration":0.9655579999999873,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory EVIDENCE_URL_HOSTS covers all required primary sources","status":"passed","title":"EVIDENCE_URL_HOSTS covers all required primary sources","duration":0.6758549999999559,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory DOK_ID_PATTERN matches valid Riksdag document IDs","status":"passed","title":"DOK_ID_PATTERN matches valid Riksdag document IDs","duration":0.7720359999999573,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory EVIDENCE_PATTERN matches dok_ids and URL hosts","status":"passed","title":"EVIDENCE_PATTERN matches dok_ids and URL hosts","duration":0.8520759999998972,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) returns passed=true for a fully seeded analysis directory","status":"passed","title":"returns passed=true for a fully seeded analysis directory","duration":26.493137000000047,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) returns passed=false and aggregates check failures for an empty directory","status":"passed","title":"returns passed=false and aggregates check failures for an empty directory","duration":1.6016889999999648,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) reports the dok_id that lacks per-document coverage","status":"passed","title":"reports the dok_id that lacks per-document coverage","duration":12.802580999999918,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953868266,"endTime":1787953868325.8025,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/analysis-gate-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting passes through a simple field","status":"passed","title":"passes through a simple field","duration":3.6739600000000223,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing commas","status":"passed","title":"quotes fields containing commas","duration":0.5773909999999773,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing double quotes and doubles them","status":"passed","title":"quotes fields containing double quotes and doubles them","duration":0.43709799999999177,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing CR or LF","status":"passed","title":"quotes fields containing CR or LF","duration":0.41849399999995285,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting treats null-ish input as empty string","status":"passed","title":"treats null-ish input as empty string","duration":0.5861170000000016,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting serialiseRow emits columns in CSV_COLUMNS order","status":"passed","title":"serialiseRow emits columns in CSV_COLUMNS order","duration":0.5096749999999588,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting CSV_COLUMNS matches the issue spec","status":"passed","title":"CSV_COLUMNS matches the issue spec","duration":1.4093900000000303,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport emits one row per (tier, violation) pair","status":"passed","title":"emits one row per (tier, violation) pair","duration":1.7428939999999784,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport emits one per-tier row with blank violation fields when contract is green","status":"passed","title":"emits one per-tier row with blank violation fields when contract is green","duration":0.8980910000000222,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport emits a header-only file when rows are empty","status":"passed","title":"writeReport emits a header-only file when rows are empty","duration":0.9807159999999726,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport creates missing parent directories","status":"passed","title":"writeReport creates missing parent directories","duration":0.9302420000000211,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport round-trips a non-trivial row set","status":"passed","title":"writeReport round-trips a non-trivial row set","duration":0.7628090000000043,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags defaults to --dry-run mode","status":"passed","title":"defaults to --dry-run mode","duration":0.6563290000000279,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags recognises --check","status":"passed","title":"recognises --check","duration":0.4098170000000323,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags recognises --apply","status":"passed","title":"recognises --apply","duration":0.4572459999999978,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --tier=A","status":"passed","title":"parses --tier=A","duration":0.44517300000001114,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --tier=A,B,C as a list","status":"passed","title":"parses --tier=A,B,C as a list","duration":0.5462830000000167,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags treats --tier=all as null (all tiers)","status":"passed","title":"treats --tier=all as null (all tiers)","duration":0.4337019999999825,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --lang=sv,no","status":"passed","title":"parses --lang=sv,no","duration":0.6128080000000296,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags treats empty --lang= as \"all languages\" (langs=null)","status":"passed","title":"treats empty --lang= as \"all languages\" (langs=null)","duration":0.47216500000001815,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --date-from / --date-to","status":"passed","title":"parses --date-from / --date-to","duration":0.6161240000000134,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --output","status":"passed","title":"parses --output","duration":0.4401540000000068,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --news-dir","status":"passed","title":"parses --news-dir","duration":0.46439000000003716,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --quiet","status":"passed","title":"parses --quiet","duration":0.43455399999999145,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags throws a typed CLI usage error instead of exiting for bad flags","status":"passed","title":"throws a typed CLI usage error instead of exiting for bad flags","duration":0.7808519999999817,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags throws for conflicting mode flags (--check + --dry-run, --apply + --check)","status":"passed","title":"throws for conflicting mode flags (--check + --dry-run, --apply + --check)","duration":1.394221000000016,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags main maps CLI usage errors to exit code 2","status":"passed","title":"main maps CLI usage errors to exit code 2","duration":1.553309000000013,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end listArticleFiles returns every .html file sorted","status":"passed","title":"listArticleFiles returns every .html file sorted","duration":1.1650909999999612,"failureMessages":[],"location":{"line":281,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end listArticleFiles skips news/index*.html","status":"passed","title":"listArticleFiles skips news/index*.html","duration":1.645511000000056,"failureMessages":[],"location":{"line":288,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --dry-run writes a CSV and exits 0","status":"passed","title":"--dry-run writes a CSV and exits 0","duration":4.6576820000000225,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --check exits non-zero when the synthetic articles violate the contract","status":"passed","title":"--check exits non-zero when the synthetic articles violate the contract","duration":1.7787809999999808,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --apply exits with CLI-misuse code 2","status":"passed","title":"--apply exits with CLI-misuse code 2","duration":1.1260480000000257,"failureMessages":[],"location":{"line":309,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --lang filter restricts scanned rows","status":"passed","title":"--lang filter restricts scanned rows","duration":1.2870399999999904,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --tier=B filter restricts to Tier B only","status":"passed","title":"--tier=B filter restricts to Tier B only","duration":1.6101150000000075,"failureMessages":[],"location":{"line":321,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --tier=C summary counts reflect emitted tiers, not pre-filter classification","status":"passed","title":"--tier=C summary counts reflect emitted tiers, not pre-filter classification","duration":1.3862859999999841,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --date-from / --date-to restrict by ISO date","status":"passed","title":"--date-from / --date-to restrict by ISO date","duration":1.2842050000000427,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]}],"startTime":1787953807853,"endTime":1787953807892.2842,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename parses a canonical date-slug-lang filename","status":"passed","title":"parses a canonical date-slug-lang filename","duration":3.992385000000013,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename parses a legacy multi-segment slug","status":"passed","title":"parses a legacy multi-segment slug","duration":0.6085290000000327,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename handles absolute and relative paths equivalently","status":"passed","title":"handles absolute and relative paths equivalently","duration":0.5543379999999729,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename returns nulls for unparseable filenames","status":"passed","title":"returns nulls for unparseable filenames","duration":0.3963929999999891,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename lower-cases the language tag","status":"passed","title":"lower-cases the language tag","duration":0.43745899999998983,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment findAnalysisSource finds an executive-brief on disk","status":"passed","title":"findAnalysisSource finds an executive-brief on disk","duration":1.2779320000000212,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment findAnalysisSource returns null for unknown date/slug","status":"passed","title":"findAnalysisSource returns null for unknown date/slug","duration":0.9052449999999794,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier A — article with an analysis source","status":"passed","title":"Tier A — article with an analysis source","duration":1.8783369999999877,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier B — article without an analysis source","status":"passed","title":"Tier B — article without an analysis source","duration":1.1620060000000194,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C — non-EN article with a below-floor description","status":"passed","title":"Tier C — non-EN article with a below-floor description","duration":1.5364170000000286,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C — RTL article with above-ceiling title","status":"passed","title":"Tier C — RTL article with above-ceiling title","duration":1.7631809999999746,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C is not assigned to EN articles even with below-floor description","status":"passed","title":"Tier C is not assigned to EN articles even with below-floor description","duration":0.9091720000000123,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment multi-tier — Tier A + Tier C for a non-EN article with source + short description","status":"passed","title":"multi-tier — Tier A + Tier C for a non-EN article with source + short description","duration":0.9285189999999943,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment every reason is set when its tier is assigned","status":"passed","title":"every reason is set when its tier is assigned","duration":0.9367029999999659,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment isKnownLang accepts all 14 contract languages and the BCP-47 `nb` alias","status":"passed","title":"isKnownLang accepts all 14 contract languages and the BCP-47 `nb` alias","duration":0.9081499999999778,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment isKnownLang rejects an unknown language","status":"passed","title":"isKnownLang rejects an unknown language","duration":0.6524709999999914,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment classifier test exports parseArticleFilename / findAnalysisSource / isKnownLang","status":"passed","title":"classifier test exports parseArticleFilename / findAnalysisSource / isKnownLang","duration":0.7120739999999728,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]}],"startTime":1787953840554,"endTime":1787953840574.7122,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/walker.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs parses --from and --to flags","status":"passed","title":"parses --from and --to flags","duration":3.8889819999999986,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs sets persist=true when --persist flag is present","status":"passed","title":"sets persist=true when --persist flag is present","duration":0.6080680000000029,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when --from is missing","status":"passed","title":"throws when --from is missing","duration":1.2976199999999949,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when --to is missing","status":"passed","title":"throws when --to is missing","duration":0.5126390000000356,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when date format is invalid","status":"passed","title":"throws when date format is invalid","duration":0.5229190000000017,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs accepts --tom as an alias for --to (Swedish, used in repo docs)","status":"passed","title":"accepts --tom as an alias for --to (Swedish, used in repo docs)","duration":0.5118689999999901,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs prefers --to over --tom when both are provided","status":"passed","title":"prefers --to over --tom when both are provided","duration":0.5253739999999993,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws CliArgsError (typed) for invalid arguments","status":"passed","title":"throws CliArgsError (typed) for invalid arguments","duration":0.5577940000000012,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a successful MCP primary manifest","status":"passed","title":"formats a successful MCP primary manifest","duration":0.9266149999999698,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a web fallback manifest with primary error","status":"passed","title":"formats a web fallback manifest with primary error","duration":0.6032289999999989,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a none (both failed) manifest","status":"passed","title":"formats a none (both failed) manifest","duration":0.41505699999999024,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]}],"startTime":1787953911778,"endTime":1787953911789.415,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/manifest.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback succeeds via MCP primary path and records manifest correctly","status":"passed","title":"succeeds via MCP primary path and records manifest correctly","duration":6.695014999999955,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback triggers web fallback when MCP returns HTML error page","status":"passed","title":"triggers web fallback when MCP returns HTML error page","duration":3.1564500000000066,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback triggers web fallback when MCP returns the degraded-kalender sentinel","status":"passed","title":"triggers web fallback when MCP returns the degraded-kalender sentinel","duration":1.2782440000000292,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback retries MCP on network error before falling back","status":"passed","title":"retries MCP on network error before falling back","duration":1.1971919999999727,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback returns path=none when both paths fail after retry exhaustion","status":"passed","title":"returns path=none when both paths fail after retry exhaustion","duration":1.540264000000036,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback manifest includes correct `date` and `dateTo` fields","status":"passed","title":"manifest includes correct `date` and `dateTo` fields","duration":0.6193499999999972,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback does not sleep before the first MCP attempt","status":"passed","title":"does not sleep before the first MCP attempt","duration":0.638526000000013,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback does not retry HTML errors (immediate fallback)","status":"passed","title":"does not retry HTML errors (immediate fallback)","duration":0.9337090000000217,"failureMessages":[],"location":{"line":244,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback – MCP succeeds on retry"],"fullName":"fetchCalendarWithFallback – MCP succeeds on retry succeeds on the second MCP attempt without triggering fallback","status":"passed","title":"succeeds on the second MCP attempt without triggering fallback","duration":0.9068780000000061,"failureMessages":[],"location":{"line":271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarEvent shape"],"fullName":"CalendarEvent shape MCP-normalized events have all required fields","status":"passed","title":"MCP-normalized events have all required fields","duration":0.5961460000000329,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarEvent shape"],"fullName":"CalendarEvent shape web-fallback events have all required fields","status":"passed","title":"web-fallback events have all required fields","duration":0.550360000000012,"failureMessages":[],"location":{"line":313,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson creates the output directory and writes a JSON file","status":"passed","title":"creates the output directory and writes a JSON file","duration":1.062419000000034,"failureMessages":[],"location":{"line":347,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson written file contains correct schema, manifest, and events","status":"passed","title":"written file contains correct schema, manifest, and events","duration":0.9987100000000169,"failureMessages":[],"location":{"line":375,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson returns the output file path","status":"passed","title":"returns the output file path","duration":0.6586130000000026,"failureMessages":[],"location":{"line":407,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson uses {from}_{dateTo}.json when range spans multiple days","status":"passed","title":"uses {from}_{dateTo}.json when range spans multiple days","duration":0.666136999999992,"failureMessages":[],"location":{"line":418,"column":3},"meta":{},"tags":[]}],"startTime":1787953786873,"endTime":1787953786894.666,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/orchestrator-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should return result object with success status","status":"passed","title":"should return result object with success status","duration":3.6232239999999365,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate indexes successfully","status":"passed","title":"should generate indexes successfully","duration":0.6600760000001173,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate index files for all 14 languages","status":"passed","title":"should generate index files for all 14 languages","duration":0.659523999999692,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate index files with correct lang attribute","status":"passed","title":"should generate index files with correct lang attribute","duration":4.791992000000391,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include domain-specific keywords in generated indexes","status":"passed","title":"should include domain-specific keywords in generated indexes","duration":0.7499639999996361,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include translated Schema.org WebSite description per language","status":"passed","title":"should include translated Schema.org WebSite description per language","duration":0.5543080000006739,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include publisher and about in Schema.org ItemList articles","status":"passed","title":"should include publisher and about in Schema.org ItemList articles","duration":0.49464699999953154,"failureMessages":[],"location":{"line":135,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should set dir=\"rtl\" for Arabic and Hebrew indexes","status":"passed","title":"should set dir=\"rtl\" for Arabic and Hebrew indexes","duration":0.38803699999971286,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include search input with id and aria-label","status":"passed","title":"should include search input with id and aria-label","duration":0.751246999999239,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include load-more button and article counter","status":"passed","title":"should include load-more button and article counter","duration":1.1980130000001736,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include PAGE_SIZE and pagination logic","status":"passed","title":"should include PAGE_SIZE and pagination logic","duration":1.1364270000003671,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include readURLParams and updateURL for URL state management","status":"passed","title":"should include readURLParams and updateURL for URL state management","duration":0.9263639999999214,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should not include conflicting DOMContentLoaded content loader","status":"passed","title":"should not include conflicting DOMContentLoaded content loader","duration":0.7215809999997873,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include esc() helper and apply it to article fields in buildArticleCard","status":"passed","title":"should include esc() helper and apply it to article fields in buildArticleCard","duration":1.6802959999995437,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include AI-Disrupted News Generation section","status":"passed","title":"should include AI-Disrupted News Generation section","duration":0.878523999999743,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should localise AI newsroom section for non-English languages","status":"passed","title":"should localise AI newsroom section for non-English languages","duration":0.8999050000002171,"failureMessages":[],"location":{"line":209,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include app version marker","status":"passed","title":"should include app version marker","duration":0.686094000000594,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the unified `rm-site-footer` 3-column trust block","status":"passed","title":"should include the unified `rm-site-footer` 3-column trust block","duration":0.6665379999994911,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should localise footer brand description for non-English languages","status":"passed","title":"should localise footer brand description for non-English languages","duration":0.5453009999991991,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"should include the unified `rm-site-header` chrome with theme toggle","duration":0.6270850000000792,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the anti-flash inline theme bootstrap in <head>","status":"passed","title":"should include the anti-flash inline theme bootstrap in <head>","duration":0.4666639999995823,"failureMessages":[],"location":{"line":249,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should emit Organization + WebSite + ItemList + BreadcrumbList JSON-LD","status":"passed","title":"should emit Organization + WebSite + ItemList + BreadcrumbList JSON-LD","duration":0.48430699999971694,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]}],"startTime":1787953820377,"endTime":1787953820400.4844,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/orchestrator-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["getDefaultImfClient"],"fullName":"getDefaultImfClient returns the same instance across calls (singleton)","status":"passed","title":"returns the same instance across calls (singleton)","duration":3.9233770000000163,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.listDatamapperIndicators"],"fullName":"ImfClient.listDatamapperIndicators hits the /indicators endpoint and parses the envelope","status":"passed","title":"hits the /indicators endpoint and parses the envelope","duration":2.213434999999947,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch issues one Datamapper call per indicator for the same country","status":"passed","title":"issues one Datamapper call per indicator for the same country","duration":2.4984179999999583,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch isolates individual failures — a flaky indicator maps to []","status":"passed","title":"isolates individual failures — a flaky indicator maps to []","duration":1.7857239999999592,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch emits a diagnostic event when one indicator is fail-softed","status":"passed","title":"emits a diagnostic event when one indicator is fail-softed","duration":3.2738109999999665,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch rethrows non-retryable indicator HTTP errors instead of fail-softing them","status":"passed","title":"rethrows non-retryable indicator HTTP errors instead of fail-softing them","duration":2.6419070000000033,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch fail-softs fetch network TypeErrors but not programmer TypeErrors","status":"passed","title":"fail-softs fetch network TypeErrors but not programmer TypeErrors","duration":1.0770169999999553,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch validates years up-front instead of swallowing caller errors","status":"passed","title":"validates years up-front instead of swallowing caller errors","duration":0.7105399999999804,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator prefers the latest non-projection value when available","status":"passed","title":"prefers the latest non-projection value when available","duration":1.0649339999999938,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator falls back to the earliest projection when only projections are present","status":"passed","title":"falls back to the earliest projection when only projections are present","duration":0.7564869999999928,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator returns null when the series is empty","status":"passed","title":"returns null when the series is empty","duration":0.6689030000000002,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.compareCountriesWeo"],"fullName":"ImfClient.compareCountriesWeo returns one entry per country, null on failure","status":"passed","title":"returns one entry per country, null on failure","duration":0.9508400000000279,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]}],"startTime":1787953834399,"endTime":1787953834420.951,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/client-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF refactor: bounded-context invariants","COFOG codes (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants COFOG codes (issue #2580 acceptance criterion) exposes only the canonical GF##_T form (legacy G02/G07/G09/G10 retired 2026-05)","status":"passed","title":"exposes only the canonical GF##_T form (legacy G02/G07/G09/G10 retired 2026-05)","duration":5.502973999999995,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Retry policy (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Retry policy (issue #2580 acceptance criterion) preserves the 30_000 ms RETRY_AFTER_CAP_MS cap","status":"passed","title":"preserves the 30_000 ms RETRY_AFTER_CAP_MS cap","duration":0.5280089999999973,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","WEO vintage default (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants WEO vintage default (issue #2580 acceptance criterion) keeps DEFAULT_WEO_VINTAGE at WEO-2026-04","status":"passed","title":"keeps DEFAULT_WEO_VINTAGE at WEO-2026-04","duration":0.44548400000002175,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","IMF SDMX subscription key auth boundary"],"fullName":"IMF refactor: bounded-context invariants IMF SDMX subscription key auth boundary is the sole reader of process.env IMF_SDMX_SUBSCRIPTION_KEY","status":"passed","title":"is the sole reader of process.env IMF_SDMX_SUBSCRIPTION_KEY","duration":1.7382450000000063,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps every source file under 300 lines","status":"passed","title":"keeps every source file under 300 lines","duration":1.301507000000015,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps imf-client.ts + imf-fetch.ts shims under 80 lines each","status":"passed","title":"keeps imf-client.ts + imf-fetch.ts shims under 80 lines each","duration":0.9751860000000079,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps each subcommand entry under 150 lines","status":"passed","title":"keeps each subcommand entry under 150 lines","duration":0.7745099999999638,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]}],"startTime":1787953895945,"endTime":1787953895956.7744,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/refactor-invariants.test.ts"},{"assertionResults":[{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats a fetchedAt date older than 6 months as stale","status":"passed","title":"treats a fetchedAt date older than 6 months as stale","duration":3.988828999999953,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats a recent fetchedAt date as fresh","status":"passed","title":"treats a recent fetchedAt date as fresh","duration":0.6287379999999985,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats invalid date strings as stale (conservative)","status":"passed","title":"treats invalid date strings as stale (conservative)","duration":0.5313049999999748,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadCachedIMFData"],"fullName":"loadCachedIMFData returns null when no cache file exists for the indicator/country pair","status":"passed","title":"returns null when no cache file exists for the indicator/country pair","duration":0.6458700000000022,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildFallbackPayload"],"fullName":"buildFallbackPayload annotates the cached payload with fallback metadata + transport=cache","status":"passed","title":"annotates the cached payload with fallback metadata + transport=cache","duration":1.259428000000014,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildFallbackPayload"],"fullName":"buildFallbackPayload uses the \">6 month vintage\" wording when stale=true (renderer key for yellow / red badge)","status":"passed","title":"uses the \">6 month vintage\" wording when stale=true (renderer key for yellow / red badge)","duration":0.588401000000033,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]}],"startTime":1787953921614,"endTime":1787953921622.5884,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/cache.test.ts"},{"assertionResults":[{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError ImfWeoSdmxOnlyError is always permanent","status":"passed","title":"ImfWeoSdmxOnlyError is always permanent","duration":4.005179999999996,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError empty-Datamapper sentinel is transient (Datamapper occasionally lags Fund publishing)","status":"passed","title":"empty-Datamapper sentinel is transient (Datamapper occasionally lags Fund publishing)","duration":0.5776109999999903,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError respects an explicit retryable=true / false flag (e.g. ImfHttpError)","status":"passed","title":"respects an explicit retryable=true / false flag (e.g. ImfHttpError)","duration":0.5858569999999759,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError AbortError is transient (timeout — worth one more shot)","status":"passed","title":"AbortError is transient (timeout — worth one more shot)","duration":0.384490000000028,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError classifies by HTTP status when no flag is present (429/5xx transient, 4xx permanent)","status":"passed","title":"classifies by HTTP status when no flag is present (429/5xx transient, 4xx permanent)","duration":0.5167169999999714,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError exports the sentinel code string used to tag empty-Datamapper errors","status":"passed","title":"exports the sentinel code string used to tag empty-Datamapper errors","duration":0.47470899999996163,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953926097,"endTime":1787953926103.4746,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/classifier.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should create client with default configuration","status":"passed","title":"should create client with default configuration","duration":4.180777999999975,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept custom configuration","status":"passed","title":"should accept custom configuration","duration":0.6602659999999787,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept string URL for backwards compatibility","status":"passed","title":"should accept string URL for backwards compatibility","duration":0.5459119999999871,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept serverUrl alias in config","status":"passed","title":"should accept serverUrl alias in config","duration":0.5492179999999962,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize request and error counts to zero","status":"passed","title":"should initialize request and error counts to zero","duration":0.6896820000000048,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept custom headers in config","status":"passed","title":"should accept custom headers in config","duration":1.2497699999999554,"failureMessages":[],"location":{"line":85,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize empty customHeaders when no headers provided","status":"passed","title":"should initialize empty customHeaders when no headers provided","duration":0.454921000000013,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize empty customHeaders for string URL config","status":"passed","title":"should initialize empty customHeaders for string URL config","duration":0.5142319999999927,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","sleep"],"fullName":"MCPClient — integration spine sleep should resolve after specified time","status":"passed","title":"should resolve after specified time","duration":50.439842,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport retries on transient network error then succeeds","status":"passed","title":"retries on transient network error then succeeds","duration":2.3960370000000353,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport does not retry on JSON-RPC error response","status":"passed","title":"does not retry on JSON-RPC error response","duration":2.7407719999999927,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport surfaces transport error via TRANSPORT_ERROR_RE-matchable message","status":"passed","title":"surfaces transport error via TRANSPORT_ERROR_RE-matchable message","duration":0.9255130000000236,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","statistics surface"],"fullName":"MCPClient — integration spine statistics surface exposes getStats/resetStats with the documented shape","status":"passed","title":"exposes getStats/resetStats with the documented shape","duration":1.0360000000000582,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke calendar.fetchCalendarEvents returns events array","status":"passed","title":"calendar.fetchCalendarEvents returns events array","duration":1.5458139999999503,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke reports.fetchPropositions returns array","status":"passed","title":"reports.fetchPropositions returns array","duration":0.8344919999999547,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke documents.searchDocuments returns array","status":"passed","title":"documents.searchDocuments returns array","duration":1.5097469999999475,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke speeches.searchSpeeches returns array","status":"passed","title":"speeches.searchSpeeches returns array","duration":0.9787329999999201,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke members.fetchMPs returns array","status":"passed","title":"members.fetchMPs returns array","duration":0.8995140000000674,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke votes.fetchVotingGroup returns array","status":"passed","title":"votes.fetchVotingGroup returns array","duration":0.8604509999998982,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]}],"startTime":1787953838688,"endTime":1787953838761.8604,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/client-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration writes every provider into a disjoint sub-tree under a shared dataRoot","status":"passed","title":"writes every provider into a disjoint sub-tree under a shared dataRoot","duration":8.246229999999969,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration every provider emits a sibling *.meta.json sidecar","status":"passed","title":"every provider emits a sibling *.meta.json sidecar","duration":2.3972089999999753,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration cross-write order does not corrupt later writes from a different provider","status":"passed","title":"cross-write order does not corrupt later writes from a different provider","duration":0.9506399999999644,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]}],"startTime":1787953867244,"endTime":1787953867255.9507,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/data-persistence-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["pdf-converter","isPdfToTextAvailable"],"fullName":"pdf-converter isPdfToTextAvailable should return a boolean","status":"passed","title":"should return a boolean","duration":8.766767000000016,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","isPdfToTextAvailable"],"fullName":"pdf-converter isPdfToTextAvailable should cache the result","status":"passed","title":"should cache the result","duration":3.5227160000000026,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should return empty string for empty input","status":"passed","title":"should return empty string for empty input","duration":0.685053000000039,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should convert ALL CAPS lines to headings","status":"passed","title":"should convert ALL CAPS lines to headings","duration":0.7514579999999569,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should preserve paragraph breaks","status":"passed","title":"should preserve paragraph breaks","duration":0.5188419999999496,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should not convert short ALL CAPS as headings","status":"passed","title":"should not convert short ALL CAPS as headings","duration":0.6961539999999786,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should handle Swedish characters in headings","status":"passed","title":"should handle Swedish characters in headings","duration":0.511146999999994,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should normalise excessive whitespace","status":"passed","title":"should normalise excessive whitespace","duration":0.5721919999999727,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should handle mixed content","status":"passed","title":"should handle mixed content","duration":0.5808170000000246,"failureMessages":[],"location":{"line":74,"column":5},"meta":{},"tags":[]}],"startTime":1787953916118,"endTime":1787953916135.5808,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/pdf-converter.test.ts"},{"assertionResults":[{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon quarter horizon = 4 scenarios","status":"passed","title":"quarter horizon = 4 scenarios","duration":3.571257000000003,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon year horizon = 4 scenarios + 5 wildcards = 9 leaves","status":"passed","title":"year horizon = 4 scenarios + 5 wildcards = 9 leaves","duration":0.48022900000000845,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon election-cycle scenario tree = 4 scenarios × 3 coalition branches = 12 leaves","status":"passed","title":"election-cycle scenario tree = 4 scenarios × 3 coalition branches = 12 leaves","duration":0.4141850000000318,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon election-cycle total branches = 12 scenario leaves + 5 wildcards = 17","status":"passed","title":"election-cycle total branches = 12 scenario leaves + 5 wildcards = 17","duration":0.3355280000000107,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon coalition branching factor (3) is the only multiplier that yields the 12-leaf cycle tree","status":"passed","title":"coalition branching factor (3) is the only multiplier that yields the 12-leaf cycle tree","duration":0.3592130000000111,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — long-horizon scenario coverage"],"fullName":"analysis/article-types.json — long-horizon scenario coverage every long-horizon-forecast entry declares scenarioHorizonYears","status":"passed","title":"every long-horizon-forecast entry declares scenarioHorizonYears","duration":0.6056940000000282,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — long-horizon scenario coverage"],"fullName":"analysis/article-types.json — long-horizon scenario coverage at least one article-type targets the election-cycle horizon (4+ years)","status":"passed","title":"at least one article-type targets the election-cycle horizon (4+ years)","duration":0.4244449999999915,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]}],"startTime":1787953900200,"endTime":1787953900206.6057,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/coalition-branches.test.ts"},{"assertionResults":[{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window prompt explicitly documents the ±30-day trigger window","status":"passed","title":"prompt explicitly documents the ±30-day trigger window","duration":3.7185530000000426,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window activation predicate uses 30 as the day-delta threshold","status":"passed","title":"activation predicate uses 30 as the day-delta threshold","duration":0.6766170000000216,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window prompt links the ±30-day window to the election anchor","status":"passed","title":"prompt links the ±30-day window to the election anchor","duration":0.6304310000000442,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T-30 → T-1 pre-election bridge","status":"passed","title":"prompt documents the T-30 → T-1 pre-election bridge","duration":0.4628270000000043,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T+1 → T+30 post-election bridge","status":"passed","title":"prompt documents the T+1 → T+30 post-election bridge","duration":0.5180599999999913,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T+31 → T+45 freeze period","status":"passed","title":"prompt documents the T+31 → T+45 freeze period","duration":0.47931699999998045,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt explicitly forbids time-budget anchor-skip reasons","status":"passed","title":"prompt explicitly forbids time-budget anchor-skip reasons","duration":0.5626829999999927,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry exposes the electionCycles block","status":"passed","title":"exposes the electionCycles block","duration":0.4182529999999929,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry exposes a `next` cycle with an ISO date start","status":"passed","title":"exposes a `next` cycle with an ISO date start","duration":0.5991909999999621,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry Swedish elections are quadrennial — current.start and next.start differ by ~4 years","status":"passed","title":"Swedish elections are quadrennial — current.start and next.start differ by ~4 years","duration":0.6792609999999968,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]}],"startTime":1787953899755,"endTime":1787953899764.6792,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/cycle-rollover.test.ts"},{"assertionResults":[{"ancestorTitles":["subtractDays"],"fullName":"subtractDays subtracts a single day across month boundary","status":"passed","title":"subtracts a single day across month boundary","duration":3.8690349999999967,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["subtractDays"],"fullName":"subtractDays subtracts multiple days across year boundary","status":"passed","title":"subtracts multiple days across year boundary","duration":0.5827320000000213,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["subtractDays"],"fullName":"subtractDays zero days is identity","status":"passed","title":"zero days is identity","duration":0.4923509999999851,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade VERY HIGH → HIGH","status":"passed","title":"VERY HIGH → HIGH","duration":0.40343500000000176,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade HIGH → MEDIUM","status":"passed","title":"HIGH → MEDIUM","duration":0.5003370000000018,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade MEDIUM → LOW","status":"passed","title":"MEDIUM → LOW","duration":0.5024809999999889,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade LOW → VERY LOW","status":"passed","title":"LOW → VERY LOW","duration":0.5828910000000178,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade VERY LOW stays at VERY LOW (floor)","status":"passed","title":"VERY LOW stays at VERY LOW (floor)","duration":0.39674300000001494,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade throws on unknown confidence value","status":"passed","title":"throws on unknown confidence value","duration":1.5881640000000061,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --from / --to","status":"passed","title":"parses --from / --to","duration":0.6941899999999919,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --date / --cycle","status":"passed","title":"parses --date / --cycle","duration":0.7201380000000199,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --dry-run flag","status":"passed","title":"parses --dry-run flag","duration":0.4520959999999832,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback default is 14","status":"passed","title":"--max-lookback default is 14","duration":0.445904999999982,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback overrides default","status":"passed","title":"--max-lookback overrides default","duration":0.5591469999999958,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback accepts zero-padded positive integers","status":"passed","title":"--max-lookback accepts zero-padded positive integers","duration":0.6097320000000082,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is missing","status":"passed","title":"--max-lookback throws when value is missing","duration":0.6572610000000054,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is non-numeric","status":"passed","title":"--max-lookback throws when value is non-numeric","duration":0.6264429999999948,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is zero","status":"passed","title":"--max-lookback throws when value is zero","duration":0.5110569999999939,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs returns CliArgs shape with required fields","status":"passed","title":"returns CliArgs shape with required fields","duration":0.5036730000000489,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward produces schema_version 1.0 output","status":"passed","title":"produces schema_version 1.0 output","duration":0.9557800000000043,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR confidence is degraded one level","status":"passed","title":"open PIR confidence is degraded one level","duration":0.7465379999999868,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR appends pir_id to existing inherits_from chain","status":"passed","title":"open PIR appends pir_id to existing inherits_from chain","duration":1.2160169999999653,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward answered PIR carried forward UNCHANGED preserves inherits_from history","status":"passed","title":"answered PIR carried forward UNCHANGED preserves inherits_from history","duration":0.7336840000000393,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR with VERY LOW stays at VERY LOW","status":"passed","title":"open PIR with VERY LOW stays at VERY LOW","duration":0.5171379999999886,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR drops answer_summary on roll-forward","status":"passed","title":"open PIR drops answer_summary on roll-forward","duration":0.5925299999999538,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from is a relative path when source is under repoRoot","status":"passed","title":"inherited_from is a relative path when source is under repoRoot","duration":0.4990149999999858,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from normalizes relative paths via path.relative semantics","status":"passed","title":"inherited_from normalizes relative paths via path.relative semantics","duration":0.6916749999999752,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from falls back to absolute path when source is outside repoRoot","status":"passed","title":"inherited_from falls back to absolute path when source is outside repoRoot","duration":0.5837030000000141,"failureMessages":[],"location":{"line":222,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward uses fixed generated_at from injected now()","status":"passed","title":"uses fixed generated_at from injected now()","duration":0.5566029999999955,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+72h' horizon (3-day lookback)","status":"passed","title":"subtractDays() supports the 'T+72h' horizon (3-day lookback)","duration":0.7599329999999895,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+7d' horizon (7-day lookback)","status":"passed","title":"subtractDays() supports the 'T+7d' horizon (7-day lookback)","duration":0.7623979999999619,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+30d' horizon (30-day lookback)","status":"passed","title":"subtractDays() supports the 'T+30d' horizon (30-day lookback)","duration":0.8333109999999806,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+90d' horizon (90-day lookback)","status":"passed","title":"subtractDays() supports the 'T+90d' horizon (90-day lookback)","duration":0.5303530000000478,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+365d' horizon (365-day lookback)","status":"passed","title":"subtractDays() supports the 'T+365d' horizon (365-day lookback)","duration":0.7081459999999993,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+1460d' horizon (1460-day lookback)","status":"passed","title":"subtractDays() supports the 'T+1460d' horizon (1460-day lookback)","duration":0.5747559999999794,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows the seven canonical horizons are distinct and monotonically increasing","status":"passed","title":"the seven canonical horizons are distinct and monotonically increasing","duration":0.6860550000000103,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]}],"startTime":1787953829306,"endTime":1787953829333.686,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/horizon-rollforward.test.ts"},{"assertionResults":[{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema file exists and is valid JSON","status":"passed","title":"schema file exists and is valid JSON","duration":3.793172000000027,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema uses JSON Schema 2020-12","status":"passed","title":"schema uses JSON Schema 2020-12","duration":0.7381020000000262,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema $id is scoped to riksdagsmonitor.com","status":"passed","title":"schema $id is scoped to riksdagsmonitor.com","duration":0.4421379999999999,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema requires mandatory top-level fields","status":"passed","title":"schema requires mandatory top-level fields","duration":1.3674009999999726,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema defines pir_id pattern","status":"passed","title":"schema defines pir_id pattern","duration":0.5743850000000066,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema lists all valid cycle types","status":"passed","title":"schema lists all valid cycle types","duration":1.0798209999999813,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json top-level and pirEntry both enforce additionalProperties: false","status":"passed","title":"top-level and pirEntry both enforce additionalProperties: false","duration":0.5296610000000328,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema enforces conditional answer_summary via if/then/else","status":"passed","title":"schema enforces conditional answer_summary via if/then/else","duration":0.7374909999999772,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema requires answer_summary to be non-empty when present","status":"passed","title":"schema requires answer_summary to be non-empty when present","duration":0.6214429999999993,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json subfolder description acknowledges schema cannot enforce equality with cycle","status":"passed","title":"subfolder description acknowledges schema cannot enforce equality with cycle","duration":0.46547099999997954,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource returns null when no source exists in lookback window","status":"passed","title":"returns null when no source exists in lookback window","duration":1.5767319999999927,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource finds nearest source within lookback","status":"passed","title":"finds nearest source within lookback","duration":0.887061000000017,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource respects maxLookback limit","status":"passed","title":"respects maxLookback limit","duration":1.0820560000000228,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain prints usage and exits 1 with no args","status":"passed","title":"prints usage and exits 1 with no args","duration":1.3389970000000062,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 when --from source not found","status":"passed","title":"exits 1 when --from source not found","duration":0.8181809999999814,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 when --to path cannot derive date/cycle","status":"passed","title":"exits 1 when --to path cannot derive date/cycle","duration":1.0255010000000198,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 with unknown cycle","status":"passed","title":"exits 1 with unknown cycle","duration":0.6792919999999754,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 with invalid --max-lookback","status":"passed","title":"exits 1 with invalid --max-lookback","duration":0.6981370000000311,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 2 when source JSON is malformed","status":"passed","title":"exits 2 when source JSON is malformed","duration":0.9656180000000063,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 2 when source fails strict validation","status":"passed","title":"exits 2 when source fails strict validation","duration":1.3385059999999953,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain writes target file successfully on happy path","status":"passed","title":"writes target file successfully on happy path","duration":2.001246999999978,"failureMessages":[],"location":{"line":254,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain --dry-run writes JSON to stdout and does not create file","status":"passed","title":"--dry-run writes JSON to stdout and does not create file","duration":1.03760299999999,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain creates target directory when missing","status":"passed","title":"creates target directory when missing","duration":1.1140459999999734,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain --date / --cycle resolves prior cycle within lookback window","status":"passed","title":"--date / --cycle resolves prior cycle within lookback window","duration":0.9990510000000086,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md references pir-status.json","status":"passed","title":"05-analysis-gate.md references pir-status.json","duration":0.5423749999999927,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md references pir-status.schema.json","status":"passed","title":"05-analysis-gate.md references pir-status.schema.json","duration":0.4404349999999795,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md enforces subfolder === cycle invariant","status":"passed","title":"05-analysis-gate.md enforces subfolder === cycle invariant","duration":0.5887029999999527,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md enforces conditional answer_summary","status":"passed","title":"05-analysis-gate.md enforces conditional answer_summary","duration":0.545501999999999,"failureMessages":[],"location":{"line":344,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md keeps PIR and supplementary checks sequential","status":"passed","title":"05-analysis-gate.md keeps PIR and supplementary checks sequential","duration":0.5623030000000426,"failureMessages":[],"location":{"line":347,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md references pir-status.json","status":"passed","title":"ai-driven-analysis-guide.md references pir-status.json","duration":0.5324769999999717,"failureMessages":[],"location":{"line":354,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md references roll-forward script","status":"passed","title":"ai-driven-analysis-guide.md references roll-forward script","duration":0.529892000000018,"failureMessages":[],"location":{"line":357,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md clarifies open vs preserved status semantics","status":"passed","title":"ai-driven-analysis-guide.md clarifies open vs preserved status semantics","duration":0.6293880000000058,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["module export sanity"],"fullName":"module export sanity CycleType values are usable in fixtures","status":"passed","title":"CycleType values are usable in fixtures","duration":0.9798350000000369,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]}],"startTime":1787953790470,"endTime":1787953790501.9797,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["validateSource"],"fullName":"validateSource accepts a valid fixture","status":"passed","title":"accepts a valid fixture","duration":4.235339999999951,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-objects","status":"passed","title":"rejects non-objects","duration":1.6840530000000058,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects missing schema_version","status":"passed","title":"rejects missing schema_version","duration":0.5812780000000544,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unsupported schema_version","status":"passed","title":"rejects unsupported schema_version","duration":0.5471049999999877,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-array pirs","status":"passed","title":"rejects non-array pirs","duration":0.6336660000000052,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects missing required field","status":"passed","title":"rejects missing required field","duration":0.6417110000000434,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level cycle","status":"passed","title":"rejects invalid top-level cycle","duration":0.6880779999999618,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level date format","status":"passed","title":"rejects invalid top-level date format","duration":0.4693189999999845,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects empty top-level subfolder","status":"passed","title":"rejects empty top-level subfolder","duration":0.809786000000031,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects top-level subfolder that does not equal cycle","status":"passed","title":"rejects top-level subfolder that does not equal cycle","duration":0.6237879999999905,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level generated_at date-time","status":"passed","title":"rejects invalid top-level generated_at date-time","duration":0.4818520000000035,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid inherited_from type","status":"passed","title":"rejects invalid inherited_from type","duration":0.50513600000005,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid pir_id pattern","status":"passed","title":"rejects invalid pir_id pattern","duration":0.44362100000000737,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects too-short statement","status":"passed","title":"rejects too-short statement","duration":0.5214359999999942,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unknown status enum","status":"passed","title":"rejects unknown status enum","duration":0.4628169999999727,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unknown confidence enum","status":"passed","title":"rejects unknown confidence enum","duration":0.5446499999999901,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects answered without answer_summary","status":"passed","title":"rejects answered without answer_summary","duration":0.46277700000001687,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-answered with answer_summary","status":"passed","title":"rejects non-answered with answer_summary","duration":0.4819919999999911,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-object pir entry","status":"passed","title":"rejects non-object pir entry","duration":0.4413069999999948,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]}],"startTime":1787953866356,"endTime":1787953866371.4414,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/status-classification.test.ts"},{"assertionResults":[{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports all artifacts missing when directory is empty","status":"passed","title":"reports all artifacts missing when directory is empty","duration":5.2462339999999585,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports success when all artifacts present","status":"passed","title":"reports success when all artifacts present","duration":2.235135000000014,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports specific missing artifact","status":"passed","title":"reports specific missing artifact","duration":1.7685020000000122,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports failure for zero-byte (empty) artifact","status":"passed","title":"reports failure for zero-byte (empty) artifact","duration":2.0106349999999793,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]}],"startTime":1787953924739,"endTime":1787953924751.0107,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/artifact-existence.test.ts"},{"assertionResults":[{"ancestorTitles":["checkCoalitionMathematics"],"fullName":"checkCoalitionMathematics passes with seat-count table","status":"passed","title":"passes with seat-count table","duration":5.598643000000038,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCoalitionMathematics"],"fullName":"checkCoalitionMathematics fails without vote-breakdown table","status":"passed","title":"fails without vote-breakdown table","duration":1.1268800000000283,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953936300,"endTime":1787953936306.127,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/coalition-mathematics.test.ts"},{"assertionResults":[{"ancestorTitles":["checkComparativeInternational"],"fullName":"checkComparativeInternational passes with comparator set declared","status":"passed","title":"passes with comparator set declared","duration":5.570601000000011,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkComparativeInternational"],"fullName":"checkComparativeInternational passes with 2+ comparator table rows","status":"passed","title":"passes with 2+ comparator table rows","duration":1.224142000000029,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953935441,"endTime":1787953935448.224,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/comparative-international.test.ts"},{"assertionResults":[{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate passes with 3+ hypotheses and 100% KJ coverage matrix","status":"passed","title":"passes with 3+ hypotheses and 100% KJ coverage matrix","duration":8.11606599999999,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate fails when KJ Coverage Matrix heading is missing","status":"passed","title":"fails when KJ Coverage Matrix heading is missing","duration":1.8201479999999606,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate fails when any KJ coverage row contains ❌","status":"passed","title":"fails when any KJ coverage row contains ❌","duration":0.9502590000000168,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953920709,"endTime":1787953920719.9502,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/devils-advocate.test.ts"},{"assertionResults":[{"ancestorTitles":["checkEvidenceCitations (aggregator)"],"fullName":"checkEvidenceCitations (aggregator) returns empty when files do not exist","status":"passed","title":"returns empty when files do not exist","duration":5.335750000000019,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkEvidenceCitations (aggregator)"],"fullName":"checkEvidenceCitations (aggregator) aggregates failures from both SWOT and significance-scoring sub-checks","status":"passed","title":"aggregates failures from both SWOT and significance-scoring sub-checks","duration":2.400675000000035,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]}],"startTime":1787953931449,"endTime":1787953931457.4006,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/evidence-citations.test.ts"},{"assertionResults":[{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 extracts the visible text from a Markdown H1","status":"passed","title":"extracts the visible text from a Markdown H1","duration":4.084797999999978,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 extracts the visible text from a centered HTML <h1> template heading","status":"passed","title":"extracts the visible text from a centered HTML <h1> template heading","duration":0.9815580000000068,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 prefers the Markdown H1 when both forms are present","status":"passed","title":"prefers the Markdown H1 when both forms are present","duration":0.6436750000000302,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 returns null when neither form is present","status":"passed","title":"returns null when neither form is present","duration":0.5882409999999823,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 strips HTML tags and entities from the heading value","status":"passed","title":"strips HTML tags and entities from the heading value","duration":0.5008479999999622,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief — H1 placeholder parity (Markdown + HTML)"],"fullName":"checkExecutiveBrief — H1 placeholder parity (Markdown + HTML) fails when H1 still contains the 'REPLACE THIS H1' template placeholder (Markdown H1 path)","status":"passed","title":"fails when H1 still contains the 'REPLACE THIS H1' template placeholder (Markdown H1 path)","duration":7.347767999999974,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief — H1 placeholder parity (Markdown + HTML)"],"fullName":"checkExecutiveBrief — H1 placeholder parity (Markdown + HTML) fails when the template placeholder is left in an HTML H1 (centered <h1> parity)","status":"passed","title":"fails when the template placeholder is left in an HTML H1 (centered <h1> parity)","duration":1.589917000000014,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]}],"startTime":1787953909127,"endTime":1787953909143.5898,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/executive-brief-h1.test.ts"},{"assertionResults":[{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief passes with publishable H1, BLUF and Decisions sections","status":"passed","title":"passes with publishable H1, BLUF and Decisions sections","duration":9.60451599999999,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when BLUF missing","status":"passed","title":"fails when BLUF missing","duration":1.56152400000002,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 is bare-boilerplate '# Executive Brief'","status":"passed","title":"fails when H1 is bare-boilerplate '# Executive Brief'","duration":0.9012879999999655,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains the banned phrase 'AI-generated political intelligence'","status":"passed","title":"fails when H1 contains the banned phrase 'AI-generated political intelligence'","duration":0.8178110000000061,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief tolerates a leading emoji in an otherwise publishable H1","status":"passed","title":"tolerates a leading emoji in an otherwise publishable H1","duration":4.264895999999965,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when the brief has no H1 at all (renderer would fall back to BLUF first sentence)","status":"passed","title":"fails when the brief has no H1 at all (renderer would fall back to BLUF first sentence)","duration":1.11015900000001,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 collapses to nothing via cleanArticleTitle (subfolder-label boilerplate)","status":"passed","title":"fails when H1 collapses to nothing via cleanArticleTitle (subfolder-label boilerplate)","duration":1.1279220000000123,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains a literal ISO date (YYYY-MM-DD)","status":"passed","title":"fails when H1 contains a literal ISO date (YYYY-MM-DD)","duration":0.9658689999999979,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains an English long-form date","status":"passed","title":"fails when H1 contains an English long-form date","duration":1.230242999999973,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains a Swedish long-form date","status":"passed","title":"fails when H1 contains a Swedish long-form date","duration":1.0300579999999968,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 ends with a trailing comma","status":"passed","title":"fails when H1 ends with a trailing comma","duration":0.881069000000025,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 ends with a coordinating connector","status":"passed","title":"fails when H1 ends with a coordinating connector","duration":0.8164390000000026,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 is normalised-identical to a prior day brief in the same subfolder","status":"passed","title":"fails when H1 is normalised-identical to a prior day brief in the same subfolder","duration":2.1570499999999697,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief passes when prior-day brief in same subfolder has a different H1","status":"passed","title":"passes when prior-day brief in same subfolder has a different H1","duration":1.3712679999999864,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]}],"startTime":1787953828345,"endTime":1787953828373.3713,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/executive-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFamilyCStructure (aggregator)"],"fullName":"checkFamilyCStructure (aggregator) returns no failures when every Family C artifact is well-formed","status":"passed","title":"returns no failures when every Family C artifact is well-formed","duration":15.338300000000004,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFamilyCStructure (aggregator)"],"fullName":"checkFamilyCStructure (aggregator) aggregates failures from multiple sub-checks when artifacts are malformed","status":"passed","title":"aggregates failures from multiple sub-checks when artifacts are malformed","duration":1.9138130000000046,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]}],"startTime":1787953906862,"endTime":1787953906878.9138,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/family-c-structure.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFamilyDStructure (aggregator)"],"fullName":"checkFamilyDStructure (aggregator) returns no failures when both Family D artifacts are well-formed","status":"passed","title":"returns no failures when both Family D artifacts are well-formed","duration":6.215609000000029,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFamilyDStructure (aggregator)"],"fullName":"checkFamilyDStructure (aggregator) aggregates failures from both sub-checks","status":"passed","title":"aggregates failures from both sub-checks","duration":1.47742599999998,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]}],"startTime":1787953928326,"endTime":1787953928333.4775,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/family-d-structure.test.ts"},{"assertionResults":[{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators passes with 10+ dated indicators","status":"passed","title":"passes with 10+ dated indicators","duration":5.850454999999954,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators fails with fewer than 10 dated indicators","status":"passed","title":"fails with fewer than 10 dated indicators","duration":1.223651000000018,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators recognises quarterly date format","status":"passed","title":"recognises quarterly date format","duration":0.9095030000000293,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953926999,"endTime":1787953927006.9094,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/forward-indicators.test.ts"},{"assertionResults":[{"ancestorTitles":["checkIntelligenceAssessment"],"fullName":"checkIntelligenceAssessment passes with 3+ Key Judgments, confidence labels, and PIR","status":"passed","title":"passes with 3+ Key Judgments, confidence labels, and PIR","duration":5.942737000000022,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkIntelligenceAssessment"],"fullName":"checkIntelligenceAssessment fails with fewer than 3 Key Judgments","status":"passed","title":"fails with fewer than 3 Key Judgments","duration":1.1661339999999996,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953933717,"endTime":1787953933724.166,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/intelligence-assessment.test.ts"},{"assertionResults":[{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams passes with Mermaid block and style directive","status":"passed","title":"passes with Mermaid block and style directive","duration":4.945030000000031,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams passes with themeVariables","status":"passed","title":"passes with themeVariables","duration":1.9913689999999633,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams fails when Mermaid block missing","status":"passed","title":"fails when Mermaid block missing","duration":1.0531819999999925,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams fails when colour config missing","status":"passed","title":"fails when colour config missing","duration":0.9869980000000282,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953925180,"endTime":1787953925188.987,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/mermaid-diagrams.test.ts"},{"assertionResults":[{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection passes when all nine required methodology-reflection sections are present","status":"passed","title":"passes when all nine required methodology-reflection sections are present","duration":9.570920999999998,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection accepts ## headings with leading emoji","status":"passed","title":"accepts ## headings with leading emoji","duration":1.5061709999999948,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when required sections are missing","status":"passed","title":"fails when required sections are missing","duration":1.7206009999999878,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when phrases are present only in body text but not as ## headings","status":"passed","title":"fails when phrases are present only in body text but not as ## headings","duration":0.8443609999999921,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when KJ Coverage Matrix has ❌ rows","status":"passed","title":"fails when KJ Coverage Matrix has ❌ rows","duration":1.132079000000033,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when a Confidence Distribution KJ row has empty Posterior","status":"passed","title":"fails when a Confidence Distribution KJ row has empty Posterior","duration":1.1436620000000062,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when Posterior cell is a `[REQUIRED]` placeholder","status":"passed","title":"fails when Posterior cell is a `[REQUIRED]` placeholder","duration":0.9877799999999866,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when Re-run Log section is present but column header row is outside the section","status":"passed","title":"fails when Re-run Log section is present but column header row is outside the section","duration":0.9496780000000058,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]}],"startTime":1787953854425,"endTime":1787953854442.9497,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/methodology-reflection.test.ts"},{"assertionResults":[{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs passes when no stubs present","status":"passed","title":"passes when no stubs present","duration":5.9229799999999955,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects AI_MUST_REPLACE placeholder","status":"passed","title":"detects AI_MUST_REPLACE placeholder","duration":1.4892380000000003,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects TODO: placeholder","status":"passed","title":"detects TODO: placeholder","duration":0.9277569999999855,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects multiple stub types in same file","status":"passed","title":"detects multiple stub types in same file","duration":1.001985999999988,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects stubs in documents/ directory (Family E)","status":"passed","title":"detects stubs in documents/ directory (Family E)","duration":1.29140799999999,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953917050,"endTime":1787953917061.2915,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/no-stubs.test.ts"},{"assertionResults":[{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence exports the canonical 180_000 ms mtime threshold","status":"passed","title":"exports the canonical 180_000 ms mtime threshold","duration":4.193200999999988,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence passes when pass1/ snapshot differs from current file","status":"passed","title":"passes when pass1/ snapshot differs from current file","duration":3.1187400000000025,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence fails when pass1/ snapshot is identical to current file (no improvements)","status":"passed","title":"fails when pass1/ snapshot is identical to current file (no improvements)","duration":1.5890949999999862,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence skips artifacts that do not exist","status":"passed","title":"skips artifacts that do not exist","duration":0.7552550000000338,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence returns pass2-evidence checkId on failure","status":"passed","title":"returns pass2-evidence checkId on failure","duration":1.2731540000000336,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953910897,"endTime":1787953910908.2732,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/pass2-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds extracts dok_ids from markdown content","status":"passed","title":"extracts dok_ids from markdown content","duration":4.554879000000028,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds deduplicates dok_ids","status":"passed","title":"deduplicates dok_ids","duration":0.8977510000000279,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds returns empty array when no dok_ids found","status":"passed","title":"returns empty array when no dok_ids found","duration":0.5134209999999939,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds handles empty content","status":"passed","title":"handles empty content","duration":0.40315499999996973,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage passes when all dok_ids have analysis files","status":"passed","title":"passes when all dok_ids have analysis files","duration":2.168790999999999,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage reports missing document analysis","status":"passed","title":"reports missing document analysis","duration":1.2256250000000364,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage reports failure when manifest has no dok_ids","status":"passed","title":"reports failure when manifest has no dok_ids","duration":0.9659490000000233,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage returns empty when manifest does not exist","status":"passed","title":"returns empty when manifest does not exist","duration":0.6386249999999905,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]}],"startTime":1787953910458,"endTime":1787953910469.6387,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/per-document-coverage.test.ts"},{"assertionResults":[{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus passes with valid pir-status.json","status":"passed","title":"passes with valid pir-status.json","duration":6.086866999999984,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when file missing","status":"passed","title":"fails when file missing","duration":0.9505500000000211,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails with invalid JSON","status":"passed","title":"fails with invalid JSON","duration":0.8820920000000001,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when schema_version is not 1.0","status":"passed","title":"fails when schema_version is not 1.0","duration":0.9355119999999602,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when subfolder != cycle","status":"passed","title":"fails when subfolder != cycle","duration":0.8155270000000314,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus validates PIR entry fields","status":"passed","title":"validates PIR entry fields","duration":0.9019289999999955,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus requires answer_summary when status is \"answered\"","status":"passed","title":"requires answer_summary when status is \"answered\"","duration":0.7986960000000067,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus passes when status is \"answered\" and answer_summary is present","status":"passed","title":"passes when status is \"answered\" and answer_summary is present","duration":0.8178110000000061,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when non-answered PIR carries answer_summary","status":"passed","title":"fails when non-answered PIR carries answer_summary","duration":1.0171439999999734,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953870169,"endTime":1787953870182.017,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/pir-status.test.ts"},{"assertionResults":[{"ancestorTitles":["checkScenarioAnalysis"],"fullName":"checkScenarioAnalysis passes with 3+ scenarios","status":"passed","title":"passes with 3+ scenarios","duration":5.744567000000018,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkScenarioAnalysis"],"fullName":"checkScenarioAnalysis fails with fewer than 3 scenarios","status":"passed","title":"fails with fewer than 3 scenarios","duration":1.1303769999999531,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]}],"startTime":1787953937182,"endTime":1787953937189.1304,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/scenario-analysis.test.ts"},{"assertionResults":[{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence passes when all significance-scoring bullets have evidence","status":"passed","title":"passes when all significance-scoring bullets have evidence","duration":5.939391999999998,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence fails when significance-scoring bullet is missing evidence","status":"passed","title":"fails when significance-scoring bullet is missing evidence","duration":1.3199819999999818,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence returns empty when significance-scoring.md does not exist","status":"passed","title":"returns empty when significance-scoring.md does not exist","duration":0.6786810000000401,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953930116,"endTime":1787953930123.6787,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/significance-scoring.test.ts"},{"assertionResults":[{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when no recognised agency mentioned","status":"passed","title":"passes when no recognised agency mentioned","duration":5.925566000000003,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when agency mentioned with statskontoret.se URL","status":"passed","title":"passes when agency mentioned with statskontoret.se URL","duration":1.378150000000005,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when agency mentioned with \"none found\"","status":"passed","title":"passes when agency mentioned with \"none found\"","duration":0.8699090000000069,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence fails when agency mentioned without Statskontoret row","status":"passed","title":"fails when agency mentioned without Statskontoret row","duration":0.78569200000004,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]}],"startTime":1787953919829,"endTime":1787953919837.7856,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/statskontoret-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence passes when all SWOT bullets have evidence","status":"passed","title":"passes when all SWOT bullets have evidence","duration":6.4625709999999685,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence fails when a SWOT bullet is missing evidence","status":"passed","title":"fails when a SWOT bullet is missing evidence","duration":1.4075559999999996,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence returns empty when swot-analysis.md does not exist","status":"passed","title":"returns empty when swot-analysis.md does not exist","duration":0.7080259999999612,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]}],"startTime":1787953930560,"endTime":1787953930568.708,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/swot-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive returns empty array when directory does not exist","status":"passed","title":"returns empty array when directory does not exist","duration":4.539641000000017,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive collects top-level .md files only","status":"passed","title":"collects top-level .md files only","duration":1.583785999999975,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive recurses into nested directories and returns paths relative to baseDir","status":"passed","title":"recurses into nested directories and returns paths relative to baseDir","duration":1.2876109999999699,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive honours a non-empty prefix and joins paths under it","status":"passed","title":"honours a non-empty prefix and joins paths under it","duration":0.7306480000000306,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]}],"startTime":1787953919391,"endTime":1787953919399.7307,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-shared/file-walkers.test.ts"},{"assertionResults":[{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup returns plain headings unchanged","status":"passed","title":"returns plain headings unchanged","duration":3.765299999999968,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup strips simple HTML tags","status":"passed","title":"strips simple HTML tags","duration":0.5604289999999992,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup strips multi-tag HTML wrapping with collapse of whitespace","status":"passed","title":"strips multi-tag HTML wrapping with collapse of whitespace","duration":0.5736139999999637,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup decodes   entities","status":"passed","title":"decodes   entities","duration":0.3974240000000009,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup collapses internal whitespace and trims edges","status":"passed","title":"collapses internal whitespace and trims edges","duration":0.423753999999974,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading matches an H2 heading body","status":"passed","title":"matches an H2 heading body","duration":1.0609870000000114,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading matches an H4 heading","status":"passed","title":"matches an H4 heading","duration":0.478336000000013,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading does not match H1","status":"passed","title":"does not match H1","duration":0.32650200000000495,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading strips a leading emoji before matching","status":"passed","title":"strips a leading emoji before matching","duration":1.6907260000000406,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading returns false when no heading line matches","status":"passed","title":"returns false when no heading line matches","duration":0.35142700000000104,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection returns the body of the matching ## section","status":"passed","title":"returns the body of the matching ## section","duration":0.9051249999999982,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection stops at the next H2 heading","status":"passed","title":"stops at the next H2 heading","duration":0.5915880000000016,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection returns empty string when section is absent","status":"passed","title":"returns empty string when section is absent","duration":0.34638899999998785,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection tolerates an emoji prefix on the section heading","status":"passed","title":"tolerates an emoji prefix on the section heading","duration":0.45193599999998924,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives BULLET_RE matches dash and asterisk bullets","status":"passed","title":"BULLET_RE matches dash and asterisk bullets","duration":0.48168199999997796,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives TABLE_ROW_RE matches markdown table rows","status":"passed","title":"TABLE_ROW_RE matches markdown table rows","duration":0.46288700000002336,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives TABLE_SEP_RE matches table separator rows","status":"passed","title":"TABLE_SEP_RE matches table separator rows","duration":0.6452990000000227,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives ANY_HEADING_RE matches H1–H6","status":"passed","title":"ANY_HEADING_RE matches H1–H6","duration":0.46910800000000563,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]}],"startTime":1787953903048,"endTime":1787953903062.469,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-shared/markdown-helpers.test.ts"},{"assertionResults":[{"ancestorTitles":["canonical og:locale regex — anchor contract"],"fullName":"canonical og:locale regex — anchor contract the script defines a regex matching the single `<meta property=\"og:locale\">` tag","status":"passed","title":"the script defines a regex matching the single `<meta property=\"og:locale\">` tag","duration":3.648161000000016,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale regex — anchor contract"],"fullName":"canonical og:locale regex — anchor contract the script enumerates 14 canonical locale codes (en_US, sv_SE, da_DK, nb_NO, fi_FI, ...)","status":"passed","title":"the script enumerates 14 canonical locale codes (en_US, sv_SE, da_DK, nb_NO, fi_FI, ...)","duration":0.8596599999999626,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale alias rule — BCP-47 nb over legacy no"],"fullName":"canonical og:locale alias rule — BCP-47 nb over legacy no the alias table maps the legacy `no_NO` locale to canonical `nb_NO`","status":"passed","title":"the alias table maps the legacy `no_NO` locale to canonical `nb_NO`","duration":0.5817900000000122,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale alias rule — BCP-47 nb over legacy no"],"fullName":"canonical og:locale alias rule — BCP-47 nb over legacy no the script documents the BCP-47 preference (Norwegian Bokmål)","status":"passed","title":"the script documents the BCP-47 preference (Norwegian Bokmål)","duration":0.3811640000000125,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale idempotency rule"],"fullName":"canonical og:locale idempotency rule the script documents the \"leave file alone if og:locale:alternate exists\" rule","status":"passed","title":"the script documents the \"leave file alone if og:locale:alternate exists\" rule","duration":0.4904989999999998,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]}],"startTime":1787953913083,"endTime":1787953913088.4905,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/canonical.test.ts"},{"assertionResults":[{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts every metadata surface","status":"passed","title":"extracts every metadata surface","duration":5.788959000000034,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts meta tag content regardless of attribute order","status":"passed","title":"extracts meta tag content regardless of attribute order","duration":1.435767999999996,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent decodes entity-bearing unquoted meta attribute values","status":"passed","title":"decodes entity-bearing unquoted meta attribute values","duration":0.6242390000000455,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent populates bodyPlainText from <article> contents","status":"passed","title":"populates bodyPlainText from <article> contents","duration":0.6903429999999844,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent decodes HTML entities in metadata","status":"passed","title":"decodes HTML entities in metadata","duration":0.5364739999999983,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent returns empty lang when <html lang=\"…\"> is missing (CLI applies the fallback)","status":"passed","title":"returns empty lang when <html lang=\"…\"> is missing (CLI applies the fallback)","duration":0.5194520000000011,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts <html lang> from single-quoted, unquoted, and reordered attributes","status":"passed","title":"extracts <html lang> from single-quoted, unquoted, and reordered attributes","duration":0.7163409999999999,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts JSON-LD with extra/reordered attributes and single quotes","status":"passed","title":"extracts JSON-LD with extra/reordered attributes and single quotes","duration":0.413503999999989,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent survives a malformed JSON-LD block without crashing","status":"passed","title":"survives a malformed JSON-LD block without crashing","duration":0.5054560000000379,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent scans multiple JSON-LD blocks and picks the first with the field","status":"passed","title":"scans multiple JSON-LD blocks and picks the first with the field","duration":0.4634680000000344,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent handles JSON-LD @graph arrays","status":"passed","title":"handles JSON-LD @graph arrays","duration":0.4586889999999926,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode test helper decodes numeric references","status":"passed","title":"htmlDecode test helper decodes numeric references","duration":0.4041260000000193,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode leaves invalid numeric references untouched","status":"passed","title":"htmlDecode leaves invalid numeric references untouched","duration":0.42016700000004903,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode is single-pass (CodeQL js/double-escaping regression)","status":"passed","title":"htmlDecode is single-pass (CodeQL js/double-escaping regression)","duration":0.39168300000000045,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags test helper removes inline tags and collapses whitespace","status":"passed","title":"stripTags test helper removes inline tags and collapses whitespace","duration":0.43452300000001287,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags handles script/style end tags with whitespace before `>`","status":"passed","title":"stripTags handles script/style end tags with whitespace before `>`","duration":0.3857320000000186,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags handles malformed script end tags with trailing tokens","status":"passed","title":"stripTags handles malformed script end tags with trailing tokens","duration":0.3605049999999892,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent inspectHtmlContent strips a script block whose end tag has whitespace","status":"passed","title":"inspectHtmlContent strips a script block whose end tag has whitespace","duration":0.4661429999999882,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]}],"startTime":1787953837733,"endTime":1787953837747.466,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/hreflang.test.ts"},{"assertionResults":[{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script exists (memory: hand-authored bypass pipeline)","status":"passed","title":"the backfill script exists (memory: hand-authored bypass pipeline)","duration":3.7123210000000313,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script targets the hand-authored breaking-news family (memory pin)","status":"passed","title":"the backfill script targets the hand-authored breaking-news family (memory pin)","duration":0.7214209999999639,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script walks the `news/` directory (covers all hand-authored families)","status":"passed","title":"the backfill script walks the `news/` directory (covers all hand-authored families)","duration":0.6210130000000049,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script supports --dry-run (smoke-check contract)","status":"passed","title":"the backfill script supports --dry-run (smoke-check contract)","duration":0.48522800000000643,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — html-inspector surface (smoke)"],"fullName":"og:locale:alternate — html-inspector surface (smoke) inspectHtmlContent extracts `<html lang>` (the alternate base lang)","status":"passed","title":"inspectHtmlContent extracts `<html lang>` (the alternate base lang)","duration":1.5605919999999855,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — html-inspector surface (smoke)"],"fullName":"og:locale:alternate — html-inspector surface (smoke) inspectHtmlContent surfaces an empty lang when `<html lang>` is missing","status":"passed","title":"inspectHtmlContent surfaces an empty lang when `<html lang>` is missing","duration":0.5903059999999982,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — 14-language registry parity"],"fullName":"og:locale:alternate — 14-language registry parity every language in the news-indexes 14-language list has an og locale value","status":"passed","title":"every language in the news-indexes 14-language list has an og locale value","duration":1.92307100000005,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — 14-language registry parity"],"fullName":"og:locale:alternate — 14-language registry parity Norwegian uses BCP-47 nb_NO (not no_NO) for og:locale:alternate","status":"passed","title":"Norwegian uses BCP-47 nb_NO (not no_NO) for og:locale:alternate","duration":0.41071899999997186,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]}],"startTime":1787953900650,"endTime":1787953900661.4106,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/og-locale-alternate.test.ts"},{"assertionResults":[{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a valid MCP JSON-RPC `kalender` response","status":"passed","title":"returns events from a valid MCP JSON-RPC `kalender` response","duration":5.861635999999976,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a direct `result.kalender` response (no content wrapper)","status":"passed","title":"returns events from a direct `result.kalender` response (no content wrapper)","duration":0.8233109999999897,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a `result.events` key","status":"passed","title":"returns events from a `result.events` key","duration":0.7094180000000279,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) when MCP returns an HTML document","status":"passed","title":"throws CalendarMcpError(html) when MCP returns an HTML document","duration":2.7908760000000257,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(http) on a non-OK HTTP status with non-HTML body","status":"passed","title":"throws CalendarMcpError(http) on a non-OK HTTP status with non-HTML body","duration":0.714006999999981,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(network) on a fetch network error","status":"passed","title":"throws CalendarMcpError(network) on a fetch network error","duration":0.7068830000000048,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(tool) when the JSON-RPC response has an `error` field","status":"passed","title":"throws CalendarMcpError(tool) when the JSON-RPC response has an `error` field","duration":0.5751170000000343,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns an empty array when `result.kalender` is an empty array","status":"passed","title":"returns an empty array when `result.kalender` is an empty array","duration":0.6677799999999934,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns an empty array when `result` has no recognised events key","status":"passed","title":"returns an empty array when `result` has no recognised events key","duration":0.7339750000000436,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on the degraded-kalender sentinel in content text","status":"passed","title":"throws CalendarMcpError(html) on the degraded-kalender sentinel in content text","duration":0.8561440000000289,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on a degraded sentinel in a direct result (no content wrapper)","status":"passed","title":"throws CalendarMcpError(html) on a degraded sentinel in a direct result (no content wrapper)","duration":0.5519429999999943,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(json) when content text is malformed JSON","status":"passed","title":"throws CalendarMcpError(json) when content text is malformed JSON","duration":0.6672700000000304,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents includes rawHtml in responseText when sentinel has rawHtml","status":"passed","title":"includes rawHtml in responseText when sentinel has rawHtml","duration":0.7287249999999972,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents includes the error string in the thrown message for degraded sentinel","status":"passed","title":"includes the error string in the thrown message for degraded sentinel","duration":1.3739229999999907,"failureMessages":[],"location":{"line":259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on a rawHtml-only sentinel (no error field)","status":"passed","title":"throws CalendarMcpError(html) on a rawHtml-only sentinel (no error field)","duration":0.6231570000000488,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]}],"startTime":1787953833931,"endTime":1787953833949.623,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/client.test.ts"},{"assertionResults":[{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a DOCTYPE HTML response","status":"passed","title":"returns true for a DOCTYPE HTML response","duration":3.7126719999999978,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a lower-case <!doctype html> response","status":"passed","title":"returns true for a lower-case <!doctype html> response","duration":0.5718709999999874,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a bare <html> opening tag","status":"passed","title":"returns true for a bare <html> opening tag","duration":0.46478000000001884,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for an uppercase <HTML> opening tag","status":"passed","title":"returns true for an uppercase <HTML> opening tag","duration":0.3246780000000058,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a leading <head> tag fragment","status":"passed","title":"returns true for a leading <head> tag fragment","duration":0.47185400000000755,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a self-closing <meta /> fragment","status":"passed","title":"returns true for a self-closing <meta /> fragment","duration":0.47958799999997836,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for a JSON response","status":"passed","title":"returns false for a JSON response","duration":0.383707999999956,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for an empty string","status":"passed","title":"returns false for an empty string","duration":0.3020559999999932,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for a leading whitespace + JSON response","status":"passed","title":"returns false for a leading whitespace + JSON response","duration":0.6171860000000038,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for whitespace before DOCTYPE","status":"passed","title":"returns true for whitespace before DOCTYPE","duration":0.4915409999999838,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) matches the canonical HTML opening sequences","status":"passed","title":"matches the canonical HTML opening sequences","duration":0.5085520000000088,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) does NOT match JSON or JSON-RPC payloads","status":"passed","title":"does NOT match JSON or JSON-RPC payloads","duration":0.38260600000000977,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) does NOT match plain text or empty strings","status":"passed","title":"does NOT match plain text or empty strings","duration":0.48954700000001594,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when an upstream error string is present","status":"passed","title":"returns true when an upstream error string is present","duration":0.5006270000000086,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when a rawHtml field is present","status":"passed","title":"returns true when a rawHtml field is present","duration":0.4370580000000359,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when both error and rawHtml are present","status":"passed","title":"returns true when both error and rawHtml are present","duration":0.4002800000000093,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true for rawHtml-only sentinel without error field","status":"passed","title":"returns true for rawHtml-only sentinel without error field","duration":0.3750830000000178,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false for a legitimate empty calendar window","status":"passed","title":"returns false for a legitimate empty calendar window","duration":0.37114400000001524,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false when error/rawHtml are empty or whitespace","status":"passed","title":"returns false when error/rawHtml are empty or whitespace","duration":0.3503759999999829,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false when error/rawHtml are non-string types","status":"passed","title":"returns false when error/rawHtml are non-string types","duration":0.5428459999999973,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false for an empty object","status":"passed","title":"returns false for an empty object","duration":0.477484000000004,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarMcpError"],"fullName":"CalendarMcpError has the correct name and kind","status":"passed","title":"has the correct name and kind","duration":0.6981670000000122,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarMcpError"],"fullName":"CalendarMcpError correctly identifies all error kinds","status":"passed","title":"correctly identifies all error kinds","duration":0.6356400000000235,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]}],"startTime":1787953869709,"endTime":1787953869723.6357,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/errors.test.ts"},{"assertionResults":[{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent maps standard MCP event fields","status":"passed","title":"maps standard MCP event fields","duration":4.687937999999974,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent handles upper-case DTSTART / SUMMARY keys","status":"passed","title":"handles upper-case DTSTART / SUMMARY keys","duration":0.6637029999999982,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent includes dtend when present","status":"passed","title":"includes dtend when present","duration":0.39392700000001923,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent collects multiple doc_refs from array fields","status":"passed","title":"collects multiple doc_refs from array fields","duration":0.7654529999999795,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent handles null / undefined gracefully","status":"passed","title":"handles null / undefined gracefully","duration":1.0869350000000395,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent omits dtend when not present in raw event","status":"passed","title":"omits dtend when not present in raw event","duration":0.6026789999999664,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953918028,"endTime":1787953918036.6028,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/normaliser.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle returns null when no datetime found","status":"passed","title":"returns null when no datetime found","duration":3.6400350000000117,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle extracts organ and akt from data attributes","status":"passed","title":"extracts organ and akt from data attributes","duration":1.6041940000000068,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle falls back to span text for org and akt when data attributes absent","status":"passed","title":"falls back to span text for org and akt when data attributes absent","duration":1.0738799999999742,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]}],"startTime":1787953938943,"endTime":1787953938949.074,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/article-block.test.ts"},{"assertionResults":[{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime extracts the datetime attribute from a <time> tag","status":"passed","title":"extracts the datetime attribute from a <time> tag","duration":3.8027099999999905,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime returns null when no <time> tag is present","status":"passed","title":"returns null when no <time> tag is present","duration":0.6187189999999987,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime returns null when <time> has no datetime attribute","status":"passed","title":"returns null when <time> has no datetime attribute","duration":0.4622659999999996,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns true when class list contains calendar-item","status":"passed","title":"returns true when class list contains calendar-item","duration":0.5257540000000063,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns true with single-quoted attribute","status":"passed","title":"returns true with single-quoted attribute","duration":0.3925460000000385,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns false when class list does not contain calendar-item","status":"passed","title":"returns false when class list does not contain calendar-item","duration":0.52489300000002,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDataAttr"],"fullName":"extractDataAttr extracts a data-* attribute value","status":"passed","title":"extracts a data-* attribute value","duration":0.5494390000000067,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDataAttr"],"fullName":"extractDataAttr returns null when attribute is missing","status":"passed","title":"returns null when attribute is missing","duration":0.425596999999982,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isRiksdagDocumentHref"],"fullName":"isRiksdagDocumentHref accepts canonical betankande paths","status":"passed","title":"accepts canonical betankande paths","duration":0.5046749999999633,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isRiksdagDocumentHref"],"fullName":"isRiksdagDocumentHref rejects unrelated URLs","status":"passed","title":"rejects unrelated URLs","duration":0.44606499999997595,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeOrgCode"],"fullName":"normalizeOrgCode uppercases short organ codes","status":"passed","title":"uppercases short organ codes","duration":0.7577090000000339,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953921158,"endTime":1787953921167.7578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/extractors.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarListItem"],"fullName":"parseCalendarListItem returns null when no datetime found","status":"passed","title":"returns null when no datetime found","duration":3.6457359999999994,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarListItem"],"fullName":"parseCalendarListItem extracts all fields from a well-formed list item","status":"passed","title":"extracts all fields from a well-formed list item","duration":3.0416649999999663,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]}],"startTime":1787953939376,"endTime":1787953939383.0417,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/list-item.test.ts"},{"assertionResults":[{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml parses article pattern events","status":"passed","title":"parses article pattern events","duration":6.585950999999966,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml falls back to list-item pattern when no articles found","status":"passed","title":"falls back to list-item pattern when no articles found","duration":1.3502280000000155,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml returns empty array for HTML with no recognisable calendar markup","status":"passed","title":"returns empty array for HTML with no recognisable calendar markup","duration":1.048813999999993,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml ignores non-calendar article blocks even when they contain time elements","status":"passed","title":"ignores non-calendar article blocks even when they contain time elements","duration":0.5484769999999912,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml parses calendar-item articles when class attribute uses single quotes","status":"passed","title":"parses calendar-item articles when class attribute uses single quotes","duration":0.6371630000000437,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar fetches and parses a calendar page with article events","status":"passed","title":"fetches and parses a calendar page with article events","duration":1.6512519999999995,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar throws on a non-OK HTTP response","status":"passed","title":"throws on a non-OK HTTP response","duration":1.8680980000000318,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar throws on a network fetch failure","status":"passed","title":"throws on a network fetch failure","duration":0.6653850000000148,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]}],"startTime":1787953872841,"endTime":1787953872855.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/parse.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json exposes every coreLanguages value as a key in the 14-language list","status":"passed","title":"exposes every coreLanguages value as a key in the 14-language list","duration":3.884093000000007,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json every registry workflow file exists in .github/workflows/","status":"passed","title":"every registry workflow file exists in .github/workflows/","duration":1.140736000000004,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json every registry entry uses one of the known families (tier-A/B/C surface)","status":"passed","title":"every registry entry uses one of the known families (tier-A/B/C surface)","duration":0.6877780000000371,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json has at least one tier-C aggregation entry (week-ahead / month-ahead)","status":"passed","title":"has at least one tier-C aggregation entry (week-ahead / month-ahead)","duration":0.5380170000000248,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]}],"startTime":1787953909582,"endTime":1787953909587.6877,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/constants/article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should return object with all 14 language keys","status":"passed","title":"should return object with all 14 language keys","duration":5077.173564999999,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should return arrays for each language","status":"passed","title":"should return arrays for each language","duration":5125.172743,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should sort articles by date descending","status":"passed","title":"should sort articles by date descending","duration":5115.504405,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits FAQPage JSON-LD","status":"passed","title":"emits FAQPage JSON-LD","duration":19.091617000000042,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":1.3621210000001156,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features localises the FAQ heading for Swedish","status":"passed","title":"localises the FAQ heading for Swedish","duration":1.0963130000000092,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits a crawler-visible article list as a collapsible <details> block","status":"passed","title":"emits a crawler-visible article list as a collapsible <details> block","duration":0.9756769999985409,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features does NOT use inline positioning styles on the article list","status":"passed","title":"does NOT use inline positioning styles on the article list","duration":1.2273679999998421,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]}],"startTime":1787953873316,"endTime":1787953888658.2273,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/article-merge.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should parse metadata from a real article file","status":"passed","title":"should parse metadata from a real article file","duration":61.25865699999997,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should return null for non-article files","status":"passed","title":"should return null for non-article files","duration":1.3488760000000184,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract correct language from filename suffix","status":"passed","title":"should extract correct language from filename suffix","duration":8.879728,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should classify week-ahead articles as prospective","status":"passed","title":"should classify week-ahead articles as prospective","duration":1.5566650000000095,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should classify committee-reports as analysis","status":"passed","title":"should classify committee-reports as analysis","duration":1.1918919999999957,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract topics from article:tag meta tags","status":"passed","title":"should extract topics from article:tag meta tags","duration":2.0017879999999764,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract tags from article:tag meta tags","status":"passed","title":"should extract tags from article:tag meta tags","duration":1.1993160000000103,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]}],"startTime":1787953848664,"endTime":1787953848741.1992,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/frontmatter.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags emits one <link rel=\"alternate\"> per language plus x-default","status":"passed","title":"emits one <link rel=\"alternate\"> per language plus x-default","duration":3.934718000000032,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags includes x-default pointing to news/index.html","status":"passed","title":"includes x-default pointing to news/index.html","duration":0.7496739999999704,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags maps Norwegian hreflang to nb (BCP-47)","status":"passed","title":"maps Norwegian hreflang to nb (BCP-47)","duration":0.5411240000000248,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags includes Swedish alternate link","status":"passed","title":"includes Swedish alternate link","duration":0.5401709999999866,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles returns empty string for non-RTL pages","status":"passed","title":"returns empty string for non-RTL pages","duration":0.7301569999999629,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles returns RTL styles for RTL pages","status":"passed","title":"returns RTL styles for RTL pages","duration":0.49399599999998145,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles RTL styles include direction-aware transforms","status":"passed","title":"RTL styles include direction-aware transforms","duration":0.5931509999999776,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns empty string for unsupported language key","status":"passed","title":"returns empty string for unsupported language key","duration":0.46313700000001745,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Danish","status":"passed","title":"returns a notice for Danish","duration":0.6502570000000105,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Norwegian","status":"passed","title":"returns a notice for Norwegian","duration":0.4599010000000021,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Arabic with dir=\"ltr\" on the EN badge","status":"passed","title":"returns a notice for Arabic with dir=\"ltr\" on the EN badge","duration":0.531265000000019,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Hebrew with dir=\"ltr\" on the EN badge","status":"passed","title":"returns a notice for Hebrew with dir=\"ltr\" on the EN badge","duration":0.4409660000000031,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice notices for non-RTL languages do not include dir=\"ltr\" on the badge","status":"passed","title":"notices for non-RTL languages do not include dir=\"ltr\" on the badge","duration":0.5085920000000215,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: da","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: da","duration":0.6396679999999719,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: no","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: no","duration":0.4262679999999932,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: fi","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: fi","duration":0.43754899999999,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: de","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: de","duration":0.46279600000002574,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: fr","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: fr","duration":0.36505399999998644,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: es","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: es","duration":0.45294799999999213,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: nl","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: nl","duration":0.3705639999999448,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ar","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ar","duration":0.5472649999999817,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: he","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: he","duration":0.4203069999999798,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ja","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ja","duration":0.5059669999999983,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ko","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ko","duration":0.4400039999999876,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: zh","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: zh","duration":0.4347439999999665,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list exports exactly 14 languages (single source of truth)","status":"passed","title":"exports exactly 14 languages (single source of truth)","duration":1.2694769999999949,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list uses BCP-47 nb (not legacy no) for Norwegian hreflang","status":"passed","title":"uses BCP-47 nb (not legacy no) for Norwegian hreflang","duration":0.5900850000000446,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list marks Arabic and Hebrew as RTL","status":"passed","title":"marks Arabic and Hebrew as RTL","duration":0.48241299999995135,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list marks all other languages as LTR (rtl flag absent or false)","status":"passed","title":"marks all other languages as LTR (rtl flag absent or false)","duration":0.8681460000000243,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]}],"startTime":1787953869247,"endTime":1787953869266.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify German prospective articles","status":"passed","title":"should classify German prospective articles","duration":55.200946999999985,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify French analysis articles","status":"passed","title":"should classify French analysis articles","duration":1.6376269999999522,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Japanese breaking news articles","status":"passed","title":"should classify Japanese breaking news articles","duration":3.8657680000000028,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Arabic prospective articles","status":"passed","title":"should classify Arabic prospective articles","duration":0.8729050000000029,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Finnish analysis articles","status":"passed","title":"should classify Finnish analysis articles","duration":1.1230429999999956,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Korean breaking news articles","status":"passed","title":"should classify Korean breaking news articles","duration":0.909121999999968,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should default to retrospective when no keywords match","status":"passed","title":"should default to retrospective when no keywords match","duration":0.9731120000000146,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from German tags","status":"passed","title":"should extract topics from German tags","duration":2.0821679999999674,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from Japanese tags","status":"passed","title":"should extract topics from Japanese tags","duration":1.234310999999991,"failureMessages":[],"location":{"line":205,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from Arabic tags","status":"passed","title":"should extract topics from Arabic tags","duration":1.3749740000000088,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]}],"startTime":1787953836240,"endTime":1787953836309.375,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/slug.test.ts"},{"assertionResults":[{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) assembles all five fragments in the expected order","status":"passed","title":"assembles all five fragments in the expected order","duration":4.123801999999955,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) produces a non-empty runtime body","status":"passed","title":"produces a non-empty runtime body","duration":0.6050330000000486,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) stays under the 200 KB CSP audit budget (single review unit)","status":"passed","title":"stays under the 200 KB CSP audit budget (single review unit)","duration":0.4930530000000317,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — helpers fragment"],"fullName":"client-script-runtime — helpers fragment exposes the esc() XSS-safe HTML escaper","status":"passed","title":"exposes the esc() XSS-safe HTML escaper","duration":0.4665340000000242,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — rendering fragment"],"fullName":"client-script-runtime — rendering fragment defines buildArticleCard()","status":"passed","title":"defines buildArticleCard()","duration":0.4545709999999872,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — rendering fragment"],"fullName":"client-script-runtime — rendering fragment escapes article fields through esc()","status":"passed","title":"escapes article fields through esc()","duration":0.4975610000000188,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — filtering fragment"],"fullName":"client-script-runtime — filtering fragment wires the type and topic filter selects","status":"passed","title":"wires the type and topic filter selects","duration":0.44525399999997717,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — sorting fragment"],"fullName":"client-script-runtime — sorting fragment wires the sort filter select","status":"passed","title":"wires the sort filter select","duration":0.37751700000001165,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — search fragment"],"fullName":"client-script-runtime — search fragment wires the search input","status":"passed","title":"wires the search input","duration":0.4741080000000011,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]}],"startTime":1787953913509,"endTime":1787953913517.474,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/template/client-script-runtime.test.ts"},{"assertionResults":[{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include collapsible filter-bar-wrapper details element","status":"passed","title":"should include collapsible filter-bar-wrapper details element","duration":4.045968999999786,"failureMessages":[],"location":{"line":40,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include clear-filters button with localized English label","status":"passed","title":"should include clear-filters button with localized English label","duration":0.7591410000004544,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localized clear-filters label for Swedish","status":"passed","title":"should include localized clear-filters label for Swedish","duration":0.5378280000004452,"failureMessages":[],"location":{"line":52,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localized clear-filters label for Arabic","status":"passed","title":"should include localized clear-filters label for Arabic","duration":0.49230199999965407,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include filter-active-count badge with aria-live","status":"passed","title":"should include filter-active-count badge with aria-live","duration":0.6016669999999067,"failureMessages":[],"location":{"line":60,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include article-card-skeleton elements in articles grid","status":"passed","title":"should include article-card-skeleton elements in articles grid","duration":0.7607539999999062,"failureMessages":[],"location":{"line":65,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should set aria-busy on articles grid initially for skeleton state","status":"passed","title":"should set aria-busy on articles grid initially for skeleton state","duration":0.5393000000003667,"failureMessages":[],"location":{"line":73,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include skeleton cards with aria-hidden for accessibility","status":"passed","title":"should include skeleton cards with aria-hidden for accessibility","duration":0.6916849999997794,"failureMessages":[],"location":{"line":78,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include computeRecency function in client script","status":"passed","title":"should include computeRecency function in client script","duration":1.3490870000005089,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include RECENCY_LABELS JSON blob in client script","status":"passed","title":"should include RECENCY_LABELS JSON blob in client script","duration":1.475282999999763,"failureMessages":[],"location":{"line":93,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should localise RECENCY_LABELS for Swedish","status":"passed","title":"should localise RECENCY_LABELS for Swedish","duration":1.1116910000000644,"failureMessages":[],"location":{"line":100,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localizeRecency function in client script","status":"passed","title":"should include localizeRecency function in client script","duration":0.4572870000001785,"failureMessages":[],"location":{"line":106,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include recency-badge in article card builder","status":"passed","title":"should include recency-badge in article card builder","duration":0.6878790000000663,"failureMessages":[],"location":{"line":110,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include data-date-recent attribute in article card builder","status":"passed","title":"should include data-date-recent attribute in article card builder","duration":0.4730549999994764,"failureMessages":[],"location":{"line":115,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include updateFilterChrome function in client script","status":"passed","title":"should include updateFilterChrome function in client script","duration":0.6116159999992306,"failureMessages":[],"location":{"line":119,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include clearAllFilters function in client script","status":"passed","title":"should include clearAllFilters function in client script","duration":0.5056370000002062,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should wire clear-filters button to clearAllFilters via onclick","status":"passed","title":"should wire clear-filters button to clearAllFilters via onclick","duration":0.46412899999995716,"failureMessages":[],"location":{"line":128,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should apply dir=\"ltr\" to language badges in RTL layout (Arabic)","status":"passed","title":"should apply dir=\"ltr\" to language badges in RTL layout (Arabic)","duration":0.5684550000005402,"failureMessages":[],"location":{"line":133,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should set IS_RTL = false for non-RTL languages (English)","status":"passed","title":"should set IS_RTL = false for non-RTL languages (English)","duration":0.42052700000022014,"failureMessages":[],"location":{"line":147,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include filter-bar with all four filter groups","status":"passed","title":"should include filter-bar with all four filter groups","duration":0.5483969999995679,"failureMessages":[],"location":{"line":154,"column":7},"meta":{},"tags":[]}],"startTime":1787953846722,"endTime":1787953846739.5483,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/template/phase2-ui-features.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary walks the scripts/imf tree and finds .ts source files (sanity)","status":"passed","title":"walks the scripts/imf tree and finds .ts source files (sanity)","duration":3.6431519999999864,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary reads IMF_SDMX_SUBSCRIPTION_KEY from process.env in exactly one file","status":"passed","title":"reads IMF_SDMX_SUBSCRIPTION_KEY from process.env in exactly one file","duration":1.8046489999999835,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary the auth boundary file actually contains a process.env read","status":"passed","title":"the auth boundary file actually contains a process.env read","duration":0.7146380000000363,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]}],"startTime":1787953923860,"endTime":1787953923866.7146,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/config/auth.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfClient constructor"],"fullName":"ImfClient constructor applies sensible defaults","status":"passed","title":"applies sensible defaults","duration":4.3400760000000105,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient constructor"],"fullName":"ImfClient constructor accepts overrides","status":"passed","title":"accepts overrides","duration":0.6262930000000324,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]}],"startTime":1787953931892,"endTime":1787953931896.6262,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/config/defaults.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError exposes name, status, and retryable for a 500 response","status":"passed","title":"exposes name, status, and retryable for a 500 response","duration":4.347430000000031,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError marks 429 as retryable","status":"passed","title":"marks 429 as retryable","duration":0.5745060000000421,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError marks 404 as NOT retryable","status":"passed","title":"marks 404 as NOT retryable","duration":0.4858400000000529,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError captures Retry-After header when present","status":"passed","title":"captures Retry-After header when present","duration":0.458217999999988,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]}],"startTime":1787953934587,"endTime":1787953934592.4858,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/errors/http-error.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfWeoSdmxOnlyError"],"fullName":"ImfWeoSdmxOnlyError error payload carries the SDMX path so callers can recover programmatically","status":"passed","title":"error payload carries the SDMX path so callers can recover programmatically","duration":5.768772000000013,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfWeoSdmxOnlyError"],"fullName":"ImfWeoSdmxOnlyError normalises lower-cased ISO3 inputs to upper-case in the error payload","status":"passed","title":"normalises lower-cased ISO3 inputs to upper-case in the error payload","duration":0.7948079999999891,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]}],"startTime":1787953932804,"endTime":1787953932810.795,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/errors/weo-sdmx-only.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form exposes the four canonical GF##_T codes as named exports","status":"passed","title":"exposes the four canonical GF##_T codes as named exports","duration":3.9099520000000325,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form IMF_GFS_COFOG_CODES catalog contains every GF##_T entry","status":"passed","title":"IMF_GFS_COFOG_CODES catalog contains every GF##_T entry","duration":1.5802189999999996,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form rejects the retired bare G02 / G07 / G09 / G10 codes","status":"passed","title":"rejects the retired bare G02 / G07 / G09 / G10 codes","duration":0.7656129999999735,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form every catalog value matches the GF##_T pattern","status":"passed","title":"every catalog value matches the GF##_T pattern","duration":0.5918980000000147,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953931016,"endTime":1787953931023.5918,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/cofog-codes.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF_FM_INDICATORS"],"fullName":"IMF_FM_INDICATORS exposes Fiscal Monitor indicators","status":"passed","title":"exposes Fiscal Monitor indicators","duration":3.6305469999999787,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]}],"startTime":1787953941146,"endTime":1787953941149.6306,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/fm.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF_WEO_INDICATORS"],"fullName":"IMF_WEO_INDICATORS exposes the canonical WEO headline indicator codes","status":"passed","title":"exposes the canonical WEO headline indicator codes","duration":3.7154969999999707,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY lists exactly the 9 WEO codes verified live on the Datamapper (2026-05-10)","status":"passed","title":"lists exactly the 9 WEO codes verified live on the Datamapper (2026-05-10)","duration":1.1996770000000083,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY flags the 4 IMF_WEO_INDICATORS codes that are SDMX-only (Datamapper returns empty envelopes)","status":"passed","title":"flags the 4 IMF_WEO_INDICATORS codes that are SDMX-only (Datamapper returns empty envelopes)","duration":0.45988099999999577,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY partitions IMF_WEO_INDICATORS into available + SDMX-only with no overlap","status":"passed","title":"partitions IMF_WEO_INDICATORS into available + SDMX-only with no overlap","duration":0.838279,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath builds the canonical WEO 9.0.0 SDMX path","status":"passed","title":"builds the canonical WEO 9.0.0 SDMX path","duration":0.46219500000000835,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath upper-cases the country code so case-mismatched ISO inputs still resolve","status":"passed","title":"upper-cases the country code so case-mismatched ISO inputs still resolve","duration":0.4054790000000139,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath URL-encodes both the indicator and country segments","status":"passed","title":"URL-encodes both the indicator and country segments","duration":0.46527100000002974,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]}],"startTime":1787953914385,"endTime":1787953914393.4653,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/weo.test.ts"},{"assertionResults":[{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues returns [] when the indicator node is absent","status":"passed","title":"returns [] when the indicator node is absent","duration":4.361456000000032,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues returns [] when the country node is absent","status":"passed","title":"returns [] when the country node is absent","duration":0.5310840000000212,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues sorts descending by year","status":"passed","title":"sorts descending by year","duration":0.5959760000000074,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues stamps projection years with the supplied vintage","status":"passed","title":"stamps projection years with the supplied vintage","duration":0.7619060000000104,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues drops null / \"n/a\" / NaN values and non-numeric years","status":"passed","title":"drops null / \"n/a\" / NaN values and non-numeric years","duration":0.4846870000000081,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues tolerates empty or missing raw envelopes","status":"passed","title":"tolerates empty or missing raw envelopes","duration":0.5608700000000226,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues tolerates partial Datamapper envelope nodes","status":"passed","title":"tolerates partial Datamapper envelope nodes","duration":0.4657930000000192,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators converts the indicators envelope into a Map keyed by code","status":"passed","title":"converts the indicators envelope into a Map keyed by code","duration":0.521837000000005,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators skips entries missing the dataset field (defensive against schema drift)","status":"passed","title":"skips entries missing the dataset field (defensive against schema drift)","duration":0.44312999999999647,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators returns an empty Map for null / undefined / missing-indicators envelopes","status":"passed","title":"returns an empty Map for null / undefined / missing-indicators envelopes","duration":0.5046949999999697,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators passes through optional lastUpdate when present, omits it otherwise","status":"passed","title":"passes through optional lastUpdate when present, omits it otherwise","duration":0.6519499999999994,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]}],"startTime":1787953895503,"endTime":1787953895512.6519,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/parsers/datamapper-envelope.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator parses the Datamapper envelope and returns descending years","status":"passed","title":"parses the Datamapper envelope and returns descending years","duration":6.8571790000000306,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator flags future years as projections and stamps the vintage","status":"passed","title":"flags future years as projections and stamps the vintage","duration":1.4260300000000257,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator returns an empty array when the response has no matching indicator","status":"passed","title":"returns an empty array when the response has no matching indicator","duration":1.3692440000000374,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator drops non-finite / null values defensively","status":"passed","title":"drops non-finite / null values defensively","duration":0.8031239999999684,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator truncates to the requested year count","status":"passed","title":"truncates to the requested year count","duration":0.8601100000000201,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator rejects non-positive or non-integer year counts","status":"passed","title":"rejects non-positive or non-integer year counts","duration":2.25645499999996,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator normalises ISO-3 input to uppercase before building the URL","status":"passed","title":"normalises ISO-3 input to uppercase before building the URL","duration":0.7198880000000258,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator sends an explicit User-Agent for IMF Datamapper compatibility","status":"passed","title":"sends an explicit User-Agent for IMF Datamapper compatibility","duration":0.7437930000000392,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator does NOT send Ocp-Apim-Subscription-Key on Datamapper requests (case-insensitive check)","status":"passed","title":"does NOT send Ocp-Apim-Subscription-Key on Datamapper requests (case-insensitive check)","duration":1.131988999999976,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicator → SDMX-only diagnostic"],"fullName":"ImfClient.getWeoIndicator → SDMX-only diagnostic throws ImfWeoSdmxOnlyError when Datamapper returns 0 points for a known SDMX-only code","status":"passed","title":"throws ImfWeoSdmxOnlyError when Datamapper returns 0 points for a known SDMX-only code","duration":1.0360200000000077,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicator → SDMX-only diagnostic"],"fullName":"ImfClient.getWeoIndicator → SDMX-only diagnostic returns [] (does NOT throw) for non-listed codes when the Datamapper envelope is genuinely empty","status":"passed","title":"returns [] (does NOT throw) for non-listed codes when the Datamapper envelope is genuinely empty","duration":0.8736250000000041,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]}],"startTime":1787953838196,"endTime":1787953838214.8735,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/datamapper.test.ts"},{"assertionResults":[{"ancestorTitles":["RETRY_AFTER_CAP_MS"],"fullName":"RETRY_AFTER_CAP_MS is exactly 30_000 ms (30 s)","status":"passed","title":"is exactly 30_000 ms (30 s)","duration":3.5394979999999805,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay applies exponential back-off: 1s / 2s / 4s","status":"passed","title":"applies exponential back-off: 1s / 2s / 4s","duration":0.5975290000000086,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay honours a positive Retry-After header (delta-seconds)","status":"passed","title":"honours a positive Retry-After header (delta-seconds)","duration":0.40156200000001263,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay caps Retry-After at 30 s to avoid pathological sleeps","status":"passed","title":"caps Retry-After at 30 s to avoid pathological sleeps","duration":0.36419200000000274,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay ignores invalid / non-positive Retry-After and falls back to exponential","status":"passed","title":"ignores invalid / non-positive Retry-After and falls back to exponential","duration":0.44747800000004645,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay clamps negative attempt numbers to attempt 0","status":"passed","title":"clamps negative attempt numbers to attempt 0","duration":0.46672399999999925,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour retries on 429 with back-off","status":"passed","title":"retries on 429 with back-off","duration":1004.1919700000001,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour retries on 5xx and gives up after maxRetries","status":"passed","title":"retries on 5xx and gives up after maxRetries","duration":1003.4863600000001,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry non-transient 4xx responses","status":"passed","title":"does not retry non-transient 4xx responses","duration":1.3253609999997025,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry JSON parse errors from successful responses","status":"passed","title":"does not retry JSON parse errors from successful responses","duration":0.9842530000000806,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry non-network TypeError programmer errors","status":"passed","title":"does not retry non-network TypeError programmer errors","duration":1.0113340000002609,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]}],"startTime":1787953897303,"endTime":1787953899320.0112,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/retry.test.ts"},{"assertionResults":[{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch prepends the SDMX base URL when path is missing the leading slash","status":"passed","title":"prepends the SDMX base URL when path is missing the leading slash","duration":5.245101999999974,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch sends Ocp-Apim-Subscription-Key header when configured via constructor option","status":"passed","title":"sends Ocp-Apim-Subscription-Key header when configured via constructor option","duration":0.9032310000000052,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch falls back to IMF_SDMX_SUBSCRIPTION_KEY env var when constructor option omitted","status":"passed","title":"falls back to IMF_SDMX_SUBSCRIPTION_KEY env var when constructor option omitted","duration":0.6800329999999803,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch omits Ocp-Apim-Subscription-Key when no key is configured","status":"passed","title":"omits Ocp-Apim-Subscription-Key when no key is configured","duration":0.663252,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch does NOT send the SDMX subscription key on Datamapper (WEO) calls","status":"passed","title":"does NOT send the SDMX subscription key on Datamapper (WEO) calls","duration":1.3095519999999965,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces a \"subscription key missing or invalid\" diagnostic on SDMX 401","status":"passed","title":"surfaces a \"subscription key missing or invalid\" diagnostic on SDMX 401","duration":2.4144110000000296,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces the auth-failure diagnostic on SDMX 403","status":"passed","title":"surfaces the auth-failure diagnostic on SDMX 403","duration":0.7203890000000115,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces the auth-failure diagnostic on SDMX 404 when no subscription key was sent (APIM mask)","status":"passed","title":"surfaces the auth-failure diagnostic on SDMX 404 when no subscription key was sent (APIM mask)","duration":0.697435999999982,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch does NOT mask a real 404 as auth-failure when a subscription key WAS sent","status":"passed","title":"does NOT mask a real 404 as auth-failure when a subscription key WAS sent","duration":1.1443029999999794,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) rewrites comma-form into /data/dataflow/.../ slash-form for sdmx/3.0","status":"passed","title":"rewrites comma-form into /data/dataflow/.../ slash-form for sdmx/3.0","duration":0.40620100000001,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) preserves the query string when rewriting","status":"passed","title":"preserves the query string when rewriting","duration":0.3674679999999739,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) handles missing leading slash on input","status":"passed","title":"handles missing leading slash on input","duration":0.3311899999999923,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) handles dataflow ref without a key suffix (structure-only query)","status":"passed","title":"handles dataflow ref without a key suffix (structure-only query)","duration":0.34366399999998976,"failureMessages":[],"location":{"line":213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) does NOT rewrite when base URL is not the sdmx/3.0 surface (defence-in-depth)","status":"passed","title":"does NOT rewrite when base URL is not the sdmx/3.0 surface (defence-in-depth)","duration":0.40086000000002286,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) does NOT double-rewrite an already slash-form path","status":"passed","title":"does NOT double-rewrite an already slash-form path","duration":0.34027699999995775,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) passes through non-data paths unchanged (e.g. /structure, /dataflow)","status":"passed","title":"passes through non-data paths unchanged (e.g. /structure, /dataflow)","duration":0.3651439999999866,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]}],"startTime":1787953827355,"endTime":1787953827371.3652,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/sdmx.test.ts"},{"assertionResults":[{"ancestorTitles":["compare subcommand"],"fullName":"compare subcommand exports runCompare as a function","status":"passed","title":"exports runCompare as a function","duration":3.6217909999999733,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]}],"startTime":1787953941589,"endTime":1787953941592.6218,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/compare.test.ts"},{"assertionResults":[{"ancestorTitles":["list-indicators subcommand"],"fullName":"list-indicators subcommand exports runListIndicators as a function","status":"passed","title":"exports runListIndicators as a function","duration":3.8603580000000193,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["list-indicators subcommand"],"fullName":"list-indicators subcommand exports runListDatamapperIndicators as a function","status":"passed","title":"exports runListDatamapperIndicators as a function","duration":0.5531860000000393,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]}],"startTime":1787953940702,"endTime":1787953940706.5532,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/list-indicators.test.ts"},{"assertionResults":[{"ancestorTitles":["sdmx subcommand"],"fullName":"sdmx subcommand exports runSdmx as a function","status":"passed","title":"exports runSdmx as a function","duration":3.5608179999999834,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]}],"startTime":1787953942023,"endTime":1787953942026.5608,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/sdmx.test.ts"},{"assertionResults":[{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget DEFAULT_WEO_VINTAGE is pinned to WEO-2026-04 (renderer + provenance reads this label)","status":"passed","title":"DEFAULT_WEO_VINTAGE is pinned to WEO-2026-04 (renderer + provenance reads this label)","duration":3.6802020000000084,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget WEO_FETCH_MAX_ATTEMPTS is a positive integer","status":"passed","title":"WEO_FETCH_MAX_ATTEMPTS is a positive integer","duration":0.6718979999999988,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget runWeo is exported as a function","status":"passed","title":"runWeo is exported as a function","duration":0.3963820000000169,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]}],"startTime":1787953939820,"endTime":1787953939825.3965,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/weo.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should use MCP_GATEWAY_API_KEY env var as auth token when MCP_AUTH_TOKEN is not set","status":"passed","title":"should use MCP_GATEWAY_API_KEY env var as auth token when MCP_AUTH_TOKEN is not set","duration":33.266028000000006,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should read gateway API key from MCP config file when env vars are unset","status":"passed","title":"should read gateway API key from MCP config file when env vars are unset","duration":6.445970000000045,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file has malformed JSON","status":"passed","title":"should return empty auth token when config file has malformed JSON","duration":6.622660999999994,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file is missing gateway field and mcpServers has no riksdag-regering","status":"passed","title":"should return empty auth token when config file is missing gateway field and mcpServers has no riksdag-regering","duration":8.400188999999955,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should read auth from mcpServers riksdag-regering headers when gateway.apiKey is absent","status":"passed","title":"should read auth from mcpServers riksdag-regering headers when gateway.apiKey is absent","duration":7.482710999999995,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should prefer gateway.apiKey over mcpServers when both are present","status":"passed","title":"should prefer gateway.apiKey over mcpServers when both are present","duration":7.953331999999989,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file does not exist","status":"passed","title":"should return empty auth token when config file does not exist","duration":6.497435999999993,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should respect GH_AW_MCP_CONFIG environment variable for config path","status":"passed","title":"should respect GH_AW_MCP_CONFIG environment variable for config path","duration":7.30258299999997,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should strip legacy \"Bearer \" prefix from MCP_AUTH_TOKEN env var","status":"passed","title":"should strip legacy \"Bearer \" prefix from MCP_AUTH_TOKEN env var","duration":7.010897,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should expose hasMcpGatewayApiKey() without leaking the token value","status":"passed","title":"should expose hasMcpGatewayApiKey() without leaking the token value","duration":1.0133070000000544,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953857326,"endTime":1787953857418.0134,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/auth.test.ts"},{"assertionResults":[{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should expose DEFAULT_MAX_RETRIES = 3","status":"passed","title":"should expose DEFAULT_MAX_RETRIES = 3","duration":6.862570000000005,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should expose RETRY_DELAY = 2000 ms","status":"passed","title":"should expose RETRY_DELAY = 2000 ms","duration":1.477076000000011,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should resolve a non-empty DEFAULT_MCP_SERVER_URL","status":"passed","title":"should resolve a non-empty DEFAULT_MCP_SERVER_URL","duration":1.310004000000049,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should default to 30000 ms when MCP_CLIENT_TIMEOUT_MS is unset","status":"passed","title":"getDefaultTimeout() should default to 30000 ms when MCP_CLIENT_TIMEOUT_MS is unset","duration":1.0238170000000082,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should honour numeric MCP_CLIENT_TIMEOUT_MS","status":"passed","title":"getDefaultTimeout() should honour numeric MCP_CLIENT_TIMEOUT_MS","duration":1.002597000000037,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should fall back to 30000 ms on invalid MCP_CLIENT_TIMEOUT_MS","status":"passed","title":"getDefaultTimeout() should fall back to 30000 ms on invalid MCP_CLIENT_TIMEOUT_MS","duration":1.084681000000046,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]}],"startTime":1787953922955,"endTime":1787953922968.0847,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/defaults.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should use MCP_SERVER_URL env var when explicitly set","status":"passed","title":"should use MCP_SERVER_URL env var when explicitly set","duration":31.23777899999999,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when MCP_GATEWAY_API_KEY is set and MCP_SERVER_URL is absent","status":"passed","title":"should auto-route to gateway URL when MCP_GATEWAY_API_KEY is set and MCP_SERVER_URL is absent","duration":6.492155999999966,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should honour MCP_GATEWAY_PORT env var when present","status":"passed","title":"should honour MCP_GATEWAY_PORT env var when present","duration":6.909756999999956,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when mcp-config.json has gateway.apiKey (AWF sandbox)","status":"passed","title":"should auto-route to gateway URL when mcp-config.json has gateway.apiKey (AWF sandbox)","duration":7.990421000000026,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when mcp-config.json has mcpServers riksdag-regering headers Authorization","status":"passed","title":"should auto-route to gateway URL when mcp-config.json has mcpServers riksdag-regering headers Authorization","duration":7.398672999999974,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should pick up gateway.port from mcp-config.json (gh-aw v0.69+ uses 8080)","status":"passed","title":"should pick up gateway.port from mcp-config.json (gh-aw v0.69+ uses 8080)","duration":7.53833400000002,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should fall back to direct onrender URL when no gateway indicators are present","status":"passed","title":"should fall back to direct onrender URL when no gateway indicators are present","duration":6.404742999999996,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]}],"startTime":1787953890393,"endTime":1787953890467.4048,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/gateway-resolver.test.ts"},{"assertionResults":[{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed should expose a frozen pattern list with the documented signatures","status":"passed","title":"should expose a frozen pattern list with the documented signatures","duration":4.112409999999954,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: document not indexed","status":"passed","title":"classifies known signal as not_indexed: document not indexed","duration":0.7681880000000092,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: No document for that id","status":"passed","title":"classifies known signal as not_indexed: No document for that id","duration":0.4659819999999968,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: Document not found in this riksmöte","status":"passed","title":"classifies known signal as not_indexed: Document not found in this riksmöte","duration":0.35066600000004655,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: dok_id not found: H101FiU01","status":"passed","title":"classifies known signal as not_indexed: dok_id not found: H101FiU01","duration":0.4142250000000445,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed does not classify bare \"404\"/\"not found\" as not_indexed","status":"passed","title":"does not classify bare \"404\"/\"not found\" as not_indexed","duration":0.47043100000001914,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed suppresses not_indexed when message is a transport error","status":"passed","title":"suppresses not_indexed when message is a transport error","duration":0.6749740000000202,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed uses dok_id-aware fallback when the dok_id appears in the message","status":"passed","title":"uses dok_id-aware fallback when the dok_id appears in the message","duration":0.3972639999999501,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed does not use dok_id fallback when message is a transport error","status":"passed","title":"does not use dok_id fallback when message is a transport error","duration":0.5252839999999992,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed returns false for empty / undefined messages","status":"passed","title":"returns false for empty / undefined messages","duration":0.4592999999999847,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]}],"startTime":1787953922048,"endTime":1787953922056.5254,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/error-classification/not-indexed.test.ts"},{"assertionResults":[{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: MCP server error: 500","status":"passed","title":"matches transport signature: MCP server error: 500","duration":3.7337009999999964,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: MCP transport error","status":"passed","title":"matches transport signature: MCP transport error","duration":0.46216500000002725,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: Server error","status":"passed","title":"matches transport signature: Server error","duration":0.39471900000000915,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: /endpoint not reachable","status":"passed","title":"matches transport signature: /endpoint not reachable","duration":0.30724600000002056,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: ECONNREFUSED 127.0.0.1:8080","status":"passed","title":"matches transport signature: ECONNREFUSED 127.0.0.1:8080","duration":0.29605400000002646,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: ETIMEDOUT","status":"passed","title":"matches transport signature: ETIMEDOUT","duration":0.45442100000002483,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: fetch failed","status":"passed","title":"matches transport signature: fetch failed","duration":0.3072050000000104,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: network unreachable","status":"passed","title":"matches transport signature: network unreachable","duration":0.26374400000003106,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: gateway timeout","status":"passed","title":"matches transport signature: gateway timeout","duration":0.5006870000000276,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 500","status":"passed","title":"matches transport signature: HTTP 500","duration":0.2800039999999626,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 502","status":"passed","title":"matches transport signature: HTTP 502","duration":0.30770599999999604,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 503","status":"passed","title":"matches transport signature: HTTP 503","duration":0.3192579999999907,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: document not indexed","status":"passed","title":"does not match application-level signature: document not indexed","duration":0.2944209999999998,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: no document for that id","status":"passed","title":"does not match application-level signature: no document for that id","duration":0.2629929999999945,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: dok_id not found: H101FiU01","status":"passed","title":"does not match application-level signature: dok_id not found: H101FiU01","duration":0.30784599999998363,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: Method not found","status":"passed","title":"does not match application-level signature: Method not found","duration":0.35244999999997617,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: Invalid tool name","status":"passed","title":"does not match application-level signature: Invalid tool name","duration":0.26020699999997987,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.385550999999964,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches HTTP 500/502/503 as word boundary, not 5001 / 5023","status":"passed","title":"matches HTTP 500/502/503 as word boundary, not 5001 / 5023","duration":0.4242950000000292,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953935015,"endTime":1787953935025.4243,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/error-classification/transport.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should fetch calendar events with date range","status":"passed","title":"should fetch calendar events with date range","duration":5.967242999999996,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should pass optional org and akt parameters","status":"passed","title":"should pass optional org and akt parameters","duration":1.554079999999999,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should return empty array when response has no events key","status":"passed","title":"should return empty array when response has no events key","duration":0.7157599999999888,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should throw when the server returns the degraded-kalender sentinel","status":"passed","title":"should throw when the server returns the degraded-kalender sentinel","duration":2.476456999999982,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should throw when the server returns a rawHtml-only sentinel (no error field)","status":"passed","title":"should throw when the server returns a rawHtml-only sentinel (no error field)","duration":1.0033990000000017,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should include the upstream error message in the thrown error","status":"passed","title":"should include the upstream error message in the thrown error","duration":0.868186000000037,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]}],"startTime":1787953895049,"endTime":1787953895061.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/calendar.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface searchDocuments routes to search_dokument","status":"passed","title":"searchDocuments routes to search_dokument","duration":5.168538000000012,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface fetchGovernmentDocuments routes to search_regering","status":"passed","title":"fetchGovernmentDocuments routes to search_regering","duration":0.7355069999999841,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface searchDocuments returns empty array when result has no documents key","status":"passed","title":"searchDocuments returns empty array when result has no documents key","duration":1.1430310000000077,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface exposes fetchDocumentDetails / fetchDocumentDetailsWithCoverage on the public surface","status":"passed","title":"exposes fetchDocumentDetails / fetchDocumentDetailsWithCoverage on the public surface","duration":0.4562750000000051,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953918955,"endTime":1787953918963.4563,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/documents.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/members — fetchMPs"],"fullName":"methods/members — fetchMPs routes to search_ledamoter tool","status":"passed","title":"routes to search_ledamoter tool","duration":5.573677000000032,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/members — fetchMPs"],"fullName":"methods/members — fetchMPs passes parti / valkrets / status filters when provided","status":"passed","title":"passes parti / valkrets / status filters when provided","duration":1.4286649999999668,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953928781,"endTime":1787953928788.4287,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/members.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should fetch committee reports with limit","status":"passed","title":"should fetch committee reports with limit","duration":5.714129999999955,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should pass optional rm and organ parameters","status":"passed","title":"should pass optional rm and organ parameters","duration":1.6414429999999811,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should return empty array when response has no reports key","status":"passed","title":"should return empty array when response has no reports key","duration":0.6624510000000328,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should fetch propositions with default limit","status":"passed","title":"should fetch propositions with default limit","duration":0.9808869999999956,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should pass optional rm parameter","status":"passed","title":"should pass optional rm parameter","duration":0.7922229999999786,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should call correct tool name (get_propositioner)","status":"passed","title":"should call correct tool name (get_propositioner)","duration":0.6874470000000201,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should return empty array when response has no propositions key","status":"passed","title":"should return empty array when response has no propositions key","duration":0.5409530000000018,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]}],"startTime":1787953893689,"endTime":1787953893700.541,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/reports.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/speeches — searchSpeeches"],"fullName":"methods/speeches — searchSpeeches routes to search_anforanden tool","status":"passed","title":"routes to search_anforanden tool","duration":5.2085630000000265,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/speeches — searchSpeeches"],"fullName":"methods/speeches — searchSpeeches returns empty array when result has no speeches key","status":"passed","title":"returns empty array when result has no speeches key","duration":1.5353450000000066,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]}],"startTime":1787953933276,"endTime":1787953933282.5354,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/speeches.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingRecords routes to search_voteringar","status":"passed","title":"fetchVotingRecords routes to search_voteringar","duration":5.675726999999995,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingGroup routes to get_voting_group","status":"passed","title":"fetchVotingGroup routes to get_voting_group","duration":0.9652169999999956,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingRecords returns empty array when result is empty","status":"passed","title":"fetchVotingRecords returns empty array when result is empty","duration":1.362922000000026,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]}],"startTime":1787953922514,"endTime":1787953922522.363,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/votes.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should make successful HTTP request with JSON-RPC 2.0","status":"passed","title":"should make successful HTTP request with JSON-RPC 2.0","duration":5.979917,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should send correct JSON-RPC 2.0 request format","status":"passed","title":"should send correct JSON-RPC 2.0 request format","duration":1.3657670000000053,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should include custom headers from config in requests","status":"passed","title":"should include custom headers from config in requests","duration":0.7727869999999939,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not override runtime headers with custom headers","status":"passed","title":"should not override runtime headers with custom headers","duration":0.9869580000000155,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should handle JSON-RPC error responses","status":"passed","title":"should handle JSON-RPC error responses","duration":2.5552040000000034,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on non-ok HTTP response","status":"passed","title":"should throw on non-ok HTTP response","duration":0.7908610000000067,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on 404 response","status":"passed","title":"should throw on 404 response","duration":0.8740369999999871,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not retry on non-network errors","status":"passed","title":"should not retry on non-network errors","duration":0.6778090000000248,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should track statistics","status":"passed","title":"should track statistics","duration":0.8481879999999933,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should use default empty params when none provided","status":"passed","title":"should use default empty params when none provided","duration":0.8119499999999675,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not add prefix when using direct server URL","status":"passed","title":"should not add prefix when using direct server URL","duration":0.5337499999999977,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should use bare tool names when using MCP gateway URL","status":"passed","title":"should use bare tool names when using MCP gateway URL","duration":0.6029690000000301,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on Internal error from gateway without retry","status":"passed","title":"should throw on Internal error from gateway without retry","duration":0.893481999999949,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]}],"startTime":1787953836785,"endTime":1787953836802.8936,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/jsonrpc.test.ts"},{"assertionResults":[{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay returns RETRY_DELAY for retryCount=0 (first retry)","status":"passed","title":"returns RETRY_DELAY for retryCount=0 (first retry)","duration":3.898499999999956,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay doubles per retry (2^N exponential backoff)","status":"passed","title":"doubles per retry (2^N exponential backoff)","duration":0.5693360000000212,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay clamps negative retryCount to 0 (no underflow)","status":"passed","title":"clamps negative retryCount to 0 (no underflow)","duration":0.5306039999999825,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for AbortError (timeout-induced)","status":"passed","title":"returns true for AbortError (timeout-induced)","duration":0.4246350000000234,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Network error","status":"passed","title":"returns true for transient signature: Network error","duration":0.43985399999996844,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: ECONNREFUSED","status":"passed","title":"returns true for transient signature: ECONNREFUSED","duration":0.46401800000001003,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Connection closed","status":"passed","title":"returns true for transient signature: Connection closed","duration":0.39987899999999854,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Too Many Requests","status":"passed","title":"returns true for transient signature: Too Many Requests","duration":0.32899600000001783,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: fetch failed: network issue","status":"passed","title":"returns true for transient signature: fetch failed: network issue","duration":0.3890089999999873,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns false for HTTP server errors (non-network)","status":"passed","title":"returns false for HTTP server errors (non-network)","duration":0.509003000000007,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError handles empty / undefined message safely","status":"passed","title":"handles empty / undefined message safely","duration":0.3997279999999819,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should retry on network error","status":"passed","title":"should retry on network error","duration":2.7843030000000226,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should retry on ECONNREFUSED error","status":"passed","title":"should retry on ECONNREFUSED error","duration":0.8871310000000108,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should fail after max retries","status":"passed","title":"should fail after max retries","duration":2.723569999999995,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]}],"startTime":1787953896417,"endTime":1787953896432.7236,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/retry.test.ts"},{"assertionResults":[{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should expose EXTERNAL_URL_FETCH_TIMEOUT_MS = 15000 ms","status":"passed","title":"should expose EXTERNAL_URL_FETCH_TIMEOUT_MS = 15000 ms","duration":3.872370999999987,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return body text on 2xx response","status":"passed","title":"should return body text on 2xx response","duration":0.9122689999999807,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should pass Accept header on the outgoing request","status":"passed","title":"should pass Accept header on the outgoing request","duration":1.7587629999999876,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return null on non-2xx response and log a warning","status":"passed","title":"should return null on non-2xx response and log a warning","duration":2.380708000000027,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return null on network error and log a warning","status":"passed","title":"should return null on network error and log a warning","duration":0.87717200000003,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should honour the timeoutMs override","status":"passed","title":"should honour the timeoutMs override","duration":6.230586000000017,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953908188,"endTime":1787953908204.2305,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/timeout.test.ts"},{"assertionResults":[{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets MAX_ENRICHMENT_PER_TYPE === 5 (verbatim)","status":"passed","title":"MAX_ENRICHMENT_PER_TYPE === 5 (verbatim)","duration":3.9841600000000312,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets LONG_HORIZON_FULL_TEXT_FLOOR === 10 (verbatim)","status":"passed","title":"LONG_HORIZON_FULL_TEXT_FLOOR === 10 (verbatim)","duration":0.49435499999998456,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets floor is strictly greater than per-type cap (so long-horizon raises the budget)","status":"passed","title":"floor is strictly greater than per-type cap (so long-horizon raises the budget)","duration":0.5419449999999983,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets every re-export site exposes the same constant value","status":"passed","title":"every re-export site exposes the same constant value","duration":0.6273750000000291,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]}],"startTime":1787953926558,"endTime":1787953926563.6274,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/enrichment/full-text-selection.test.ts"},{"assertionResults":[{"ancestorTitles":["persistDownloadedData — collision avoidance"],"fullName":"persistDownloadedData — collision avoidance should suffix duplicate doc IDs within a batch","status":"passed","title":"should suffix duplicate doc IDs within a batch","duration":6.165906000000007,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]}],"startTime":1787953927888,"endTime":1787953927894.166,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/collision-avoidance.test.ts"},{"assertionResults":[{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should write data files without _metadata injection","status":"passed","title":"should write data files without _metadata injection","duration":5.894926999999996,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should write sidecar .meta.json alongside data file","status":"passed","title":"should write sidecar .meta.json alongside data file","duration":1.4810640000000035,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should handle all document types","status":"passed","title":"should handle all document types","duration":2.291080000000022,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should create date-stamped vote directories","status":"passed","title":"should create date-stamped vote directories","duration":0.9375550000000317,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should skip null documents","status":"passed","title":"should skip null documents","duration":0.8772619999999733,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should handle empty data gracefully","status":"passed","title":"should handle empty data gracefully","duration":0.6538040000000365,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should allow custom mcpToolMap overrides","status":"passed","title":"should allow custom mcpToolMap overrides","duration":0.9016679999999724,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should return correct dataRoot in result","status":"passed","title":"should return correct dataRoot in result","duration":0.45475099999998747,"failureMessages":[],"location":{"line":129,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should persist events to date-stamped directories","status":"passed","title":"should persist events to date-stamped directories","duration":1.2265769999999634,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should use \"undated\" for events without valid date","status":"passed","title":"should use \"undated\" for events without valid date","duration":0.7201580000000263,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should skip null events","status":"passed","title":"should skip null events","duration":0.7105910000000222,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should write metadata with correct tool name","status":"passed","title":"should write metadata with correct tool name","duration":0.7398349999999709,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should handle \"from\" field as date fallback","status":"passed","title":"should handle \"from\" field as date fallback","duration":0.774530000000027,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should persist MP profiles using intressent_id","status":"passed","title":"should persist MP profiles using intressent_id","duration":0.9272260000000188,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should skip null MP entries","status":"passed","title":"should skip null MP entries","duration":0.48722200000003113,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should fall back to resolveDocId when intressent_id missing","status":"passed","title":"should fall back to resolveDocId when intressent_id missing","duration":0.6809149999999704,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should write metadata with correct tool name","status":"passed","title":"should write metadata with correct tool name","duration":0.6566090000000031,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","getDataRoot"],"fullName":"data-persistence — documents getDataRoot should return path ending with analysis/data","status":"passed","title":"should return path ending with analysis/data","duration":0.7261090000000081,"failureMessages":[],"location":{"line":217,"column":5},"meta":{},"tags":[]}],"startTime":1787953837269,"endTime":1787953837290.726,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/documents.test.ts"},{"assertionResults":[{"ancestorTitles":["persistIMFData"],"fullName":"persistIMFData stores IMF data under imf/{indicator}/{country}.json with sidecar","status":"passed","title":"stores IMF data under imf/{indicator}/{country}.json with sidecar","duration":5.202682999999979,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistIMFData"],"fullName":"persistIMFData omits optional provenance fields when not supplied","status":"passed","title":"omits optional provenance fields when not supplied","duration":1.1440020000000004,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953929229,"endTime":1787953929235.144,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/imf.test.ts"},{"assertionResults":[{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should store generic MCP tool response in server/tool subdirs","status":"passed","title":"should store generic MCP tool response in server/tool subdirs","duration":5.482817000000011,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should use UUID-based fallback for empty id","status":"passed","title":"should use UUID-based fallback for empty id","duration":1.505899999999997,"failureMessages":[],"location":{"line":54,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should derive riksmote from call.params.rm when not explicitly provided","status":"passed","title":"should derive riksmote from call.params.rm when not explicitly provided","duration":0.8621449999999982,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should use explicit riksmote param over call.params.rm","status":"passed","title":"should use explicit riksmote param over call.params.rm","duration":0.772927999999979,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should sanitize raw `../` in server and tool names","status":"passed","title":"should sanitize raw `../` in server and tool names","duration":1.0999590000000126,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should handle dots-only server names","status":"passed","title":"should handle dots-only server names","duration":0.8183520000000044,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should neutralise URL-encoded traversal (%2e%2e/) in server name","status":"passed","title":"should neutralise URL-encoded traversal (%2e%2e/) in server name","duration":1.0081279999999992,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should neutralise uppercase URL-encoded traversal (%2E%2E%2F) in tool name","status":"passed","title":"should neutralise uppercase URL-encoded traversal (%2E%2E%2F) in tool name","duration":0.8741770000000315,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should strip embedded NUL bytes (\\0) from server, tool and id","status":"passed","title":"should strip embedded NUL bytes (\\0) from server, tool and id","duration":1.1712029999999913,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should reject absolute path injection in tool name (unix)","status":"passed","title":"should reject absolute path injection in tool name (unix)","duration":0.7685690000000136,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should reject absolute path injection in tool name (windows-style)","status":"passed","title":"should reject absolute path injection in tool name (windows-style)","duration":0.8152270000000499,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should sanitize multi-level traversal (..\\..\\..)","status":"passed","title":"should sanitize multi-level traversal (..\\..\\..)","duration":0.7670259999999871,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]}],"startTime":1787953848214,"endTime":1787953848230.767,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/mcp-response.test.ts"},{"assertionResults":[{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta strips in-memory MCP annotations from the raw `.json` file","status":"passed","title":"strips in-memory MCP annotations from the raw `.json` file","duration":5.117803000000038,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta writes provenance to a separate `.meta.json` sidecar","status":"passed","title":"writes provenance to a separate `.meta.json` sidecar","duration":1.0094899999999711,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta produces byte-identical `.json` output across repeated calls (parallel-workflow safety)","status":"passed","title":"produces byte-identical `.json` output across repeated calls (parallel-workflow safety)","duration":0.8665129999999976,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta does not mutate the input document (defensive copy)","status":"passed","title":"does not mutate the input document (defensive copy)","duration":0.6601359999999659,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta throws if baseFilename does not end with .json","status":"passed","title":"throws if baseFilename does not end with .json","duration":1.5057800000000157,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta creates the output directory if it does not exist","status":"passed","title":"creates the output directory if it does not exist","duration":0.8306349999999725,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]}],"startTime":1787953892299,"endTime":1787953892308.8306,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/meta-sidecar.test.ts"},{"assertionResults":[{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should prefer dok_id when available","status":"passed","title":"should prefer dok_id when available","duration":3.9750829999999837,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should fall back to titel when dok_id is missing","status":"passed","title":"should fall back to titel when dok_id is missing","duration":0.5754870000000096,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should fall back through dokument_id, id, rel_dok_id, titel, title","status":"passed","title":"should fall back through dokument_id, id, rel_dok_id, titel, title","duration":0.5085820000000467,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should use index-based fallback when all fields empty","status":"passed","title":"should use index-based fallback when all fields empty","duration":0.4536099999999692,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should trim whitespace from identifiers","status":"passed","title":"should trim whitespace from identifiers","duration":0.3724280000000135,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should skip empty string fields","status":"passed","title":"should skip empty string fields","duration":0.43667799999997214,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953932336,"endTime":1787953932342.4368,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/resolve-doc-id.test.ts"},{"assertionResults":[{"ancestorTitles":["persistRiksbankData"],"fullName":"persistRiksbankData should store Riksbank artifacts with sidecar","status":"passed","title":"should store Riksbank artifacts with sidecar","duration":5.242125999999985,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953938072,"endTime":1787953938077.2422,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/riksbank.test.ts"},{"assertionResults":[{"ancestorTitles":["persistSCBData"],"fullName":"persistSCBData should store SCB table data with sidecar","status":"passed","title":"should store SCB table data with sidecar","duration":5.432492000000025,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistSCBData"],"fullName":"persistSCBData should work without query parameter","status":"passed","title":"should work without query parameter","duration":1.1137259999999856,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]}],"startTime":1787953936742,"endTime":1787953936749.1138,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/scb.test.ts"},{"assertionResults":[{"ancestorTitles":["persistDownloadedData — sidecar invariant"],"fullName":"persistDownloadedData — sidecar invariant strips in-memory MCP coverage metadata so data files remain byte-identical","status":"passed","title":"strips in-memory MCP coverage metadata so data files remain byte-identical","duration":6.434578999999985,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistDownloadedData — sidecar invariant"],"fullName":"persistDownloadedData — sidecar invariant produces byte-identical data files for parallel writes (collision-free)","status":"passed","title":"produces byte-identical data files for parallel writes (collision-free)","duration":1.3760059999999612,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]}],"startTime":1787953903509,"endTime":1787953903517.376,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/sidecar-invariant.test.ts"},{"assertionResults":[{"ancestorTitles":["persistStatskontoretData"],"fullName":"persistStatskontoretData should store Statskontoret data with dataset/artifact structure and sidecar","status":"passed","title":"should store Statskontoret data with dataset/artifact structure and sidecar","duration":5.26262399999996,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistStatskontoretData"],"fullName":"persistStatskontoretData should sanitize dataset and artifact names","status":"passed","title":"should sanitize dataset and artifact names","duration":1.2154260000000363,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953929676,"endTime":1787953929683.2153,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/statskontoret.test.ts"},{"assertionResults":[{"ancestorTitles":["persistWorldBankData"],"fullName":"persistWorldBankData should store data with indicator/country structure","status":"passed","title":"should store data with indicator/country structure","duration":5.277702000000033,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953937632,"endTime":1787953937637.2776,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/world-bank.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBluf"],"fullName":"extractBluf extracts the prose paragraph following a `## BLUF` heading","status":"passed","title":"extracts the prose paragraph following a `## BLUF` heading","duration":4.0693899999999985,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf accepts a decorated BLUF heading (e.g. with an emoji prefix)","status":"passed","title":"accepts a decorated BLUF heading (e.g. with an emoji prefix)","duration":0.9120270000000232,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf returns null when no BLUF heading is present","status":"passed","title":"returns null when no BLUF heading is present","duration":0.4880939999999896,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf skips blockquote / table / list-only first paragraphs (returns null)","status":"passed","title":"skips blockquote / table / list-only first paragraphs (returns null)","duration":0.4543610000000058,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf handles a BLUF block that runs to end-of-file (no trailing heading)","status":"passed","title":"handles a BLUF block that runs to end-of-file (no trailing heading)","duration":0.440936000000022,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf returns no violations when no BLUF heading is present","status":"passed","title":"returns no violations when no BLUF heading is present","duration":1.0765250000000037,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf returns no violations when BLUF is within bounds and carries an anchor","status":"passed","title":"returns no violations when BLUF is within bounds and carries an anchor","duration":1.1941959999999767,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags a BLUF that is too short with the `bluf-too-short` code","status":"passed","title":"flags a BLUF that is too short with the `bluf-too-short` code","duration":1.2135719999999992,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags a BLUF that exceeds the maximum prose length","status":"passed","title":"flags a BLUF that exceeds the maximum prose length","duration":0.6902120000000309,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags missing evidence anchor when prose has no dok_id / URL / vote id","status":"passed","title":"flags missing evidence anchor when prose has no dok_id / URL / vote id","duration":0.4896370000000161,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity returns no violations for empty text","status":"passed","title":"returns no violations for empty text","duration":1.1097280000000183,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity flags prose with words but zero evidence anchors","status":"passed","title":"flags prose with words but zero evidence anchors","duration":0.9794540000000325,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity passes when density is within the default 200 words-per-anchor budget","status":"passed","title":"passes when density is within the default 200 words-per-anchor budget","duration":0.4327599999999734,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity flags density that exceeds the default 200 words-per-anchor threshold","status":"passed","title":"flags density that exceeds the default 200 words-per-anchor threshold","duration":0.6402779999999666,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity honours the per-article-type threshold from reference-quality-thresholds.json","status":"passed","title":"honours the per-article-type threshold from reference-quality-thresholds.json","duration":1.3751050000000191,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity falls back to the default threshold for unknown article types","status":"passed","title":"falls back to the default threshold for unknown article types","duration":0.6928670000000352,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance returns [] when no `retrieved_at:` lines are present","status":"passed","title":"returns [] when no `retrieved_at:` lines are present","duration":0.5374970000000303,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance returns [] when all provenance vintages are within 6 months","status":"passed","title":"returns [] when all provenance vintages are within 6 months","duration":0.8643280000000004,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance emits `stale-economic-provenance` when vintage exceeds 6 months without annotation","status":"passed","title":"emits `stale-economic-provenance` when vintage exceeds 6 months without annotation","duration":0.7343849999999748,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance does not flag stale vintage when an annotation comment is on the preceding line","status":"passed","title":"does not flag stale vintage when an annotation comment is on the preceding line","duration":0.45905900000002475,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance lists up to two stale vintages in the message sample","status":"passed","title":"lists up to two stale vintages in the message sample","duration":0.7874040000000377,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases"],"fullName":"checkBannedPhrases returns [] when no banned phrases are present","status":"passed","title":"returns [] when no banned phrases are present","duration":1.227749000000017,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases"],"fullName":"checkBannedPhrases emits `banned-phrase-detected` when at least one phrase appears in the text","status":"passed","title":"emits `banned-phrase-detected` when at least one phrase appears in the text","duration":1.0484329999999886,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) emits `missing-banned-phrase-list` when the canonical JSON cannot be found","status":"passed","title":"emits `missing-banned-phrase-list` when the canonical JSON cannot be found","duration":0.9930390000000102,"failureMessages":[],"location":{"line":301,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) treats a malformed JSON file as a missing list (returns null)","status":"passed","title":"treats a malformed JSON file as a missing list (returns null)","duration":0.9265950000000203,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) treats a JSON file without `allPhrases` as a missing list","status":"passed","title":"treats a JSON file without `allPhrases` as a missing list","duration":0.8390210000000025,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) deduplicates entries (case-insensitive) and skips blanks / non-strings","status":"passed","title":"deduplicates entries (case-insensitive) and skips blanks / non-strings","duration":1.0503770000000259,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]}],"startTime":1787953787360,"endTime":1787953787386.0503,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/article/rules.test.ts"},{"assertionResults":[{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses 2026-02-14-test-en.html → en","status":"passed","title":"parses 2026-02-14-test-en.html → en","duration":3.665734000000043,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses 2026-04-09-committee-de.html → de","status":"passed","title":"parses 2026-04-09-committee-de.html → de","duration":0.5561519999999973,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses anything-fr.html → fr","status":"passed","title":"parses anything-fr.html → fr","duration":0.4253770000000259,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses weekly-es.html → es","status":"passed","title":"parses weekly-es.html → es","duration":0.2817380000000185,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses rtl-ar.html → ar","status":"passed","title":"parses rtl-ar.html → ar","duration":0.4490610000000288,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses rtl-he.html → he","status":"passed","title":"parses rtl-he.html → he","duration":0.364612999999963,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-ja.html → ja","status":"passed","title":"parses cjk-ja.html → ja","duration":0.44487299999997276,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-ko.html → ko","status":"passed","title":"parses cjk-ko.html → ko","duration":0.2626319999999964,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-zh.html → zh","status":"passed","title":"parses cjk-zh.html → zh","duration":0.293309000000022,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-da.html → da","status":"passed","title":"parses nordic-da.html → da","duration":0.29927000000003545,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-no.html → no","status":"passed","title":"parses nordic-no.html → no","duration":0.49425500000000966,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-fi.html → fi","status":"passed","title":"parses nordic-fi.html → fi","duration":0.2642640000000256,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses euro-nl.html → nl","status":"passed","title":"parses euro-nl.html → nl","duration":0.2965650000000437,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses svensk-sv.html → sv","status":"passed","title":"parses svensk-sv.html → sv","duration":0.26316300000002,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode returns null when filename has no trailing language suffix","status":"passed","title":"returns null when filename has no trailing language suffix","duration":0.3959509999999682,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode rejects suffixes longer than two letters","status":"passed","title":"rejects suffixes longer than two letters","duration":0.38187499999997954,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG maps Norwegian filename suffix \"no\" to BCP-47 \"nb\" (preferred)","status":"passed","title":"maps Norwegian filename suffix \"no\" to BCP-47 \"nb\" (preferred)","duration":0.4178719999999885,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG maps every other language suffix to itself","status":"passed","title":"maps every other language suffix to itself","duration":0.8536080000000084,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG covers all 14 supported languages","status":"passed","title":"covers all 14 supported languages","duration":0.7412380000000098,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps Norwegian to nb_NO (not no_NO)","status":"passed","title":"maps Norwegian to nb_NO (not no_NO)","duration":0.4681860000000029,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps en to en_US","status":"passed","title":"maps en to en_US","duration":0.4925519999999892,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps sv to sv_SE","status":"passed","title":"maps sv to sv_SE","duration":0.3975849999999923,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps da to da_DK","status":"passed","title":"maps da to da_DK","duration":0.4456239999999525,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps fi to fi_FI","status":"passed","title":"maps fi to fi_FI","duration":0.3724480000000199,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps de to de_DE","status":"passed","title":"maps de to de_DE","duration":0.4339819999999577,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps fr to fr_FR","status":"passed","title":"maps fr to fr_FR","duration":0.3751320000000078,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps es to es_ES","status":"passed","title":"maps es to es_ES","duration":0.44222800000000007,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps nl to nl_NL","status":"passed","title":"maps nl to nl_NL","duration":0.4711529999999584,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ar to ar_SA","status":"passed","title":"maps ar to ar_SA","duration":0.3975940000000264,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps he to he_IL","status":"passed","title":"maps he to he_IL","duration":0.454830999999956,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ja to ja_JP","status":"passed","title":"maps ja to ja_JP","duration":0.6392460000000142,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ko to ko_KR","status":"passed","title":"maps ko to ko_KR","duration":0.7275220000000218,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps zh to zh_CN","status":"passed","title":"maps zh to zh_CN","duration":0.5198430000000371,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["NON_SWEDISH_LANGS"],"fullName":"NON_SWEDISH_LANGS does not include Swedish","status":"passed","title":"does not include Swedish","duration":0.5298020000000179,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["NON_SWEDISH_LANGS"],"fullName":"NON_SWEDISH_LANGS includes the 13 non-Swedish supported languages","status":"passed","title":"includes the 13 non-Swedish supported languages","duration":1.4127960000000144,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]}],"startTime":1787953908628,"endTime":1787953908648.4128,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/language.test.ts"},{"assertionResults":[{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker detects English files as non-Swedish targets","status":"passed","title":"detects English files as non-Swedish targets","duration":6.513847999999996,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker skips Swedish files","status":"passed","title":"skips Swedish files","duration":1.1738579999999956,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker ignores files without a language code","status":"passed","title":"ignores files without a language code","duration":0.8005190000000084,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker recurses into subdirectories","status":"passed","title":"recurses into subdirectories","duration":0.9265250000000265,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes exits 1 when data-translate markers remain","status":"passed","title":"exits 1 when data-translate markers remain","duration":1.1089069999999879,"failureMessages":[],"location":{"line":96,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes exits 0 for fully translated articles","status":"passed","title":"exits 0 for fully translated articles","duration":0.7940570000000093,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes extracts a sample marker count when markers remain","status":"passed","title":"extracts a sample marker count when markers remain","duration":0.9262949999999819,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) passes Norwegian articles with consistent lang=\"nb\"","status":"passed","title":"passes Norwegian articles with consistent lang=\"nb\"","duration":1.7382949999999937,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) fails Norwegian articles that still use lang=\"no\"","status":"passed","title":"fails Norwegian articles that still use lang=\"no\"","duration":1.1317090000000007,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) fails Arabic articles missing dir=\"rtl\"","status":"passed","title":"fails Arabic articles missing dir=\"rtl\"","duration":1.4655850000000328,"failureMessages":[],"location":{"line":158,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Content leakage detection (soft warning)"],"fullName":"validateNewsTranslations — orchestrator integration spine Content leakage detection (soft warning) warns on EN paragraph leakage in non-EN articles without failing","status":"passed","title":"warns on EN paragraph leakage in non-EN articles without failing","duration":1.4602449999999862,"failureMessages":[],"location":{"line":172,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Content leakage detection (soft warning)"],"fullName":"validateNewsTranslations — orchestrator integration spine Content leakage detection (soft warning) warns on banned English phrases in translations","status":"passed","title":"warns on banned English phrases in translations","duration":0.9985389999999938,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","AI_MUST_REPLACE marker detection (restored regression)"],"fullName":"validateNewsTranslations — orchestrator integration spine AI_MUST_REPLACE marker detection (restored regression) fails with exit 1 when an AI_MUST_REPLACE comment remains","status":"passed","title":"fails with exit 1 when an AI_MUST_REPLACE comment remains","duration":1.4575099999999566,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","AI_MUST_REPLACE marker detection (restored regression)"],"fullName":"validateNewsTranslations — orchestrator integration spine AI_MUST_REPLACE marker detection (restored regression) reports distinct sample marker names","status":"passed","title":"reports distinct sample marker names","duration":0.863476999999989,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]}],"startTime":1787953832465,"endTime":1787953832486.8635,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles finds top-level HTML files","status":"passed","title":"finds top-level HTML files","duration":5.358584000000008,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles recurses into subdirectories","status":"passed","title":"recurses into subdirectories","duration":1.279115000000047,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles ignores non-HTML files","status":"passed","title":"ignores non-HTML files","duration":1.39358900000002,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles returns an empty array (and logs) for a missing directory","status":"passed","title":"returns an empty array (and logs) for a missing directory","duration":0.6805550000000267,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns the EN sibling path when it exists","status":"passed","title":"returns the EN sibling path when it exists","duration":0.7296959999999899,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns null when the EN sibling is missing","status":"passed","title":"returns null when the EN sibling is missing","duration":0.7496240000000398,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns null when the filename has no language suffix","status":"passed","title":"returns null when the filename has no language suffix","duration":0.5825010000000361,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath derives EN sibling regardless of source language (fr, ja, ar)","status":"passed","title":"derives EN sibling regardless of source language (fr, ja, ar)","duration":0.823421000000053,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]}],"startTime":1787953901554,"endTime":1787953901565.8235,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/walker.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers returns null when no AI_MUST_REPLACE markers are present","status":"passed","title":"returns null when no AI_MUST_REPLACE markers are present","duration":4.322443000000021,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers detects a single AI_MUST_REPLACE comment","status":"passed","title":"detects a single AI_MUST_REPLACE comment","duration":2.1368610000000103,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers counts multiple markers and reports up to three distinct sample names","status":"passed","title":"counts multiple markers and reports up to three distinct sample names","duration":1.733746999999994,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers ignores AI_MUST_REPLACE text outside of HTML comments","status":"passed","title":"ignores AI_MUST_REPLACE text outside of HTML comments","duration":0.6151419999999916,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers records the filename even when the language suffix is missing","status":"passed","title":"records the filename even when the language suffix is missing","duration":0.6089699999999993,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers throws a contextualised error when the file cannot be read","status":"passed","title":"throws a contextualised error when the file cannot be read","duration":1.3889609999999948,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]}],"startTime":1787953901995,"endTime":1787953902006.389,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/ai-must-replace.test.ts"},{"assertionResults":[{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration passes when html[lang]=\"nb\", og:locale=\"nb_NO\", inLanguage=\"nb\"","status":"passed","title":"passes when html[lang]=\"nb\", og:locale=\"nb_NO\", inLanguage=\"nb\"","duration":4.732761000000039,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags html[lang]=\"no\" as expected=\"nb\", actual=\"no\"","status":"passed","title":"flags html[lang]=\"no\" as expected=\"nb\", actual=\"no\"","duration":0.9353310000000192,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags inLanguage=\"no\" as expected=\"nb\", actual=\"no\"","status":"passed","title":"flags inLanguage=\"no\" as expected=\"nb\", actual=\"no\"","duration":0.5901759999999854,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags og:locale=\"no_NO\" as expected=\"nb_NO\", actual=\"no_NO\"","status":"passed","title":"flags og:locale=\"no_NO\" as expected=\"nb_NO\", actual=\"no_NO\"","duration":0.5747860000000173,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute flags Arabic articles missing dir=\"rtl\"","status":"passed","title":"flags Arabic articles missing dir=\"rtl\"","duration":0.9245809999999892,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute flags Hebrew articles missing dir=\"rtl\"","status":"passed","title":"flags Hebrew articles missing dir=\"rtl\"","duration":0.7497440000000211,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute passes Arabic articles that declare dir=\"rtl\"","status":"passed","title":"passes Arabic articles that declare dir=\"rtl\"","duration":0.5707089999999653,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles passes consistent English articles","status":"passed","title":"passes consistent English articles","duration":0.6079280000000153,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles reports html[lang] mismatch when the tag disagrees with the filename","status":"passed","title":"reports html[lang] mismatch when the tag disagrees with the filename","duration":0.9226370000000088,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles does not report og:locale when the meta tag is absent","status":"passed","title":"does not report og:locale when the meta tag is absent","duration":0.819184000000007,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]}],"startTime":1787953868766,"endTime":1787953868777.819,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/bcp47.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs returns only paragraphs longer than the minimum length","status":"passed","title":"returns only paragraphs longer than the minimum length","duration":5.10769300000004,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs strips inline tags inside paragraphs","status":"passed","title":"strips inline tags inside paragraphs","duration":0.6272239999999556,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs removes <script> and <style> blocks before extraction","status":"passed","title":"removes <script> and <style> blocks before extraction","duration":0.5482569999999782,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs collapses whitespace inside paragraphs","status":"passed","title":"collapses whitespace inside paragraphs","duration":0.44676700000002256,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null when fileLang is \"en\" (EN articles are not checked)","status":"passed","title":"returns null when fileLang is \"en\" (EN articles are not checked)","duration":1.0737010000000282,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects EN paragraph leakage when the same paragraph appears in EN and DE files","status":"passed","title":"detects EN paragraph leakage when the same paragraph appears in EN and DE files","duration":1.214033000000029,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects Swedish leakage phrases in non-SV articles","status":"passed","title":"detects Swedish leakage phrases in non-SV articles","duration":1.081865999999991,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects banned English boilerplate phrases in translations","status":"passed","title":"detects banned English boilerplate phrases in translations","duration":0.7180850000000305,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null for fully translated DE articles with no leakage","status":"passed","title":"returns null for fully translated DE articles with no leakage","duration":0.8411550000000148,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null when the translated body has no paragraphs above the minimum length","status":"passed","title":"returns null when the translated body has no paragraphs above the minimum length","duration":0.5762290000000121,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage handles a missing EN source file gracefully (phrase rules still run)","status":"passed","title":"handles a missing EN source file gracefully (phrase rules still run)","duration":0.7344549999999685,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]}],"startTime":1787953855856,"endTime":1787953855869.7344,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/body-leakage.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns passed=true when no markers are present","status":"passed","title":"returns passed=true when no markers are present","duration":4.171379999999999,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent counts every data-translate=\"true\" occurrence","status":"passed","title":"counts every data-translate=\"true\" occurrence","duration":0.9191710000000057,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns up to three sample Swedish snippets from the markers","status":"passed","title":"returns up to three sample Swedish snippets from the markers","duration":1.5466260000000034,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns an error record when the file cannot be read","status":"passed","title":"returns an error record when the file cannot be read","duration":0.6128070000000321,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent does not match standalone strings without the full attribute","status":"passed","title":"does not match standalone strings without the full attribute","duration":0.5411129999999957,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]}],"startTime":1787953912651,"endTime":1787953912659.541,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/untranslated.test.ts"}],"coverageMap":{"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/analysis-gate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/analysis-gate.ts","statementMap":{"0":{"start":{"line":71,"column":36},"end":{"line":71,"column":null}},"1":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"2":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"3":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"4":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"6":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"7":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"8":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"9":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"10":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"11":{"start":{"line":84,"column":23},"end":{"line":84,"column":null}},"12":{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},"13":{"start":{"line":85,"column":2},"end":{"line":89,"column":null}}},"fnMap":{"0":{"name":"validateAnalysisGate","decl":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"loc":{"start":{"line":70,"column":33},"end":{"line":90,"column":null}},"line":70},"1":{"name":"(anonymous_1)","decl":{"start":{"line":84,"column":30},"end":{"line":84,"column":38}},"loc":{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},"line":84}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":180,"13":3},"f":{"0":3,"1":180},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":14,"seen":{"f:68:22:68:Infinity":0,"s:71:36:71:Infinity":0,"s:73:2:73:Infinity":1,"s:74:2:74:Infinity":2,"s:75:2:75:Infinity":3,"s:76:2:76:Infinity":4,"s:77:2:77:Infinity":5,"s:78:2:78:Infinity":6,"s:79:2:79:Infinity":7,"s:80:2:80:Infinity":8,"s:81:2:81:Infinity":9,"s:82:2:82:Infinity":10,"s:84:23:84:Infinity":11,"f:84:30:84:38":1,"s:84:44:84:53":12,"s:85:2:89:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/artifact-existence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/artifact-existence.ts","statementMap":{"0":{"start":{"line":20,"column":37},"end":{"line":20,"column":null}},"1":{"start":{"line":21,"column":2},"end":{"line":45,"column":null}},"2":{"start":{"line":22,"column":21},"end":{"line":22,"column":null}},"3":{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},"4":{"start":{"line":24,"column":6},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},"6":{"start":{"line":31,"column":6},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":6},"end":{"line":43,"column":null}},"8":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkArtifactExistence","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":39}},"loc":{"start":{"line":19,"column":79},"end":{"line":47,"column":null}},"line":19}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},{"start":{"line":30,"column":11},"end":{"line":44,"column":null}}],"line":23},"1":{"loc":{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},{"start":{"line":37,"column":11},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":161,"3":161,"4":47,"5":114,"6":1,"7":113,"8":7},"f":{"0":7},"b":{"0":[47,114],"1":[1,113]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":9,"seen":{"f:19:16:19:39":0,"s:20:37:20:Infinity":0,"s:21:2:45:Infinity":1,"s:22:21:22:Infinity":2,"b:23:4:44:Infinity:30:11:44:Infinity":0,"s:23:4:44:Infinity":3,"s:24:6:29:Infinity":4,"b:30:11:44:Infinity:37:11:44:Infinity":1,"s:30:11:44:Infinity":5,"s:31:6:36:Infinity":6,"s:38:6:43:Infinity":7,"s:46:2:46:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/coalition-mathematics.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/coalition-mathematics.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":19},"end":{"line":28,"column":null}},"6":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"7":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":43,"column":null}},"9":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkCoalitionMathematics","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":47,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},{"start":{"line":37,"column":9},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":2,"8":4,"9":6},"f":{"0":7},"b":{"0":[1,6],"1":[2,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":10,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:28:19:28:Infinity":5,"b:30:2:44:Infinity:37:9:44:Infinity":1,"s:30:2:44:Infinity":6,"s:31:4:36:Infinity":7,"s:38:4:43:Infinity":8,"s:46:2:46:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/artifact-inventory.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/artifact-inventory.ts","statementMap":{"0":{"start":{"line":68,"column":65},"end":{"line":78,"column":null}},"1":{"start":{"line":85,"column":65},"end":{"line":88,"column":null}},"2":{"start":{"line":95,"column":65},"end":{"line":101,"column":null}},"3":{"start":{"line":108,"column":65},"end":{"line":116,"column":null}},"4":{"start":{"line":123,"column":69},"end":{"line":128,"column":null}},"5":{"start":{"line":131,"column":62},"end":{"line":133,"column":null}},"6":{"start":{"line":132,"column":36},"end":{"line":132,"column":46}},"7":{"start":{"line":136,"column":61},"end":{"line":138,"column":null}},"8":{"start":{"line":137,"column":39},"end":{"line":137,"column":56}},"9":{"start":{"line":137,"column":69},"end":{"line":137,"column":79}},"10":{"start":{"line":141,"column":59},"end":{"line":143,"column":null}},"11":{"start":{"line":142,"column":39},"end":{"line":142,"column":54}},"12":{"start":{"line":142,"column":67},"end":{"line":142,"column":77}},"13":{"start":{"line":149,"column":52},"end":{"line":154,"column":null}},"14":{"start":{"line":160,"column":54},"end":{"line":173,"column":null}},"15":{"start":{"line":179,"column":53},"end":{"line":188,"column":null}},"16":{"start":{"line":194,"column":30},"end":{"line":194,"column":null}},"17":{"start":{"line":202,"column":2},"end":{"line":202,"column":null}},"18":{"start":{"line":210,"column":32},"end":{"line":212,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":132,"column":25},"end":{"line":132,"column":30}},"loc":{"start":{"line":132,"column":36},"end":{"line":132,"column":46}},"line":132},"1":{"name":"(anonymous_1)","decl":{"start":{"line":137,"column":25},"end":{"line":137,"column":33}},"loc":{"start":{"line":137,"column":39},"end":{"line":137,"column":56}},"line":137},"2":{"name":"(anonymous_2)","decl":{"start":{"line":137,"column":58},"end":{"line":137,"column":63}},"loc":{"start":{"line":137,"column":69},"end":{"line":137,"column":79}},"line":137},"3":{"name":"(anonymous_3)","decl":{"start":{"line":142,"column":25},"end":{"line":142,"column":33}},"loc":{"start":{"line":142,"column":39},"end":{"line":142,"column":54}},"line":142},"4":{"name":"(anonymous_4)","decl":{"start":{"line":142,"column":56},"end":{"line":142,"column":61}},"loc":{"start":{"line":142,"column":67},"end":{"line":142,"column":77}},"line":142},"5":{"name":"escapeRegexLiteral","decl":{"start":{"line":201,"column":9},"end":{"line":201,"column":28}},"loc":{"start":{"line":201,"column":47},"end":{"line":203,"column":null}},"line":201}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":23,"4":23,"5":23,"6":529,"7":23,"8":529,"9":368,"10":23,"11":529,"12":506,"13":23,"14":23,"15":23,"16":23,"17":184,"18":23},"f":{"0":529,"1":529,"2":368,"3":529,"4":506,"5":184},"b":{},"meta":{"lastBranch":0,"lastFunction":6,"lastStatement":19,"seen":{"s:68:65:78:Infinity":0,"s:85:65:88:Infinity":1,"s:95:65:101:Infinity":2,"s:108:65:116:Infinity":3,"s:123:69:128:Infinity":4,"s:131:62:133:Infinity":5,"f:132:25:132:30":0,"s:132:36:132:46":6,"s:136:61:138:Infinity":7,"f:137:25:137:33":1,"s:137:39:137:56":8,"f:137:58:137:63":2,"s:137:69:137:79":9,"s:141:59:143:Infinity":10,"f:142:25:142:33":3,"s:142:39:142:54":11,"f:142:56:142:61":4,"s:142:67:142:77":12,"s:149:52:154:Infinity":13,"s:160:54:173:Infinity":14,"s:179:53:188:Infinity":15,"s:194:30:194:Infinity":16,"f:201:9:201:28":5,"s:202:2:202:Infinity":17,"s:210:32:212:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/comparative-international.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/comparative-international.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":29,"column":28},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":27},"end":{"line":31,"column":null}},"7":{"start":{"line":33,"column":20},"end":{"line":38,"column":null}},"8":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"9":{"start":{"line":34,"column":27},"end":{"line":34,"column":null}},"10":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"11":{"start":{"line":35,"column":52},"end":{"line":35,"column":null}},"12":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"13":{"start":{"line":36,"column":67},"end":{"line":36,"column":null}},"14":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"15":{"start":{"line":40,"column":24},"end":{"line":40,"column":null}},"16":{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},"17":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"18":{"start":{"line":50,"column":4},"end":{"line":55,"column":null}},"19":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"checkComparativeInternational","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":59,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":40},"end":{"line":33,"column":48}},"loc":{"start":{"line":33,"column":57},"end":{"line":38,"column":3}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":27},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":27},"end":{"line":30,"column":null}},{"start":{"line":31,"column":4},"end":{"line":31,"column":null}}],"line":30},"2":{"loc":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":35},"4":{"loc":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"5":{"loc":{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},{"start":{"line":49,"column":9},"end":{"line":56,"column":null}}],"line":42},"6":{"loc":{"start":{"line":42,"column":6},"end":{"line":42,"column":43}},"type":"binary-expr","locations":[{"start":{"line":42,"column":6},"end":{"line":42,"column":27}},{"start":{"line":42,"column":27},"end":{"line":42,"column":43}}],"line":42}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":7,"8":36,"9":20,"10":16,"11":4,"12":12,"13":4,"14":8,"15":7,"16":7,"17":1,"18":5,"19":6},"f":{"0":7,"1":36},"b":{"0":[1,6],"1":[6,4],"2":[20,16],"3":[4,12],"4":[4,8],"5":[1,5],"6":[7,2]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":20,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:29:28:29:Infinity":5,"s:30:27:31:Infinity":6,"b:30:27:30:Infinity:31:4:31:Infinity":1,"s:33:20:38:Infinity":7,"f:33:40:33:48":1,"b:34:4:34:Infinity:undefined:undefined:undefined:undefined":2,"s:34:4:34:Infinity":8,"s:34:27:34:Infinity":9,"b:35:4:35:Infinity:undefined:undefined:undefined:undefined":3,"s:35:4:35:Infinity":10,"s:35:52:35:Infinity":11,"b:36:4:36:Infinity:undefined:undefined:undefined:undefined":4,"s:36:4:36:Infinity":12,"s:36:67:36:Infinity":13,"s:37:4:37:Infinity":14,"s:40:24:40:Infinity":15,"b:42:2:56:Infinity:49:9:56:Infinity":5,"s:42:2:56:Infinity":16,"b:42:6:42:27:42:27:42:43":6,"s:43:4:48:Infinity":17,"s:50:4:55:Infinity":18,"s:58:2:58:Infinity":19}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/evidence-citations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/evidence-citations.ts","statementMap":{"0":{"start":{"line":24,"column":37},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}}},"fnMap":{"0":{"name":"checkEvidenceCitations","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":23,"column":30},"end":{"line":30,"column":null}},"line":23}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"f:21:22:21:Infinity":0,"s:24:37:24:Infinity":0,"s:26:2:26:Infinity":1,"s:27:2:27:Infinity":2,"s:29:2:29:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/devils-advocate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/devils-advocate.ts","statementMap":{"0":{"start":{"line":28,"column":37},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":19},"end":{"line":29,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"3":{"start":{"line":30,"column":29},"end":{"line":30,"column":null}},"4":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"5":{"start":{"line":33,"column":20},"end":{"line":35,"column":null}},"6":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":44,"column":null}},"9":{"start":{"line":46,"column":4},"end":{"line":51,"column":null}},"10":{"start":{"line":57,"column":33},"end":{"line":60,"column":null}},"11":{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},"12":{"start":{"line":62,"column":4},"end":{"line":67,"column":null}},"13":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"14":{"start":{"line":71,"column":24},"end":{"line":74,"column":null}},"15":{"start":{"line":75,"column":17},"end":{"line":77,"column":null}},"16":{"start":{"line":77,"column":22},"end":{"line":77,"column":59}},"17":{"start":{"line":78,"column":23},"end":{"line":78,"column":null}},"18":{"start":{"line":78,"column":44},"end":{"line":78,"column":57}},"19":{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},"20":{"start":{"line":80,"column":4},"end":{"line":85,"column":null}},"21":{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},"22":{"start":{"line":87,"column":4},"end":{"line":92,"column":null}},"23":{"start":{"line":94,"column":4},"end":{"line":99,"column":null}},"24":{"start":{"line":102,"column":2},"end":{"line":102,"column":null}}},"fnMap":{"0":{"name":"checkDevilsAdvocate","decl":{"start":{"line":25,"column":22},"end":{"line":25,"column":null}},"loc":{"start":{"line":27,"column":30},"end":{"line":103,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":77,"column":5},"end":{"line":77,"column":13}},"loc":{"start":{"line":77,"column":22},"end":{"line":77,"column":59}},"line":77},"2":{"name":"(anonymous_2)","decl":{"start":{"line":78,"column":30},"end":{"line":78,"column":36}},"loc":{"start":{"line":78,"column":44},"end":{"line":78,"column":57}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":30},"1":{"loc":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":28},"end":{"line":36,"column":47}},{"start":{"line":36,"column":47},"end":{"line":36,"column":null}}],"line":36},"2":{"loc":{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},{"start":{"line":45,"column":9},"end":{"line":52,"column":null}}],"line":38},"3":{"loc":{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":61},"4":{"loc":{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},{"start":{"line":86,"column":9},"end":{"line":100,"column":null}}],"line":79},"5":{"loc":{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},{"start":{"line":93,"column":9},"end":{"line":100,"column":null}}],"line":86}},"s":{"0":8,"1":8,"2":8,"3":2,"4":6,"5":6,"6":6,"7":8,"8":0,"9":6,"10":6,"11":6,"12":1,"13":1,"14":5,"15":5,"16":34,"17":5,"18":14,"19":5,"20":0,"21":5,"22":1,"23":4,"24":5},"f":{"0":8,"1":34,"2":14},"b":{"0":[2,6],"1":[6,0],"2":[0,6],"3":[1,5],"4":[0,5],"5":[1,4]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":25,"seen":{"f:25:22:25:Infinity":0,"s:28:37:28:Infinity":0,"s:29:19:29:Infinity":1,"b:30:2:30:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:30:Infinity":2,"s:30:29:30:Infinity":3,"s:32:18:32:Infinity":4,"s:33:20:35:Infinity":5,"s:36:16:36:Infinity":6,"b:36:28:36:47:36:47:36:Infinity":1,"b:38:2:52:Infinity:45:9:52:Infinity":2,"s:38:2:52:Infinity":7,"s:39:4:44:Infinity":8,"s:46:4:51:Infinity":9,"s:57:33:60:Infinity":10,"b:61:2:69:Infinity:undefined:undefined:undefined:undefined":3,"s:61:2:69:Infinity":11,"s:62:4:67:Infinity":12,"s:68:4:68:Infinity":13,"s:71:24:74:Infinity":14,"s:75:17:77:Infinity":15,"f:77:5:77:13":1,"s:77:22:77:59":16,"s:78:23:78:Infinity":17,"f:78:30:78:36":2,"s:78:44:78:57":18,"b:79:2:100:Infinity:86:9:100:Infinity":4,"s:79:2:100:Infinity":19,"s:80:4:85:Infinity":20,"b:86:9:100:Infinity:93:9:100:Infinity":5,"s:86:9:100:Infinity":21,"s:87:4:92:Infinity":22,"s:94:4:99:Infinity":23,"s:102:2:102:Infinity":24}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief-h1.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief-h1.ts","statementMap":{"0":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"2":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"3":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"5":{"start":{"line":28,"column":14},"end":{"line":28,"column":null}},"6":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"7":{"start":{"line":34,"column":80},"end":{"line":39,"column":null}},"8":{"start":{"line":41,"column":73},"end":{"line":58,"column":null}},"9":{"start":{"line":61,"column":2},"end":{"line":70,"column":null}},"10":{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},"11":{"start":{"line":63,"column":6},"end":{"line":68,"column":null}},"12":{"start":{"line":74,"column":18},"end":{"line":78,"column":null}},"13":{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},"14":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":95,"column":18},"end":{"line":95,"column":null}},"16":{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},"17":{"start":{"line":97,"column":27},"end":{"line":102,"column":null}},"18":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"19":{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},"20":{"start":{"line":104,"column":6},"end":{"line":110,"column":null}},"21":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"22":{"start":{"line":114,"column":2},"end":{"line":124,"column":null}},"23":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"24":{"start":{"line":116,"column":6},"end":{"line":121,"column":null}},"25":{"start":{"line":122,"column":6},"end":{"line":122,"column":null}},"26":{"start":{"line":125,"column":20},"end":{"line":125,"column":null}},"27":{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},"28":{"start":{"line":127,"column":4},"end":{"line":133,"column":null}},"29":{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},"30":{"start":{"line":139,"column":4},"end":{"line":145,"column":null}},"31":{"start":{"line":158,"column":19},"end":{"line":158,"column":null}},"32":{"start":{"line":159,"column":20},"end":{"line":159,"column":null}},"33":{"start":{"line":160,"column":22},"end":{"line":160,"column":null}},"34":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"35":{"start":{"line":161,"column":74},"end":{"line":161,"column":null}},"36":{"start":{"line":162,"column":2},"end":{"line":203,"column":null}},"37":{"start":{"line":163,"column":25},"end":{"line":168,"column":null}},"38":{"start":{"line":164,"column":21},"end":{"line":164,"column":36}},"39":{"start":{"line":165,"column":18},"end":{"line":165,"column":24}},"40":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"41":{"start":{"line":169,"column":10},"end":{"line":177,"column":null}},"42":{"start":{"line":170,"column":6},"end":{"line":177,"column":null}},"43":{"start":{"line":178,"column":24},"end":{"line":178,"column":null}},"44":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"45":{"start":{"line":179,"column":33},"end":{"line":179,"column":null}},"46":{"start":{"line":180,"column":4},"end":{"line":200,"column":null}},"47":{"start":{"line":181,"column":27},"end":{"line":181,"column":null}},"48":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"49":{"start":{"line":182,"column":37},"end":{"line":182,"column":null}},"50":{"start":{"line":183,"column":37},"end":{"line":183,"column":null}},"51":{"start":{"line":184,"column":6},"end":{"line":188,"column":null}},"52":{"start":{"line":185,"column":8},"end":{"line":185,"column":null}},"53":{"start":{"line":187,"column":8},"end":{"line":187,"column":null}},"54":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"55":{"start":{"line":189,"column":22},"end":{"line":189,"column":null}},"56":{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},"57":{"start":{"line":191,"column":8},"end":{"line":197,"column":null}},"58":{"start":{"line":198,"column":8},"end":{"line":198,"column":null}}},"fnMap":{"0":{"name":"extractExecutiveBriefH1","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":40}},"loc":{"start":{"line":23,"column":72},"end":{"line":31,"column":null}},"line":23},"1":{"name":"checkH1Placeholders","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":36}},"loc":{"start":{"line":60,"column":82},"end":{"line":71,"column":null}},"line":60},"2":{"name":"checkH1Boilerplate","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":35}},"loc":{"start":{"line":73,"column":81},"end":{"line":88,"column":null}},"line":73},"3":{"name":"checkH1RendererCollapse","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"loc":{"start":{"line":94,"column":8},"end":{"line":147,"column":null}},"line":94},"4":{"name":"(anonymous_4)","decl":{"start":{"line":97,"column":35},"end":{"line":97,"column":null}},"loc":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"line":99},"5":{"name":"checkH1AcrossDaysUniqueness","decl":{"start":{"line":149,"column":16},"end":{"line":149,"column":null}},"loc":{"start":{"line":154,"column":8},"end":{"line":204,"column":null}},"line":154},"6":{"name":"(anonymous_6)","decl":{"start":{"line":164,"column":7},"end":{"line":164,"column":15}},"loc":{"start":{"line":164,"column":21},"end":{"line":164,"column":36}},"line":164},"7":{"name":"(anonymous_7)","decl":{"start":{"line":165,"column":7},"end":{"line":165,"column":12}},"loc":{"start":{"line":165,"column":18},"end":{"line":165,"column":24}},"line":165},"8":{"name":"(anonymous_8)","decl":{"start":{"line":166,"column":7},"end":{"line":166,"column":15}},"loc":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"line":166},"9":{"name":"(anonymous_9)","decl":{"start":{"line":169,"column":10},"end":{"line":169,"column":25}},"loc":{"start":{"line":170,"column":6},"end":{"line":177,"column":null}},"line":170}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"2":{"loc":{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":79},"4":{"loc":{"start":{"line":79,"column":6},"end":{"line":79,"column":55}},"type":"binary-expr","locations":[{"start":{"line":79,"column":6},"end":{"line":79,"column":39}},{"start":{"line":79,"column":39},"end":{"line":79,"column":55}}],"line":79},"5":{"loc":{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":96},"6":{"loc":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},{"start":{"line":100,"column":8},"end":{"line":100,"column":null}},{"start":{"line":101,"column":8},"end":{"line":101,"column":null}}],"line":99},"7":{"loc":{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":103},"8":{"loc":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":115},"9":{"loc":{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},{"start":{"line":134,"column":9},"end":{"line":146,"column":null}}],"line":126},"10":{"loc":{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":134},"11":{"loc":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"12":{"loc":{"start":{"line":161,"column":6},"end":{"line":161,"column":74}},"type":"binary-expr","locations":[{"start":{"line":161,"column":6},"end":{"line":161,"column":50}},{"start":{"line":161,"column":50},"end":{"line":161,"column":74}}],"line":161},"13":{"loc":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"type":"binary-expr","locations":[{"start":{"line":166,"column":21},"end":{"line":166,"column":54}},{"start":{"line":166,"column":54},"end":{"line":166,"column":69}}],"line":166},"14":{"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":179},"15":{"loc":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"16":{"loc":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},{"start":{},"end":{}}],"line":189},"17":{"loc":{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},"type":"if","locations":[{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},{"start":{},"end":{}}],"line":190}},"s":{"0":27,"1":27,"2":21,"3":6,"4":6,"5":6,"6":3,"7":4,"8":4,"9":18,"10":72,"11":5,"12":18,"13":18,"14":1,"15":18,"16":18,"17":2,"18":1,"19":2,"20":1,"21":2,"22":16,"23":59,"24":3,"25":3,"26":16,"27":16,"28":1,"29":15,"30":1,"31":18,"32":18,"33":18,"34":18,"35":16,"36":2,"37":2,"38":4,"39":4,"40":4,"41":2,"42":4,"43":2,"44":2,"45":0,"46":2,"47":2,"48":2,"49":0,"50":2,"51":2,"52":2,"53":0,"54":2,"55":0,"56":2,"57":1,"58":1},"f":{"0":27,"1":18,"2":18,"3":18,"4":1,"5":18,"6":4,"7":4,"8":4,"9":4},"b":{"0":[21,6],"1":[3,3],"2":[5,67],"3":[1,17],"4":[18,17],"5":[2,16],"6":[1,1,1],"7":[1,1],"8":[3,56],"9":[1,15],"10":[1,14],"11":[16,2],"12":[18,2],"13":[4,4],"14":[0,2],"15":[0,2],"16":[0,2],"17":[1,1]},"meta":{"lastBranch":18,"lastFunction":10,"lastStatement":59,"seen":{"f:23:16:23:40":0,"s:24:21:24:Infinity":0,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":1,"s:25:18:25:Infinity":2,"s:27:17:27:Infinity":3,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":1,"s:28:2:28:Infinity":4,"s:28:14:28:Infinity":5,"s:30:2:30:Infinity":6,"s:34:80:39:Infinity":7,"s:41:73:58:Infinity":8,"f:60:16:60:36":1,"s:61:2:70:Infinity":9,"b:62:4:69:Infinity:undefined:undefined:undefined:undefined":2,"s:62:4:69:Infinity":10,"s:63:6:68:Infinity":11,"f:73:16:73:35":2,"s:74:18:78:Infinity":12,"b:79:2:87:Infinity:undefined:undefined:undefined:undefined":3,"s:79:2:87:Infinity":13,"b:79:6:79:39:79:39:79:55":4,"s:80:4:86:Infinity":14,"f:90:16:90:Infinity":3,"s:95:18:95:Infinity":15,"b:96:2:113:Infinity:undefined:undefined:undefined:undefined":5,"s:96:2:113:Infinity":16,"s:97:27:102:Infinity":17,"f:97:35:97:Infinity":4,"s:99:8:101:Infinity":18,"b:99:8:99:Infinity:100:8:100:Infinity:101:8:101:Infinity":6,"b:103:4:111:Infinity:undefined:undefined:undefined:undefined":7,"s:103:4:111:Infinity":19,"s:104:6:110:Infinity":20,"s:112:4:112:Infinity":21,"s:114:2:124:Infinity":22,"b:115:4:123:Infinity:undefined:undefined:undefined:undefined":8,"s:115:4:123:Infinity":23,"s:116:6:121:Infinity":24,"s:122:6:122:Infinity":25,"s:125:20:125:Infinity":26,"b:126:2:146:Infinity:134:9:146:Infinity":9,"s:126:2:146:Infinity":27,"s:127:4:133:Infinity":28,"b:134:9:146:Infinity:undefined:undefined:undefined:undefined":10,"s:134:9:146:Infinity":29,"s:139:4:145:Infinity":30,"f:149:16:149:Infinity":5,"s:158:19:158:Infinity":31,"s:159:20:159:Infinity":32,"s:160:22:160:Infinity":33,"b:161:2:161:Infinity:undefined:undefined:undefined:undefined":11,"s:161:2:161:Infinity":34,"b:161:6:161:50:161:50:161:74":12,"s:161:74:161:Infinity":35,"s:162:2:203:Infinity":36,"s:163:25:168:Infinity":37,"f:164:7:164:15":6,"s:164:21:164:36":38,"f:165:7:165:12":7,"s:165:18:165:24":39,"f:166:7:166:15":8,"s:166:21:166:69":40,"b:166:21:166:54:166:54:166:69":13,"s:169:10:177:Infinity":41,"f:169:10:169:25":9,"s:170:6:177:Infinity":42,"s:178:24:178:Infinity":43,"b:179:4:179:Infinity:undefined:undefined:undefined:undefined":14,"s:179:4:179:Infinity":44,"s:179:33:179:Infinity":45,"s:180:4:200:Infinity":46,"s:181:27:181:Infinity":47,"b:182:6:182:Infinity:undefined:undefined:undefined:undefined":15,"s:182:6:182:Infinity":48,"s:182:37:182:Infinity":49,"s:183:37:183:Infinity":50,"s:184:6:188:Infinity":51,"s:185:8:185:Infinity":52,"s:187:8:187:Infinity":53,"b:189:6:189:Infinity:undefined:undefined:undefined:undefined":16,"s:189:6:189:Infinity":54,"s:189:22:189:Infinity":55,"b:190:6:199:Infinity:undefined:undefined:undefined:undefined":17,"s:190:6:199:Infinity":56,"s:191:8:197:Infinity":57,"s:198:8:198:Infinity":58}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-d-structure.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-d-structure.ts","statementMap":{"0":{"start":{"line":21,"column":37},"end":{"line":21,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}}},"fnMap":{"0":{"name":"checkFamilyDStructure","decl":{"start":{"line":18,"column":22},"end":{"line":18,"column":null}},"loc":{"start":{"line":20,"column":30},"end":{"line":27,"column":null}},"line":20}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"f:18:22:18:Infinity":0,"s:21:37:21:Infinity":0,"s:23:2:23:Infinity":1,"s:24:2:24:Infinity":2,"s:26:2:26:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief.ts","statementMap":{"0":{"start":{"line":41,"column":37},"end":{"line":41,"column":null}},"1":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"2":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"3":{"start":{"line":43,"column":29},"end":{"line":43,"column":null}},"4":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"5":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"7":{"start":{"line":49,"column":4},"end":{"line":54,"column":null}},"8":{"start":{"line":57,"column":23},"end":{"line":57,"column":null}},"9":{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},"10":{"start":{"line":59,"column":4},"end":{"line":64,"column":null}},"11":{"start":{"line":70,"column":30},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":20},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":13},"end":{"line":72,"column":null}},"14":{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},"15":{"start":{"line":74,"column":4},"end":{"line":80,"column":null}},"16":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"17":{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},"18":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"19":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"20":{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},"21":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"22":{"start":{"line":93,"column":4},"end":{"line":98,"column":null}},"23":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"checkExecutiveBrief","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":40,"column":30},"end":{"line":102,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":91,"column":12},"end":{"line":91,"column":20}},"loc":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"line":91}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":71,"column":20},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":20},"end":{"line":71,"column":75}},{"start":{"line":71,"column":75},"end":{"line":71,"column":null}}],"line":71},"4":{"loc":{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},{"start":{"line":81,"column":9},"end":{"line":86,"column":null}}],"line":73},"5":{"loc":{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":88},"6":{"loc":{"start":{"line":89,"column":4},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},{"start":{"line":91,"column":4},"end":{"line":91,"column":null}}],"line":89},"7":{"loc":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"type":"binary-expr","locations":[{"start":{"line":91,"column":26},"end":{"line":91,"column":39}},{"start":{"line":91,"column":39},"end":{"line":91,"column":74}}],"line":91}},"s":{"0":21,"1":21,"2":21,"3":1,"4":20,"5":20,"6":20,"7":1,"8":20,"9":20,"10":1,"11":20,"12":20,"13":21,"14":21,"15":2,"16":18,"17":18,"18":18,"19":18,"20":20,"21":14,"22":6,"23":20},"f":{"0":21,"1":14},"b":{"0":[1,20],"1":[1,19],"2":[1,19],"3":[20,0],"4":[2,18],"5":[6,14],"6":[20,19,18],"7":[14,14]},"meta":{"lastBranch":8,"lastFunction":2,"lastStatement":24,"seen":{"f:38:22:38:Infinity":0,"s:41:37:41:Infinity":0,"s:42:19:42:Infinity":1,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":2,"s:43:29:43:Infinity":3,"s:45:18:45:Infinity":4,"s:47:18:47:Infinity":5,"b:48:2:55:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:55:Infinity":6,"s:49:4:54:Infinity":7,"s:57:23:57:Infinity":8,"b:58:2:65:Infinity:undefined:undefined:undefined:undefined":2,"s:58:2:65:Infinity":9,"s:59:4:64:Infinity":10,"s:70:30:70:Infinity":11,"s:71:20:71:Infinity":12,"b:71:20:71:75:71:75:71:Infinity":3,"s:72:13:72:Infinity":13,"b:73:2:86:Infinity:81:9:86:Infinity":4,"s:73:2:86:Infinity":14,"s:74:4:80:Infinity":15,"s:82:4:82:Infinity":16,"s:83:4:83:Infinity":17,"s:84:4:84:Infinity":18,"s:85:4:85:Infinity":19,"b:88:2:99:Infinity:undefined:undefined:undefined:undefined":5,"s:88:2:99:Infinity":20,"b:89:4:89:Infinity:90:4:90:Infinity:91:4:91:Infinity":6,"f:91:12:91:20":1,"s:91:26:91:74":21,"b:91:26:91:39:91:39:91:74":7,"s:93:4:98:Infinity":22,"s:101:2:101:Infinity":23}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-c-structure.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-c-structure.ts","statementMap":{"0":{"start":{"line":26,"column":37},"end":{"line":26,"column":null}},"1":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"4":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"5":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"7":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}}},"fnMap":{"0":{"name":"checkFamilyCStructure","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":25,"column":30},"end":{"line":36,"column":null}},"line":25}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":8,"seen":{"f:23:22:23:Infinity":0,"s:26:37:26:Infinity":0,"s:28:2:28:Infinity":1,"s:29:2:29:Infinity":2,"s:30:2:30:Infinity":3,"s:31:2:31:Infinity":4,"s:32:2:32:Infinity":5,"s:33:2:33:Infinity":6,"s:35:2:35:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/forward-indicators.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/forward-indicators.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"6":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"7":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},"9":{"start":{"line":33,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"11":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"checkForwardIndicators","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":49,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":26},"end":{"line":30,"column":43}},{"start":{"line":30,"column":43},"end":{"line":30,"column":null}}],"line":30},"2":{"loc":{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},{"start":{"line":39,"column":9},"end":{"line":46,"column":null}}],"line":32}},"s":{"0":8,"1":8,"2":8,"3":1,"4":7,"5":7,"6":7,"7":7,"8":8,"9":2,"10":5,"11":7},"f":{"0":8},"b":{"0":[1,7],"1":[7,0],"2":[2,5]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":12,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:28:22:28:Infinity":5,"s:29:18:29:Infinity":6,"s:30:16:30:Infinity":7,"b:30:26:30:43:30:43:30:Infinity":1,"b:32:2:46:Infinity:39:9:46:Infinity":2,"s:32:2:46:Infinity":8,"s:33:4:38:Infinity":9,"s:40:4:45:Infinity":10,"s:48:2:48:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/intelligence-assessment.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/intelligence-assessment.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":18},"end":{"line":30,"column":null}},"7":{"start":{"line":30,"column":55},"end":{"line":30,"column":75}},"8":{"start":{"line":31,"column":18},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},"10":{"start":{"line":33,"column":4},"end":{"line":38,"column":null}},"11":{"start":{"line":41,"column":22},"end":{"line":43,"column":null}},"12":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"13":{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},"14":{"start":{"line":46,"column":4},"end":{"line":51,"column":null}},"15":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"16":{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},"17":{"start":{"line":56,"column":4},"end":{"line":61,"column":null}},"18":{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},"19":{"start":{"line":65,"column":4},"end":{"line":70,"column":null}},"20":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}}},"fnMap":{"0":{"name":"checkIntelligenceAssessment","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":74,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":38},"end":{"line":30,"column":46}},"loc":{"start":{"line":30,"column":55},"end":{"line":30,"column":75}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":32},"2":{"loc":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":34},"end":{"line":44,"column":55}},{"start":{"line":44,"column":55},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":45},"4":{"loc":{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"5":{"loc":{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":64},"6":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":48}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":22}},{"start":{"line":64,"column":22},"end":{"line":64,"column":40}},{"start":{"line":64,"column":40},"end":{"line":64,"column":48}}],"line":64}},"s":{"0":7,"1":7,"2":7,"3":2,"4":5,"5":5,"6":5,"7":49,"8":5,"9":5,"10":1,"11":5,"12":5,"13":7,"14":0,"15":5,"16":5,"17":0,"18":5,"19":4,"20":5},"f":{"0":7,"1":49},"b":{"0":[2,5],"1":[1,4],"2":[5,0],"3":[0,7],"4":[0,5],"5":[4,1],"6":[5,4,4]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":21,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:29:20:29:Infinity":5,"s:30:18:30:Infinity":6,"f:30:38:30:46":1,"s:30:55:30:75":7,"s:31:18:31:Infinity":8,"b:32:2:39:Infinity:undefined:undefined:undefined:undefined":1,"s:32:2:39:Infinity":9,"s:33:4:38:Infinity":10,"s:41:22:43:Infinity":11,"s:44:20:44:Infinity":12,"b:44:34:44:55:44:55:44:Infinity":2,"b:45:2:52:Infinity:undefined:undefined:undefined:undefined":3,"s:45:2:52:Infinity":13,"s:46:4:51:Infinity":14,"s:54:17:54:Infinity":15,"b:55:2:62:Infinity:undefined:undefined:undefined:undefined":4,"s:55:2:62:Infinity":16,"s:56:4:61:Infinity":17,"b:64:2:71:Infinity:undefined:undefined:undefined:undefined":5,"s:64:2:71:Infinity":18,"b:64:6:64:22:64:22:64:40:64:40:64:48":6,"s:65:4:70:Infinity":19,"s:73:2:73:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/mermaid-diagrams.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/mermaid-diagrams.ts","statementMap":{"0":{"start":{"line":24,"column":37},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":63,"column":null}},"2":{"start":{"line":27,"column":21},"end":{"line":27,"column":null}},"3":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"4":{"start":{"line":28,"column":31},"end":{"line":28,"column":null}},"5":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"6":{"start":{"line":32,"column":23},"end":{"line":32,"column":null}},"7":{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},"8":{"start":{"line":34,"column":6},"end":{"line":39,"column":null}},"9":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"10":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"11":{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},"12":{"start":{"line":49,"column":6},"end":{"line":54,"column":null}},"13":{"start":{"line":56,"column":6},"end":{"line":61,"column":null}},"14":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"checkMermaidDiagrams","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":23,"column":30},"end":{"line":66,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},{"start":{"line":46,"column":6},"end":{"line":46,"column":null}}],"line":44},"3":{"loc":{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},{"start":{"line":55,"column":11},"end":{"line":62,"column":null}}],"line":48}},"s":{"0":7,"1":7,"2":112,"3":112,"4":76,"5":36,"6":36,"7":36,"8":1,"9":1,"10":35,"11":112,"12":1,"13":34,"14":7},"f":{"0":7},"b":{"0":[76,36],"1":[1,35],"2":[35,2,1],"3":[1,34]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":15,"seen":{"f:21:22:21:Infinity":0,"s:24:37:24:Infinity":0,"s:26:2:63:Infinity":1,"s:27:21:27:Infinity":2,"b:28:4:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:4:28:Infinity":3,"s:28:31:28:Infinity":4,"s:30:20:30:Infinity":5,"s:32:23:32:Infinity":6,"b:33:4:41:Infinity:undefined:undefined:undefined:undefined":1,"s:33:4:41:Infinity":7,"s:34:6:39:Infinity":8,"s:40:6:40:Infinity":9,"s:44:6:46:Infinity":10,"b:44:6:44:Infinity:45:6:45:Infinity:46:6:46:Infinity":2,"b:48:4:62:Infinity:55:11:62:Infinity":3,"s:48:4:62:Infinity":11,"s:49:6:54:Infinity":12,"s:56:6:61:Infinity":13,"s:65:2:65:Infinity":14}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/methodology-reflection.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/methodology-reflection.ts","statementMap":{"0":{"start":{"line":29,"column":37},"end":{"line":29,"column":null}},"1":{"start":{"line":30,"column":19},"end":{"line":30,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"3":{"start":{"line":31,"column":29},"end":{"line":31,"column":null}},"4":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"5":{"start":{"line":35,"column":28},"end":{"line":38,"column":null}},"6":{"start":{"line":39,"column":28},"end":{"line":42,"column":null}},"7":{"start":{"line":43,"column":23},"end":{"line":43,"column":null}},"8":{"start":{"line":47,"column":35},"end":{"line":58,"column":null}},"9":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"10":{"start":{"line":48,"column":38},"end":{"line":48,"column":null}},"11":{"start":{"line":49,"column":18},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":4},"end":{"line":56,"column":null}},"13":{"start":{"line":61,"column":25},"end":{"line":63,"column":null}},"14":{"start":{"line":63,"column":22},"end":{"line":63,"column":59}},"15":{"start":{"line":64,"column":33},"end":{"line":64,"column":null}},"16":{"start":{"line":64,"column":62},"end":{"line":64,"column":75}},"17":{"start":{"line":65,"column":34},"end":{"line":67,"column":null}},"18":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"19":{"start":{"line":68,"column":32},"end":{"line":68,"column":null}},"20":{"start":{"line":72,"column":45},"end":{"line":74,"column":null}},"21":{"start":{"line":76,"column":76},"end":{"line":134,"column":null}},"22":{"start":{"line":136,"column":26},"end":{"line":138,"column":null}},"23":{"start":{"line":137,"column":29},"end":{"line":137,"column":37}},"24":{"start":{"line":138,"column":24},"end":{"line":138,"column":29}},"25":{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},"26":{"start":{"line":141,"column":4},"end":{"line":146,"column":null}},"27":{"start":{"line":148,"column":4},"end":{"line":153,"column":null}},"28":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"29":{"start":{"line":164,"column":26},"end":{"line":164,"column":null}},"30":{"start":{"line":165,"column":26},"end":{"line":167,"column":null}},"31":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"32":{"start":{"line":168,"column":29},"end":{"line":168,"column":null}},"33":{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},"34":{"start":{"line":170,"column":18},"end":{"line":173,"column":null}},"35":{"start":{"line":173,"column":21},"end":{"line":173,"column":46}},"36":{"start":{"line":174,"column":4},"end":{"line":176,"column":null}},"37":{"start":{"line":175,"column":6},"end":{"line":175,"column":null}},"38":{"start":{"line":178,"column":27},"end":{"line":180,"column":null}},"39":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"40":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"41":{"start":{"line":181,"column":37},"end":{"line":181,"column":null}},"42":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"43":{"start":{"line":182,"column":32},"end":{"line":182,"column":null}},"44":{"start":{"line":183,"column":2},"end":{"line":194,"column":null}},"45":{"start":{"line":184,"column":18},"end":{"line":184,"column":null}},"46":{"start":{"line":184,"column":57},"end":{"line":184,"column":65}},"47":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"48":{"start":{"line":186,"column":21},"end":{"line":186,"column":null}},"49":{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},"50":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"51":{"start":{"line":195,"column":2},"end":{"line":195,"column":null}}},"fnMap":{"0":{"name":"checkMethodologyReflection","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":null}},"loc":{"start":{"line":28,"column":30},"end":{"line":157,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":47,"column":60},"end":{"line":47,"column":66}},"loc":{"start":{"line":47,"column":75},"end":{"line":58,"column":3}},"line":47},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":13}},"loc":{"start":{"line":63,"column":22},"end":{"line":63,"column":59}},"line":63},"3":{"name":"(anonymous_3)","decl":{"start":{"line":64,"column":48},"end":{"line":64,"column":54}},"loc":{"start":{"line":64,"column":62},"end":{"line":64,"column":75}},"line":64},"4":{"name":"(anonymous_4)","decl":{"start":{"line":65,"column":49},"end":{"line":65,"column":55}},"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"line":66},"5":{"name":"(anonymous_5)","decl":{"start":{"line":137,"column":5},"end":{"line":137,"column":13}},"loc":{"start":{"line":137,"column":29},"end":{"line":137,"column":37}},"line":137},"6":{"name":"(anonymous_6)","decl":{"start":{"line":138,"column":5},"end":{"line":138,"column":10}},"loc":{"start":{"line":138,"column":24},"end":{"line":138,"column":29}},"line":138},"7":{"name":"checkConfidencePosteriorColumn","decl":{"start":{"line":163,"column":9},"end":{"line":163,"column":40}},"loc":{"start":{"line":163,"column":76},"end":{"line":196,"column":null}},"line":163},"8":{"name":"(anonymous_8)","decl":{"start":{"line":165,"column":42},"end":{"line":165,"column":null}},"loc":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"line":166},"9":{"name":"(anonymous_9)","decl":{"start":{"line":173,"column":7},"end":{"line":173,"column":12}},"loc":{"start":{"line":173,"column":21},"end":{"line":173,"column":46}},"line":173},"10":{"name":"(anonymous_10)","decl":{"start":{"line":174,"column":33},"end":{"line":174,"column":44}},"loc":{"start":{"line":175,"column":6},"end":{"line":175,"column":null}},"line":175},"11":{"name":"(anonymous_11)","decl":{"start":{"line":178,"column":43},"end":{"line":178,"column":51}},"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"line":179},"12":{"name":"(anonymous_12)","decl":{"start":{"line":184,"column":46},"end":{"line":184,"column":51}},"loc":{"start":{"line":184,"column":57},"end":{"line":184,"column":65}},"line":184}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":31},"1":{"loc":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":51,"column":6},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},{"start":{"line":54,"column":6},"end":{"line":54,"column":null}},{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{"line":56,"column":6},"end":{"line":56,"column":null}}],"line":51},"3":{"loc":{"start":{"line":91,"column":8},"end":{"line":93,"column":null}},"type":"binary-expr","locations":[{"start":{"line":91,"column":8},"end":{"line":91,"column":null}},{"start":{"line":92,"column":8},"end":{"line":92,"column":null}},{"start":{"line":93,"column":8},"end":{"line":93,"column":null}}],"line":91},"4":{"loc":{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},{"start":{"line":147,"column":9},"end":{"line":154,"column":null}}],"line":140},"5":{"loc":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"type":"binary-expr","locations":[{"start":{"line":166,"column":14},"end":{"line":166,"column":45}},{"start":{"line":166,"column":45},"end":{"line":166,"column":null}}],"line":166},"6":{"loc":{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},"type":"if","locations":[{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},{"start":{},"end":{}}],"line":169},"7":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"8":{"loc":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"9":{"loc":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":17},"end":{"line":185,"column":48}},{"start":{"line":185,"column":48},"end":{"line":185,"column":null}}],"line":185},"10":{"loc":{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":187},"11":{"loc":{"start":{"line":188,"column":6},"end":{"line":190,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":6},"end":{"line":188,"column":null}},{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},{"start":{"line":190,"column":6},"end":{"line":190,"column":null}}],"line":188}},"s":{"0":13,"1":13,"2":13,"3":2,"4":11,"5":11,"6":11,"7":11,"8":11,"9":13,"10":5,"11":8,"12":8,"13":11,"14":65,"15":11,"16":26,"17":11,"18":26,"19":11,"20":11,"21":11,"22":13,"23":132,"24":26,"25":13,"26":6,"27":5,"28":11,"29":11,"30":11,"31":11,"32":11,"33":11,"34":9,"35":45,"36":9,"37":36,"38":11,"39":56,"40":11,"41":2,"42":9,"43":0,"44":9,"45":24,"46":120,"47":24,"48":24,"49":24,"50":2,"51":7},"f":{"0":13,"1":13,"2":65,"3":26,"4":26,"5":132,"6":26,"7":11,"8":11,"9":45,"10":36,"11":56,"12":120},"b":{"0":[2,11],"1":[5,8],"2":[8,8,8,8,8,8],"3":[11,9,8],"4":[6,5],"5":[11,9],"6":[9,2],"7":[2,9],"8":[0,9],"9":[24,0],"10":[2,22],"11":[24,23,22]},"meta":{"lastBranch":12,"lastFunction":13,"lastStatement":52,"seen":{"f:26:22:26:Infinity":0,"s:29:37:29:Infinity":0,"s:30:19:30:Infinity":1,"b:31:2:31:Infinity:undefined:undefined:undefined:undefined":0,"s:31:2:31:Infinity":2,"s:31:29:31:Infinity":3,"s:33:18:33:Infinity":4,"s:35:28:38:Infinity":5,"s:39:28:42:Infinity":6,"s:43:23:43:Infinity":7,"s:47:35:58:Infinity":8,"f:47:60:47:66":1,"b:48:4:48:Infinity:undefined:undefined:undefined:undefined":1,"s:48:4:48:Infinity":9,"s:48:38:48:Infinity":10,"s:49:18:49:Infinity":11,"s:50:4:56:Infinity":12,"b:51:6:51:Infinity:52:6:52:Infinity:53:6:53:Infinity:54:6:54:Infinity:55:6:55:Infinity:56:6:56:Infinity":2,"s:61:25:63:Infinity":13,"f:63:5:63:13":2,"s:63:22:63:59":14,"s:64:33:64:Infinity":15,"f:64:48:64:54":3,"s:64:62:64:75":16,"s:65:34:67:Infinity":17,"f:65:49:65:55":4,"s:66:4:66:Infinity":18,"s:68:32:68:Infinity":19,"s:72:45:74:Infinity":20,"s:76:76:134:Infinity":21,"b:91:8:91:Infinity:92:8:92:Infinity:93:8:93:Infinity":3,"s:136:26:138:Infinity":22,"f:137:5:137:13":5,"s:137:29:137:37":23,"f:138:5:138:10":6,"s:138:24:138:29":24,"b:140:2:154:Infinity:147:9:154:Infinity":4,"s:140:2:154:Infinity":25,"s:141:4:146:Infinity":26,"s:148:4:153:Infinity":27,"s:156:2:156:Infinity":28,"f:163:9:163:40":7,"s:164:26:164:Infinity":29,"s:165:26:167:Infinity":30,"f:165:42:165:Infinity":8,"s:166:14:166:Infinity":31,"b:166:14:166:45:166:45:166:Infinity":5,"s:168:29:168:Infinity":32,"b:169:2:177:Infinity:undefined:undefined:undefined:undefined":6,"s:169:2:177:Infinity":33,"s:170:18:173:Infinity":34,"f:173:7:173:12":9,"s:173:21:173:46":35,"s:174:4:176:Infinity":36,"f:174:33:174:44":10,"s:175:6:175:Infinity":37,"s:178:27:180:Infinity":38,"f:178:43:178:51":11,"s:179:4:179:Infinity":39,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":7,"s:181:2:181:Infinity":40,"s:181:37:181:Infinity":41,"b:182:2:182:Infinity:undefined:undefined:undefined:undefined":8,"s:182:2:182:Infinity":42,"s:182:32:182:Infinity":43,"s:183:2:194:Infinity":44,"s:184:18:184:Infinity":45,"f:184:46:184:51":12,"s:184:57:184:65":46,"s:185:17:185:Infinity":47,"b:185:17:185:48:185:48:185:Infinity":9,"s:186:21:186:Infinity":48,"b:187:4:193:Infinity:undefined:undefined:undefined:undefined":10,"s:187:4:193:Infinity":49,"b:188:6:188:Infinity:189:6:189:Infinity:190:6:190:Infinity":11,"s:192:6:192:Infinity":50,"s:195:2:195:Infinity":51}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/no-stubs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/no-stubs.ts","statementMap":{"0":{"start":{"line":27,"column":37},"end":{"line":27,"column":null}},"1":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":44,"column":null}},"3":{"start":{"line":32,"column":21},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"5":{"start":{"line":34,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},"7":{"start":{"line":36,"column":8},"end":{"line":41,"column":null}},"8":{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},"9":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"10":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}}},"fnMap":{"0":{"name":"checkNoStubs","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":35}},"loc":{"start":{"line":26,"column":84},"end":{"line":55,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":35},"1":{"loc":{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":46}},"s":{"0":8,"1":8,"2":8,"3":100,"4":100,"5":100,"6":400,"7":6,"8":8,"9":4,"10":8},"f":{"0":8},"b":{"0":[6,394],"1":[4,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":11,"seen":{"f:26:22:26:35":0,"s:27:37:27:Infinity":0,"s:29:18:29:Infinity":1,"s:31:2:44:Infinity":2,"s:32:21:32:Infinity":3,"s:33:20:33:Infinity":4,"s:34:4:43:Infinity":5,"b:35:6:42:Infinity:undefined:undefined:undefined:undefined":0,"s:35:6:42:Infinity":6,"s:36:8:41:Infinity":7,"b:46:2:52:Infinity:undefined:undefined:undefined:undefined":1,"s:46:2:52:Infinity":8,"s:47:4:51:Infinity":9,"s:54:2:54:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pass2-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pass2-evidence.ts","statementMap":{"0":{"start":{"line":25,"column":40},"end":{"line":25,"column":null}},"1":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":79,"column":null}},"4":{"start":{"line":39,"column":21},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"6":{"start":{"line":40,"column":31},"end":{"line":40,"column":null}},"7":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"8":{"start":{"line":44,"column":22},"end":{"line":44,"column":null}},"9":{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},"10":{"start":{"line":46,"column":34},"end":{"line":49,"column":null}},"11":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"12":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"13":{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":26},"end":{"line":57,"column":null}},"16":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"17":{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},"18":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"19":{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},"20":{"start":{"line":65,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":72,"column":6},"end":{"line":77,"column":null}},"22":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}}},"fnMap":{"0":{"name":"checkPass2Evidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":82,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":59,"column":10},"end":{"line":59,"column":80}},"type":"binary-expr","locations":[{"start":{"line":59,"column":10},"end":{"line":59,"column":29}},{"start":{"line":59,"column":29},"end":{"line":59,"column":80}}],"line":59},"6":{"loc":{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},{"start":{"line":71,"column":11},"end":{"line":78,"column":null}}],"line":64}},"s":{"0":2,"1":7,"2":7,"3":7,"4":154,"5":154,"6":107,"7":47,"8":47,"9":47,"10":47,"11":47,"12":45,"13":47,"14":2,"15":2,"16":2,"17":2,"18":0,"19":47,"20":2,"21":45,"22":7},"f":{"0":7},"b":{"0":[107,47],"1":[47,0],"2":[45,2],"3":[2,45],"4":[0,2],"5":[2,2],"6":[2,45]},"meta":{"lastBranch":7,"lastFunction":1,"lastStatement":23,"seen":{"s:25:40:25:Infinity":0,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":1,"s:36:19:36:Infinity":2,"s:38:2:79:Infinity":3,"s:39:21:39:Infinity":4,"b:40:4:40:Infinity:undefined:undefined:undefined:undefined":0,"s:40:4:40:Infinity":5,"s:40:31:40:Infinity":6,"s:42:20:42:Infinity":7,"s:44:22:44:Infinity":8,"b:45:4:53:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:53:Infinity":9,"s:46:34:49:Infinity":10,"b:50:6:52:Infinity:undefined:undefined:undefined:undefined":2,"s:50:6:52:Infinity":11,"s:51:8:51:Infinity":12,"b:55:4:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:4:62:Infinity":13,"s:56:23:56:Infinity":14,"s:57:26:57:Infinity":15,"s:58:22:58:Infinity":16,"b:59:6:61:Infinity:undefined:undefined:undefined:undefined":4,"s:59:6:61:Infinity":17,"b:59:10:59:29:59:29:59:80":5,"s:60:8:60:Infinity":18,"b:64:4:78:Infinity:71:11:78:Infinity":6,"s:64:4:78:Infinity":19,"s:65:6:70:Infinity":20,"s:72:6:77:Infinity":21,"s:81:2:81:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pir-status.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pir-status.ts","statementMap":{"0":{"start":{"line":37,"column":27},"end":{"line":39,"column":null}},"1":{"start":{"line":41,"column":32},"end":{"line":43,"column":null}},"2":{"start":{"line":45,"column":23},"end":{"line":45,"column":null}},"3":{"start":{"line":51,"column":37},"end":{"line":51,"column":null}},"4":{"start":{"line":52,"column":19},"end":{"line":52,"column":null}},"5":{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},"6":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"7":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":74,"column":null}},"9":{"start":{"line":65,"column":16},"end":{"line":65,"column":null}},"10":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"11":{"start":{"line":68,"column":4},"end":{"line":72,"column":null}},"12":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"13":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"14":{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},"15":{"start":{"line":79,"column":4},"end":{"line":83,"column":null}},"16":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"17":{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},"18":{"start":{"line":88,"column":4},"end":{"line":92,"column":null}},"19":{"start":{"line":95,"column":2},"end":{"line":97,"column":null}},"20":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"21":{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},"22":{"start":{"line":100,"column":4},"end":{"line":104,"column":null}},"23":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"24":{"start":{"line":111,"column":25},"end":{"line":111,"column":null}},"25":{"start":{"line":112,"column":2},"end":{"line":120,"column":null}},"26":{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},"27":{"start":{"line":114,"column":6},"end":{"line":118,"column":null}},"28":{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},"29":{"start":{"line":123,"column":4},"end":{"line":127,"column":null}},"30":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"31":{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},"32":{"start":{"line":135,"column":4},"end":{"line":139,"column":null}},"33":{"start":{"line":142,"column":2},"end":{"line":150,"column":null}},"34":{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},"35":{"start":{"line":144,"column":6},"end":{"line":148,"column":null}},"36":{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},"37":{"start":{"line":153,"column":4},"end":{"line":157,"column":null}},"38":{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},"39":{"start":{"line":161,"column":4},"end":{"line":165,"column":null}},"40":{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},"41":{"start":{"line":169,"column":4},"end":{"line":173,"column":null}},"42":{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},"43":{"start":{"line":176,"column":4},"end":{"line":180,"column":null}}},"fnMap":{"0":{"name":"checkPirStatus","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":37}},"loc":{"start":{"line":50,"column":86},"end":{"line":108,"column":null}},"line":50},"1":{"name":"validateTopLevel","decl":{"start":{"line":110,"column":9},"end":{"line":110,"column":26}},"loc":{"start":{"line":110,"column":81},"end":{"line":129,"column":null}},"line":110},"2":{"name":"validatePirEntry","decl":{"start":{"line":131,"column":9},"end":{"line":131,"column":26}},"loc":{"start":{"line":131,"column":75},"end":{"line":182,"column":null}},"line":131}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":54},"1":{"loc":{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":78},"2":{"loc":{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":87},"3":{"loc":{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},{"start":{},"end":{}}],"line":99},"4":{"loc":{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},{"start":{},"end":{}}],"line":113},"5":{"loc":{"start":{"line":113,"column":8},"end":{"line":113,"column":78}},"type":"binary-expr","locations":[{"start":{"line":113,"column":8},"end":{"line":113,"column":28}},{"start":{"line":113,"column":28},"end":{"line":113,"column":78}}],"line":113},"6":{"loc":{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":122},"7":{"loc":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"type":"binary-expr","locations":[{"start":{"line":132,"column":14},"end":{"line":132,"column":28}},{"start":{"line":132,"column":28},"end":{"line":132,"column":null}}],"line":132},"8":{"loc":{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":134},"9":{"loc":{"start":{"line":134,"column":6},"end":{"line":134,"column":55}},"type":"binary-expr","locations":[{"start":{"line":134,"column":6},"end":{"line":134,"column":21}},{"start":{"line":134,"column":21},"end":{"line":134,"column":55}}],"line":134},"10":{"loc":{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":143},"11":{"loc":{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},{"start":{},"end":{}}],"line":152},"12":{"loc":{"start":{"line":152,"column":6},"end":{"line":152,"column":57}},"type":"binary-expr","locations":[{"start":{"line":152,"column":6},"end":{"line":152,"column":20}},{"start":{"line":152,"column":20},"end":{"line":152,"column":57}}],"line":152},"13":{"loc":{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":160},"14":{"loc":{"start":{"line":160,"column":6},"end":{"line":160,"column":70}},"type":"binary-expr","locations":[{"start":{"line":160,"column":6},"end":{"line":160,"column":24}},{"start":{"line":160,"column":24},"end":{"line":160,"column":70}}],"line":160},"15":{"loc":{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":168},"16":{"loc":{"start":{"line":168,"column":6},"end":{"line":168,"column":56}},"type":"binary-expr","locations":[{"start":{"line":168,"column":6},"end":{"line":168,"column":35}},{"start":{"line":168,"column":35},"end":{"line":168,"column":56}}],"line":168},"17":{"loc":{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":175},"18":{"loc":{"start":{"line":175,"column":6},"end":{"line":175,"column":69}},"type":"binary-expr","locations":[{"start":{"line":175,"column":6},"end":{"line":175,"column":35}},{"start":{"line":175,"column":35},"end":{"line":175,"column":69}}],"line":175}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":12,"6":2,"7":2,"8":10,"9":10,"10":10,"11":1,"12":1,"13":9,"14":9,"15":0,"16":0,"17":9,"18":1,"19":9,"20":7,"21":9,"22":4,"23":9,"24":9,"25":9,"26":54,"27":0,"28":9,"29":1,"30":7,"31":7,"32":1,"33":7,"34":21,"35":1,"36":7,"37":1,"38":7,"39":1,"40":7,"41":1,"42":7,"43":1},"f":{"0":12,"1":9,"2":7},"b":{"0":[2,10],"1":[0,9],"2":[1,8],"3":[4,5],"4":[0,54],"5":[54,54],"6":[1,8],"7":[7,0],"8":[1,6],"9":[7,7],"10":[1,20],"11":[1,6],"12":[7,7],"13":[1,6],"14":[7,7],"15":[1,6],"16":[7,2],"17":[1,6],"18":[7,5]},"meta":{"lastBranch":19,"lastFunction":3,"lastStatement":44,"seen":{"s:37:27:39:Infinity":0,"s:41:32:43:Infinity":1,"s:45:23:45:Infinity":2,"f:50:22:50:37":0,"s:51:37:51:Infinity":3,"s:52:19:52:Infinity":4,"b:54:2:61:Infinity:undefined:undefined:undefined:undefined":0,"s:54:2:61:Infinity":5,"s:55:4:59:Infinity":6,"s:60:4:60:Infinity":7,"s:64:2:74:Infinity":8,"s:65:16:65:Infinity":9,"s:66:4:66:Infinity":10,"s:68:4:72:Infinity":11,"s:73:4:73:Infinity":12,"s:76:2:76:Infinity":13,"b:78:2:85:Infinity:undefined:undefined:undefined:undefined":1,"s:78:2:85:Infinity":14,"s:79:4:83:Infinity":15,"s:84:4:84:Infinity":16,"b:87:2:93:Infinity:undefined:undefined:undefined:undefined":2,"s:87:2:93:Infinity":17,"s:88:4:92:Infinity":18,"s:95:2:97:Infinity":19,"s:96:4:96:Infinity":20,"b:99:2:105:Infinity:undefined:undefined:undefined:undefined":3,"s:99:2:105:Infinity":21,"s:100:4:104:Infinity":22,"s:107:2:107:Infinity":23,"f:110:9:110:26":1,"s:111:25:111:Infinity":24,"s:112:2:120:Infinity":25,"b:113:4:119:Infinity:undefined:undefined:undefined:undefined":4,"s:113:4:119:Infinity":26,"b:113:8:113:28:113:28:113:78":5,"s:114:6:118:Infinity":27,"b:122:2:128:Infinity:undefined:undefined:undefined:undefined":6,"s:122:2:128:Infinity":28,"s:123:4:127:Infinity":29,"f:131:9:131:26":2,"s:132:14:132:Infinity":30,"b:132:14:132:28:132:28:132:Infinity":7,"b:134:2:140:Infinity:undefined:undefined:undefined:undefined":8,"s:134:2:140:Infinity":31,"b:134:6:134:21:134:21:134:55":9,"s:135:4:139:Infinity":32,"s:142:2:150:Infinity":33,"b:143:4:149:Infinity:undefined:undefined:undefined:undefined":10,"s:143:4:149:Infinity":34,"s:144:6:148:Infinity":35,"b:152:2:158:Infinity:undefined:undefined:undefined:undefined":11,"s:152:2:158:Infinity":36,"b:152:6:152:20:152:20:152:57":12,"s:153:4:157:Infinity":37,"b:160:2:166:Infinity:undefined:undefined:undefined:undefined":13,"s:160:2:166:Infinity":38,"b:160:6:160:24:160:24:160:70":14,"s:161:4:165:Infinity":39,"b:168:2:174:Infinity:undefined:undefined:undefined:undefined":15,"s:168:2:174:Infinity":40,"b:168:6:168:35:168:35:168:56":16,"s:169:4:173:Infinity":41,"b:175:2:181:Infinity:undefined:undefined:undefined:undefined":17,"s:175:2:181:Infinity":42,"b:175:6:175:35:175:35:175:69":18,"s:176:4:180:Infinity":43}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/per-document-coverage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/per-document-coverage.ts","statementMap":{"0":{"start":{"line":27,"column":37},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"4":{"start":{"line":34,"column":18},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"6":{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"9":{"start":{"line":46,"column":23},"end":{"line":46,"column":null}},"10":{"start":{"line":47,"column":2},"end":{"line":57,"column":null}},"11":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"12":{"start":{"line":49,"column":4},"end":{"line":56,"column":null}},"13":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"14":{"start":{"line":66,"column":24},"end":{"line":66,"column":null}},"15":{"start":{"line":67,"column":18},"end":{"line":67,"column":null}},"16":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"17":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"18":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"19":{"start":{"line":77,"column":19},"end":{"line":82,"column":null}},"20":{"start":{"line":83,"column":2},"end":{"line":86,"column":null}},"21":{"start":{"line":84,"column":14},"end":{"line":84,"column":null}},"22":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}}},"fnMap":{"0":{"name":"checkPerDocumentCoverage","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":null}},"loc":{"start":{"line":26,"column":30},"end":{"line":60,"column":null}},"line":26},"1":{"name":"extractDokIds","decl":{"start":{"line":65,"column":16},"end":{"line":65,"column":30}},"loc":{"start":{"line":65,"column":57},"end":{"line":70,"column":null}},"line":65},"2":{"name":"hasDocumentAnalysis","decl":{"start":{"line":76,"column":9},"end":{"line":76,"column":29}},"loc":{"start":{"line":76,"column":75},"end":{"line":87,"column":null}},"line":76},"3":{"name":"(anonymous_3)","decl":{"start":{"line":83,"column":18},"end":{"line":83,"column":24}},"loc":{"start":{"line":83,"column":30},"end":{"line":86,"column":3}},"line":83}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"1":{"loc":{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":37},"2":{"loc":{"start":{"line":52,"column":15},"end":{"line":54,"column":null}},"type":"cond-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":null}},{"start":{"line":54,"column":10},"end":{"line":54,"column":null}}],"line":52},"3":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"4":{"loc":{"start":{"line":85,"column":11},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":11},"end":{"line":85,"column":28}},{"start":{"line":85,"column":28},"end":{"line":85,"column":null}}],"line":85}},"s":{"0":7,"1":7,"2":7,"3":2,"4":5,"5":5,"6":5,"7":1,"8":1,"9":4,"10":4,"11":9,"12":9,"13":4,"14":9,"15":9,"16":9,"17":3,"18":6,"19":9,"20":9,"21":22,"22":22},"f":{"0":7,"1":9,"2":9,"3":22},"b":{"0":[2,5],"1":[1,4],"2":[7,2],"3":[3,6],"4":[22,7]},"meta":{"lastBranch":5,"lastFunction":4,"lastStatement":23,"seen":{"f:24:22:24:Infinity":0,"s:27:37:27:Infinity":0,"s:28:23:28:Infinity":1,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:32:Infinity":2,"s:31:4:31:Infinity":3,"s:34:18:34:Infinity":4,"s:35:17:35:Infinity":5,"b:37:2:44:Infinity:undefined:undefined:undefined:undefined":1,"s:37:2:44:Infinity":6,"s:38:4:42:Infinity":7,"s:43:4:43:Infinity":8,"s:46:23:46:Infinity":9,"s:47:2:57:Infinity":10,"s:48:18:48:Infinity":11,"s:49:4:56:Infinity":12,"b:53:10:53:Infinity:54:10:54:Infinity":2,"s:59:2:59:Infinity":13,"f:65:16:65:30":1,"s:66:24:66:Infinity":14,"s:67:18:67:Infinity":15,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":3,"s:68:2:68:Infinity":16,"s:68:16:68:Infinity":17,"s:69:2:69:Infinity":18,"f:76:9:76:29":2,"s:77:19:82:Infinity":19,"s:83:2:86:Infinity":20,"f:83:18:83:24":3,"s:84:14:84:Infinity":21,"s:85:4:85:Infinity":22,"b:85:11:85:28:85:28:85:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/scenario-analysis.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/scenario-analysis.ts","statementMap":{"0":{"start":{"line":22,"column":37},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":19},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":24,"column":29},"end":{"line":24,"column":null}},"4":{"start":{"line":26,"column":18},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":26},"end":{"line":27,"column":null}},"6":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"7":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"8":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"9":{"start":{"line":38,"column":4},"end":{"line":43,"column":null}},"10":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkScenarioAnalysis","decl":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"loc":{"start":{"line":21,"column":30},"end":{"line":47,"column":null}},"line":21}},"branchMap":{"0":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":24},"1":{"loc":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"type":"cond-expr","locations":[{"start":{"line":28,"column":34},"end":{"line":28,"column":59}},{"start":{"line":28,"column":59},"end":{"line":28,"column":null}}],"line":28},"2":{"loc":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},{"start":{"line":37,"column":9},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":7,"8":2,"9":4,"10":6},"f":{"0":7},"b":{"0":[1,6],"1":[6,0],"2":[2,4]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":11,"seen":{"f:19:22:19:Infinity":0,"s:22:37:22:Infinity":0,"s:23:19:23:Infinity":1,"b:24:2:24:Infinity:undefined:undefined:undefined:undefined":0,"s:24:2:24:Infinity":2,"s:24:29:24:Infinity":3,"s:26:18:26:Infinity":4,"s:27:26:27:Infinity":5,"s:28:16:28:Infinity":6,"b:28:34:28:59:28:59:28:Infinity":1,"b:30:2:44:Infinity:37:9:44:Infinity":2,"s:30:2:44:Infinity":7,"s:31:4:36:Infinity":8,"s:38:4:43:Infinity":9,"s:46:2:46:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/significance-scoring.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/significance-scoring.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":25,"column":24},"end":{"line":25,"column":null}},"2":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":37,"column":29},"end":{"line":37,"column":null}},"6":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"7":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"8":{"start":{"line":41,"column":18},"end":{"line":41,"column":null}},"9":{"start":{"line":42,"column":22},"end":{"line":42,"column":null}},"10":{"start":{"line":44,"column":2},"end":{"line":96,"column":null}},"11":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"12":{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},"13":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"14":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"15":{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},"16":{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},"17":{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},"18":{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},"19":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"20":{"start":{"line":56,"column":44},"end":{"line":56,"column":null}},"21":{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},"22":{"start":{"line":58,"column":8},"end":{"line":63,"column":null}},"23":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"24":{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},"25":{"start":{"line":69,"column":6},"end":{"line":69,"column":null}},"26":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"27":{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},"28":{"start":{"line":74,"column":6},"end":{"line":79,"column":null}},"29":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"30":{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},"31":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"32":{"start":{"line":84,"column":35},"end":{"line":84,"column":null}},"33":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"34":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"35":{"start":{"line":86,"column":31},"end":{"line":86,"column":null}},"36":{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},"37":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"38":{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},"39":{"start":{"line":99,"column":4},"end":{"line":104,"column":null}},"40":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}}},"fnMap":{"0":{"name":"checkSignificanceScoringEvidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":108,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":50,"column":8},"end":{"line":50,"column":44}},"type":"binary-expr","locations":[{"start":{"line":50,"column":8},"end":{"line":50,"column":21}},{"start":{"line":50,"column":21},"end":{"line":50,"column":44}}],"line":50},"4":{"loc":{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":55},"5":{"loc":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":57},"7":{"loc":{"start":{"line":57,"column":10},"end":{"line":57,"column":70}},"type":"binary-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":40}},{"start":{"line":57,"column":40},"end":{"line":57,"column":70}}],"line":57},"8":{"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":68},"9":{"loc":{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":73},"10":{"loc":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"type":"binary-expr","locations":[{"start":{"line":73,"column":8},"end":{"line":73,"column":50}},{"start":{"line":73,"column":50},"end":{"line":73,"column":80}}],"line":73},"11":{"loc":{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":83},"12":{"loc":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"13":{"loc":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"14":{"loc":{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":87},"15":{"loc":{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},{"start":{},"end":{}}],"line":98}},"s":{"0":3,"1":3,"2":8,"3":8,"4":8,"5":3,"6":5,"7":5,"8":5,"9":5,"10":5,"11":47,"12":2,"13":2,"14":2,"15":45,"16":2,"17":2,"18":43,"19":6,"20":4,"21":2,"22":0,"23":2,"24":37,"25":14,"26":14,"27":23,"28":2,"29":2,"30":21,"31":8,"32":2,"33":6,"34":6,"35":2,"36":4,"37":0,"38":5,"39":3,"40":5},"f":{"0":8},"b":{"0":[3,5],"1":[2,45],"2":[2,43],"3":[45,8],"4":[6,37],"5":[4,2],"6":[0,2],"7":[2,2],"8":[14,23],"9":[2,21],"10":[23,10],"11":[8,13],"12":[2,6],"13":[2,4],"14":[0,4],"15":[3,2]},"meta":{"lastBranch":16,"lastFunction":1,"lastStatement":41,"seen":{"s:23:2:23:Infinity":0,"s:25:24:25:Infinity":1,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":2,"s:36:19:36:Infinity":3,"b:37:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:2:37:Infinity":4,"s:37:29:37:Infinity":5,"s:39:18:39:Infinity":6,"s:40:16:40:Infinity":7,"s:41:18:41:Infinity":8,"s:42:22:42:Infinity":9,"s:44:2:96:Infinity":10,"b:45:4:49:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:49:Infinity":11,"s:46:6:46:Infinity":12,"s:47:6:47:Infinity":13,"s:48:6:48:Infinity":14,"b:50:4:53:Infinity:undefined:undefined:undefined:undefined":2,"s:50:4:53:Infinity":15,"b:50:8:50:21:50:21:50:44":3,"s:51:6:51:Infinity":16,"s:52:6:52:Infinity":17,"b:55:4:66:Infinity:undefined:undefined:undefined:undefined":4,"s:55:4:66:Infinity":18,"b:56:6:56:Infinity:undefined:undefined:undefined:undefined":5,"s:56:6:56:Infinity":19,"s:56:44:56:Infinity":20,"b:57:6:64:Infinity:undefined:undefined:undefined:undefined":6,"s:57:6:64:Infinity":21,"b:57:10:57:40:57:40:57:70":7,"s:58:8:63:Infinity":22,"s:65:6:65:Infinity":23,"b:68:4:71:Infinity:undefined:undefined:undefined:undefined":8,"s:68:4:71:Infinity":24,"s:69:6:69:Infinity":25,"s:70:6:70:Infinity":26,"b:73:4:81:Infinity:undefined:undefined:undefined:undefined":9,"s:73:4:81:Infinity":27,"b:73:8:73:50:73:50:73:80":10,"s:74:6:79:Infinity":28,"s:80:6:80:Infinity":29,"b:83:4:95:Infinity:undefined:undefined:undefined:undefined":11,"s:83:4:95:Infinity":30,"b:84:6:84:Infinity:undefined:undefined:undefined:undefined":12,"s:84:6:84:Infinity":31,"s:84:35:84:Infinity":32,"s:85:6:85:Infinity":33,"b:86:6:86:Infinity:undefined:undefined:undefined:undefined":13,"s:86:6:86:Infinity":34,"s:86:31:86:Infinity":35,"b:87:6:94:Infinity:undefined:undefined:undefined:undefined":14,"s:87:6:94:Infinity":36,"s:88:8:93:Infinity":37,"b:98:2:105:Infinity:undefined:undefined:undefined:undefined":15,"s:98:2:105:Infinity":38,"s:99:4:104:Infinity":39,"s:107:2:107:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/swot-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/swot-evidence.ts","statementMap":{"0":{"start":{"line":26,"column":24},"end":{"line":26,"column":null}},"1":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"3":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"4":{"start":{"line":37,"column":29},"end":{"line":37,"column":null}},"5":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"6":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":22},"end":{"line":42,"column":null}},"9":{"start":{"line":44,"column":2},"end":{"line":87,"column":null}},"10":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"11":{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},"12":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"13":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"14":{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},"15":{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},"16":{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},"17":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"18":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"19":{"start":{"line":55,"column":25},"end":{"line":55,"column":null}},"20":{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},"21":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"22":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"23":{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},"24":{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},"25":{"start":{"line":64,"column":8},"end":{"line":69,"column":null}},"26":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"27":{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},"28":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"29":{"start":{"line":75,"column":35},"end":{"line":75,"column":null}},"30":{"start":{"line":76,"column":6},"end":{"line":76,"column":null}},"31":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"32":{"start":{"line":77,"column":31},"end":{"line":77,"column":null}},"33":{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},"34":{"start":{"line":79,"column":8},"end":{"line":84,"column":null}},"35":{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},"36":{"start":{"line":90,"column":4},"end":{"line":95,"column":null}},"37":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"checkSwotEvidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":99,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":57},"5":{"loc":{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":62},"6":{"loc":{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":63},"7":{"loc":{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":74},"8":{"loc":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":75},"9":{"loc":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":77},"10":{"loc":{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":78},"11":{"loc":{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":89}},"s":{"0":3,"1":8,"2":8,"3":8,"4":3,"5":5,"6":5,"7":5,"8":5,"9":5,"10":73,"11":14,"12":14,"13":14,"14":59,"15":5,"16":5,"17":5,"18":54,"19":5,"20":49,"21":17,"22":17,"23":32,"24":22,"25":2,"26":22,"27":10,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":5,"36":3,"37":5},"f":{"0":8},"b":{"0":[3,5],"1":[14,59],"2":[5,54],"3":[5,49],"4":[17,32],"5":[22,10],"6":[2,20],"7":[0,10],"8":[0,0],"9":[0,0],"10":[0,0],"11":[3,2]},"meta":{"lastBranch":12,"lastFunction":1,"lastStatement":38,"seen":{"s:26:24:26:Infinity":0,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":1,"s:36:19:36:Infinity":2,"b:37:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:2:37:Infinity":3,"s:37:29:37:Infinity":4,"s:39:18:39:Infinity":5,"s:40:16:40:Infinity":6,"s:41:23:41:Infinity":7,"s:42:22:42:Infinity":8,"s:44:2:87:Infinity":9,"b:45:4:49:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:49:Infinity":10,"s:46:6:46:Infinity":11,"s:47:6:47:Infinity":12,"s:48:6:48:Infinity":13,"b:50:4:54:Infinity:undefined:undefined:undefined:undefined":2,"s:50:4:54:Infinity":14,"s:51:6:51:Infinity":15,"s:52:6:52:Infinity":16,"s:53:6:53:Infinity":17,"b:55:4:55:Infinity:undefined:undefined:undefined:undefined":3,"s:55:4:55:Infinity":18,"s:55:25:55:Infinity":19,"b:57:4:60:Infinity:undefined:undefined:undefined:undefined":4,"s:57:4:60:Infinity":20,"s:58:6:58:Infinity":21,"s:59:6:59:Infinity":22,"b:62:4:72:Infinity:undefined:undefined:undefined:undefined":5,"s:62:4:72:Infinity":23,"b:63:6:70:Infinity:undefined:undefined:undefined:undefined":6,"s:63:6:70:Infinity":24,"s:64:8:69:Infinity":25,"s:71:6:71:Infinity":26,"b:74:4:86:Infinity:undefined:undefined:undefined:undefined":7,"s:74:4:86:Infinity":27,"b:75:6:75:Infinity:undefined:undefined:undefined:undefined":8,"s:75:6:75:Infinity":28,"s:75:35:75:Infinity":29,"s:76:6:76:Infinity":30,"b:77:6:77:Infinity:undefined:undefined:undefined:undefined":9,"s:77:6:77:Infinity":31,"s:77:31:77:Infinity":32,"b:78:6:85:Infinity:undefined:undefined:undefined:undefined":10,"s:78:6:85:Infinity":33,"s:79:8:84:Infinity":34,"b:89:2:96:Infinity:undefined:undefined:undefined:undefined":11,"s:89:2:96:Infinity":35,"s:90:4:95:Infinity":36,"s:98:2:98:Infinity":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/statskontoret-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/statskontoret-evidence.ts","statementMap":{"0":{"start":{"line":26,"column":37},"end":{"line":26,"column":null}},"1":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"2":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":28,"column":29},"end":{"line":28,"column":null}},"4":{"start":{"line":30,"column":18},"end":{"line":30,"column":null}},"5":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},"7":{"start":{"line":34,"column":4},"end":{"line":39,"column":null}},"8":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"9":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"10":{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},"11":{"start":{"line":47,"column":4},"end":{"line":52,"column":null}},"12":{"start":{"line":54,"column":4},"end":{"line":59,"column":null}},"13":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}}},"fnMap":{"0":{"name":"checkStatskontoretEvidence","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":25,"column":30},"end":{"line":63,"column":null}},"line":25}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},{"start":{"line":53,"column":9},"end":{"line":60,"column":null}}],"line":46}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":3,"8":3,"9":3,"10":3,"11":1,"12":2,"13":3},"f":{"0":7},"b":{"0":[1,6],"1":[3,3],"2":[1,2]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":14,"seen":{"f:23:22:23:Infinity":0,"s:26:37:26:Infinity":0,"s:27:19:27:Infinity":1,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:28:Infinity":2,"s:28:29:28:Infinity":3,"s:30:18:30:Infinity":4,"s:32:24:32:Infinity":5,"b:33:2:41:Infinity:undefined:undefined:undefined:undefined":1,"s:33:2:41:Infinity":6,"s:34:4:39:Infinity":7,"s:40:4:40:Infinity":8,"s:44:4:44:Infinity":9,"b:46:2:60:Infinity:53:9:60:Infinity":2,"s:46:2:60:Infinity":10,"s:47:4:52:Infinity":11,"s:54:4:59:Infinity":12,"s:62:2:62:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/file-walkers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/file-walkers.ts","statementMap":{"0":{"start":{"line":25,"column":28},"end":{"line":25,"column":null}},"1":{"start":{"line":26,"column":21},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":18},"end":{"line":28,"column":null}},"5":{"start":{"line":29,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"7":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"8":{"start":{"line":32,"column":6},"end":{"line":32,"column":null}},"9":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"10":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"11":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}}},"fnMap":{"0":{"name":"collectMdFilesRecursive","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":24,"column":21},"end":{"line":38,"column":null}},"line":24}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":21},"end":{"line":26,"column":null}},"type":"cond-expr","locations":[{"start":{"line":26,"column":30},"end":{"line":26,"column":54}},{"start":{"line":26,"column":54},"end":{"line":26,"column":null}}],"line":26},"1":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},{"start":{},"end":{}}],"line":27},"2":{"loc":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":29},"end":{"line":30,"column":57}},{"start":{"line":30,"column":57},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},{"start":{"line":33,"column":11},"end":{"line":35,"column":null}}],"line":31},"4":{"loc":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33}},"s":{"0":19,"1":19,"2":19,"3":1,"4":18,"5":18,"6":117,"7":117,"8":7,"9":110,"10":106,"11":18},"f":{"0":19},"b":{"0":[8,11],"1":[1,18],"2":[54,63],"3":[7,110],"4":[106,4]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":12,"seen":{"f:21:22:21:Infinity":0,"s:25:28:25:Infinity":0,"s:26:21:26:Infinity":1,"b:26:30:26:54:26:54:26:Infinity":0,"b:27:2:27:Infinity:undefined:undefined:undefined:undefined":1,"s:27:2:27:Infinity":2,"s:27:31:27:Infinity":3,"s:28:18:28:Infinity":4,"s:29:2:36:Infinity":5,"s:30:20:30:Infinity":6,"b:30:29:30:57:30:57:30:Infinity":2,"b:31:4:35:Infinity:33:11:35:Infinity":3,"s:31:4:35:Infinity":7,"s:32:6:32:Infinity":8,"b:33:11:35:Infinity:undefined:undefined:undefined:undefined":4,"s:33:11:35:Infinity":9,"s:34:6:34:Infinity":10,"s:37:2:37:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/markdown-helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/markdown-helpers.ts","statementMap":{"0":{"start":{"line":17,"column":25},"end":{"line":17,"column":null}},"1":{"start":{"line":20,"column":28},"end":{"line":20,"column":null}},"2":{"start":{"line":23,"column":28},"end":{"line":23,"column":null}},"3":{"start":{"line":26,"column":30},"end":{"line":26,"column":null}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"6":{"start":{"line":38,"column":2},"end":{"line":50,"column":null}},"7":{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},"8":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"9":{"start":{"line":41,"column":6},"end":{"line":41,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"11":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"12":{"start":{"line":45,"column":8},"end":{"line":45,"column":null}},"13":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"15":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"16":{"start":{"line":63,"column":2},"end":{"line":69,"column":null}},"17":{"start":{"line":64,"column":25},"end":{"line":64,"column":null}},"18":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"19":{"start":{"line":65,"column":23},"end":{"line":65,"column":null}},"20":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"21":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"22":{"start":{"line":68,"column":28},"end":{"line":68,"column":null}},"23":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"24":{"start":{"line":79,"column":16},"end":{"line":79,"column":null}},"25":{"start":{"line":80,"column":18},"end":{"line":80,"column":null}},"26":{"start":{"line":81,"column":30},"end":{"line":81,"column":null}},"27":{"start":{"line":82,"column":2},"end":{"line":93,"column":null}},"28":{"start":{"line":83,"column":25},"end":{"line":83,"column":null}},"29":{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},"30":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"31":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"32":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"33":{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},"34":{"start":{"line":88,"column":8},"end":{"line":88,"column":null}},"35":{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},"36":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"37":{"start":{"line":92,"column":19},"end":{"line":92,"column":null}},"38":{"start":{"line":94,"column":2},"end":{"line":94,"column":null}}},"fnMap":{"0":{"name":"stripHeadingMarkup","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":58},"end":{"line":53,"column":null}},"line":34},"1":{"name":"hasHeading","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":27}},"loc":{"start":{"line":62,"column":70},"end":{"line":71,"column":null}},"line":62},"2":{"name":"extractSection","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":31}},"loc":{"start":{"line":78,"column":80},"end":{"line":95,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":43},"2":{"loc":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":44},"3":{"loc":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"4":{"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"5":{"loc":{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":84},"6":{"loc":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"7":{"loc":{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":87},"8":{"loc":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92}},"s":{"0":10,"1":10,"2":10,"3":10,"4":29,"5":29,"6":29,"7":1453,"8":8,"9":8,"10":1445,"11":51,"12":8,"13":51,"14":1394,"15":29,"16":110,"17":1753,"18":1753,"19":1305,"20":448,"21":448,"22":91,"23":19,"24":42,"25":42,"26":42,"27":42,"28":675,"29":675,"30":159,"31":159,"32":29,"33":130,"34":35,"35":35,"36":611,"37":611,"38":42},"f":{"0":29,"1":110,"2":42},"b":{"0":[8,1445],"1":[51,1394],"2":[8,43],"3":[1305,448],"4":[91,357],"5":[159,516],"6":[29,130],"7":[35,95],"8":[196,415]},"meta":{"lastBranch":9,"lastFunction":3,"lastStatement":39,"seen":{"s:17:25:17:Infinity":0,"s:20:28:20:Infinity":1,"s:23:28:23:Infinity":2,"s:26:30:26:Infinity":3,"f:34:16:34:35":0,"s:35:13:35:Infinity":4,"s:36:18:36:Infinity":5,"s:38:2:50:Infinity":6,"b:39:4:42:Infinity:undefined:undefined:undefined:undefined":0,"s:39:4:42:Infinity":7,"s:40:6:40:Infinity":8,"s:41:6:41:Infinity":9,"b:43:4:48:Infinity:undefined:undefined:undefined:undefined":1,"s:43:4:48:Infinity":10,"b:44:6:46:Infinity:undefined:undefined:undefined:undefined":2,"s:44:6:46:Infinity":11,"s:45:8:45:Infinity":12,"s:47:6:47:Infinity":13,"s:49:4:49:Infinity":14,"s:52:2:52:Infinity":15,"f:62:16:62:27":1,"s:63:2:69:Infinity":16,"s:64:25:64:Infinity":17,"b:65:4:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:4:65:Infinity":18,"s:65:23:65:Infinity":19,"s:67:17:67:Infinity":20,"b:68:4:68:Infinity:undefined:undefined:undefined:undefined":4,"s:68:4:68:Infinity":21,"s:68:28:68:Infinity":22,"s:70:2:70:Infinity":23,"f:78:16:78:31":2,"s:79:16:79:Infinity":24,"s:80:18:80:Infinity":25,"s:81:30:81:Infinity":26,"s:82:2:93:Infinity":27,"s:83:25:83:Infinity":28,"b:84:4:91:Infinity:undefined:undefined:undefined:undefined":5,"s:84:4:91:Infinity":29,"s:85:19:85:Infinity":30,"b:86:6:86:Infinity:undefined:undefined:undefined:undefined":6,"s:86:6:86:Infinity":31,"s:86:21:86:Infinity":32,"b:87:6:90:Infinity:undefined:undefined:undefined:undefined":7,"s:87:6:90:Infinity":33,"s:88:8:88:Infinity":34,"s:89:8:89:Infinity":35,"b:92:4:92:Infinity:undefined:undefined:undefined:undefined":8,"s:92:4:92:Infinity":36,"s:92:19:92:Infinity":37,"s:94:2:94:Infinity":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/classifier.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/classifier.ts","statementMap":{"0":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"1":{"start":{"line":66,"column":12},"end":{"line":66,"column":null}},"2":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"3":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"4":{"start":{"line":70,"column":2},"end":{"line":75,"column":null}},"5":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"6":{"start":{"line":87,"column":33},"end":{"line":87,"column":null}},"7":{"start":{"line":88,"column":14},"end":{"line":88,"column":null}},"8":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"9":{"start":{"line":89,"column":27},"end":{"line":89,"column":null}},"10":{"start":{"line":90,"column":21},"end":{"line":94,"column":null}},"11":{"start":{"line":95,"column":2},"end":{"line":97,"column":null}},"12":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"13":{"start":{"line":96,"column":26},"end":{"line":96,"column":null}},"14":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"15":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"16":{"start":{"line":115,"column":47},"end":{"line":115,"column":null}},"17":{"start":{"line":117,"column":25},"end":{"line":117,"column":null}},"18":{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},"19":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"20":{"start":{"line":121,"column":4},"end":{"line":124,"column":null}},"21":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"22":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"23":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"24":{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},"25":{"start":{"line":133,"column":19},"end":{"line":133,"column":null}},"26":{"start":{"line":134,"column":30},"end":{"line":136,"column":null}},"27":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"28":{"start":{"line":137,"column":32},"end":{"line":139,"column":null}},"29":{"start":{"line":138,"column":13},"end":{"line":138,"column":null}},"30":{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},"31":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"32":{"start":{"line":142,"column":6},"end":{"line":147,"column":null}},"33":{"start":{"line":151,"column":2},"end":{"line":151,"column":null}},"34":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"35":{"start":{"line":159,"column":24},"end":{"line":163,"column":null}}},"fnMap":{"0":{"name":"parseArticleFilename","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":37}},"loc":{"start":{"line":64,"column":74},"end":{"line":76,"column":null}},"line":64},"1":{"name":"findAnalysisSource","decl":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"loc":{"start":{"line":86,"column":17},"end":{"line":99,"column":null}},"line":86},"2":{"name":"classify","decl":{"start":{"line":109,"column":16},"end":{"line":109,"column":null}},"loc":{"start":{"line":113,"column":24},"end":{"line":152,"column":null}},"line":113},"3":{"name":"(anonymous_3)","decl":{"start":{"line":134,"column":50},"end":{"line":134,"column":null}},"loc":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"line":135},"4":{"name":"(anonymous_4)","decl":{"start":{"line":137,"column":52},"end":{"line":137,"column":null}},"loc":{"start":{"line":138,"column":13},"end":{"line":138,"column":null}},"line":138},"5":{"name":"isKnownLang","decl":{"start":{"line":155,"column":16},"end":{"line":155,"column":28}},"loc":{"start":{"line":155,"column":60},"end":{"line":157,"column":null}},"line":155}},"branchMap":{"0":{"loc":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":67},"1":{"loc":{"start":{"line":72,"column":10},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":10},"end":{"line":72,"column":18}},{"start":{"line":72,"column":18},"end":{"line":72,"column":null}}],"line":72},"2":{"loc":{"start":{"line":73,"column":15},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":23}},{"start":{"line":73,"column":23},"end":{"line":73,"column":null}}],"line":73},"3":{"loc":{"start":{"line":74,"column":11},"end":{"line":74,"column":21}},"type":"binary-expr","locations":[{"start":{"line":74,"column":11},"end":{"line":74,"column":19}},{"start":{"line":74,"column":19},"end":{"line":74,"column":21}}],"line":74},"4":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"5":{"loc":{"start":{"line":87,"column":6},"end":{"line":87,"column":33}},"type":"binary-expr","locations":[{"start":{"line":87,"column":6},"end":{"line":87,"column":18}},{"start":{"line":87,"column":18},"end":{"line":87,"column":33}}],"line":87},"6":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"7":{"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"8":{"loc":{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":119},"9":{"loc":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":127},"10":{"loc":{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":132},"11":{"loc":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"type":"binary-expr","locations":[{"start":{"line":135,"column":13},"end":{"line":135,"column":51}},{"start":{"line":135,"column":51},"end":{"line":135,"column":null}}],"line":135},"12":{"loc":{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},{"start":{},"end":{}}],"line":140},"13":{"loc":{"start":{"line":140,"column":8},"end":{"line":140,"column":50}},"type":"binary-expr","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":29}},{"start":{"line":140,"column":29},"end":{"line":140,"column":50}}],"line":140},"14":{"loc":{"start":{"line":145,"column":11},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":31},"end":{"line":145,"column":53}},{"start":{"line":145,"column":53},"end":{"line":145,"column":null}}],"line":145},"15":{"loc":{"start":{"line":146,"column":11},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":54},"end":{"line":146,"column":62}},{"start":{"line":146,"column":62},"end":{"line":146,"column":null}}],"line":146},"16":{"loc":{"start":{"line":146,"column":11},"end":{"line":146,"column":54}},"type":"binary-expr","locations":[{"start":{"line":146,"column":11},"end":{"line":146,"column":32}},{"start":{"line":146,"column":32},"end":{"line":146,"column":54}}],"line":146},"17":{"loc":{"start":{"line":147,"column":11},"end":{"line":147,"column":51}},"type":"cond-expr","locations":[{"start":{"line":147,"column":33},"end":{"line":147,"column":48}},{"start":{"line":147,"column":48},"end":{"line":147,"column":51}}],"line":147}},"s":{"0":30,"1":30,"2":30,"3":1,"4":29,"5":19,"6":0,"7":19,"8":19,"9":15,"10":4,"11":4,"12":4,"13":4,"14":0,"15":17,"16":17,"17":17,"18":17,"19":3,"20":3,"21":17,"22":14,"23":14,"24":17,"25":9,"26":9,"27":20,"28":9,"29":20,"30":9,"31":9,"32":9,"33":17,"34":19,"35":2},"f":{"0":30,"1":19,"2":17,"3":20,"4":20,"5":19},"b":{"0":[1,29],"1":[29,0],"2":[30,0],"3":[30,0],"4":[0,19],"5":[19,19],"6":[15,4],"7":[4,0],"8":[3,14],"9":[14,3],"10":[9,8],"11":[20,12],"12":[9,0],"13":[9,1],"14":[8,1],"15":[0,9],"16":[9,8],"17":[1,8]},"meta":{"lastBranch":18,"lastFunction":6,"lastStatement":36,"seen":{"f:64:16:64:37":0,"s:65:15:65:Infinity":0,"s:66:12:66:Infinity":1,"b:67:2:69:Infinity:undefined:undefined:undefined:undefined":0,"s:67:2:69:Infinity":2,"s:68:4:68:Infinity":3,"s:70:2:75:Infinity":4,"b:72:10:72:18:72:18:72:Infinity":1,"b:73:15:73:23:73:23:73:Infinity":2,"b:74:11:74:19:74:19:74:21":3,"f:83:16:83:Infinity":1,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":4,"s:87:2:87:Infinity":5,"b:87:6:87:18:87:18:87:33":5,"s:87:33:87:Infinity":6,"s:88:14:88:Infinity":7,"b:89:2:89:Infinity:undefined:undefined:undefined:undefined":6,"s:89:2:89:Infinity":8,"s:89:27:89:Infinity":9,"s:90:21:94:Infinity":10,"s:95:2:97:Infinity":11,"b:96:4:96:Infinity:undefined:undefined:undefined:undefined":7,"s:96:4:96:Infinity":12,"s:96:26:96:Infinity":13,"s:98:2:98:Infinity":14,"f:109:16:109:Infinity":2,"s:114:24:114:Infinity":15,"s:115:47:115:Infinity":16,"s:117:25:117:Infinity":17,"b:119:2:125:Infinity:undefined:undefined:undefined:undefined":8,"s:119:2:125:Infinity":18,"s:120:4:120:Infinity":19,"s:121:4:124:Infinity":20,"b:127:2:130:Infinity:undefined:undefined:undefined:undefined":9,"s:127:2:130:Infinity":21,"s:128:4:128:Infinity":22,"s:129:4:129:Infinity":23,"b:132:2:149:Infinity:undefined:undefined:undefined:undefined":10,"s:132:2:149:Infinity":24,"s:133:19:133:Infinity":25,"s:134:30:136:Infinity":26,"f:134:50:134:Infinity":3,"s:135:13:135:Infinity":27,"b:135:13:135:51:135:51:135:Infinity":11,"s:137:32:139:Infinity":28,"f:137:52:137:Infinity":4,"s:138:13:138:Infinity":29,"b:140:4:148:Infinity:undefined:undefined:undefined:undefined":12,"s:140:4:148:Infinity":30,"b:140:8:140:29:140:29:140:50":13,"s:141:6:141:Infinity":31,"s:142:6:147:Infinity":32,"b:145:31:145:53:145:53:145:Infinity":14,"b:146:54:146:62:146:62:146:Infinity":15,"b:146:11:146:32:146:32:146:54":16,"b:147:33:147:48:147:48:147:51":17,"s:151:2:151:Infinity":33,"f:155:16:155:28":5,"s:156:2:156:Infinity":34,"s:159:24:163:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/contract-checker.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/contract-checker.ts","statementMap":{"0":{"start":{"line":52,"column":33},"end":{"line":57,"column":null}},"1":{"start":{"line":60,"column":31},"end":{"line":65,"column":null}},"2":{"start":{"line":68,"column":31},"end":{"line":73,"column":null}},"3":{"start":{"line":76,"column":58},"end":{"line":92,"column":null}},"4":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"5":{"start":{"line":102,"column":55},"end":{"line":111,"column":null}},"6":{"start":{"line":115,"column":61},"end":{"line":128,"column":null}},"7":{"start":{"line":131,"column":27},"end":{"line":131,"column":null}},"8":{"start":{"line":137,"column":33},"end":{"line":137,"column":null}},"9":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"10":{"start":{"line":147,"column":38},"end":{"line":147,"column":null}},"11":{"start":{"line":152,"column":37},"end":{"line":152,"column":null}},"12":{"start":{"line":184,"column":14},"end":{"line":184,"column":null}},"13":{"start":{"line":185,"column":2},"end":{"line":185,"column":null}},"14":{"start":{"line":198,"column":42},"end":{"line":198,"column":null}},"15":{"start":{"line":199,"column":17},"end":{"line":199,"column":null}},"16":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"17":{"start":{"line":202,"column":22},"end":{"line":202,"column":null}},"18":{"start":{"line":204,"column":19},"end":{"line":204,"column":null}},"19":{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},"20":{"start":{"line":206,"column":4},"end":{"line":211,"column":null}},"21":{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},"22":{"start":{"line":214,"column":6},"end":{"line":219,"column":null}},"23":{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},"24":{"start":{"line":222,"column":6},"end":{"line":227,"column":null}},"25":{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},"26":{"start":{"line":232,"column":4},"end":{"line":237,"column":null}},"27":{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},"28":{"start":{"line":241,"column":4},"end":{"line":246,"column":null}},"29":{"start":{"line":249,"column":2},"end":{"line":259,"column":null}},"30":{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},"31":{"start":{"line":251,"column":6},"end":{"line":256,"column":null}},"32":{"start":{"line":257,"column":6},"end":{"line":257,"column":null}},"33":{"start":{"line":261,"column":22},"end":{"line":261,"column":null}},"34":{"start":{"line":262,"column":18},"end":{"line":262,"column":null}},"35":{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},"36":{"start":{"line":265,"column":4},"end":{"line":270,"column":null}},"37":{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},"38":{"start":{"line":273,"column":6},"end":{"line":278,"column":null}},"39":{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},"40":{"start":{"line":281,"column":6},"end":{"line":286,"column":null}},"41":{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},"42":{"start":{"line":290,"column":6},"end":{"line":295,"column":null}},"43":{"start":{"line":296,"column":23},"end":{"line":296,"column":null}},"44":{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},"45":{"start":{"line":298,"column":8},"end":{"line":303,"column":null}},"46":{"start":{"line":307,"column":4},"end":{"line":317,"column":null}},"47":{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},"48":{"start":{"line":309,"column":8},"end":{"line":314,"column":null}},"49":{"start":{"line":315,"column":8},"end":{"line":315,"column":null}},"50":{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},"51":{"start":{"line":320,"column":6},"end":{"line":325,"column":null}},"52":{"start":{"line":329,"column":2},"end":{"line":333,"column":null}},"53":{"start":{"line":336,"column":24},"end":{"line":341,"column":null}}},"fnMap":{"0":{"name":"visualLength","decl":{"start":{"line":97,"column":9},"end":{"line":97,"column":22}},"loc":{"start":{"line":97,"column":44},"end":{"line":99,"column":null}},"line":97},"1":{"name":"windowFor","decl":{"start":{"line":183,"column":16},"end":{"line":183,"column":26}},"loc":{"start":{"line":183,"column":52},"end":{"line":186,"column":null}},"line":183},"2":{"name":"checkAgainstContract","decl":{"start":{"line":194,"column":16},"end":{"line":194,"column":null}},"loc":{"start":{"line":197,"column":18},"end":{"line":334,"column":null}},"line":197}},"branchMap":{"0":{"loc":{"start":{"line":185,"column":9},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":9},"end":{"line":185,"column":30}},{"start":{"line":185,"column":30},"end":{"line":185,"column":null}}],"line":185},"1":{"loc":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"type":"binary-expr","locations":[{"start":{"line":201,"column":16},"end":{"line":201,"column":30}},{"start":{"line":201,"column":30},"end":{"line":201,"column":null}}],"line":201},"2":{"loc":{"start":{"line":202,"column":22},"end":{"line":202,"column":null}},"type":"binary-expr","locations":[{"start":{"line":202,"column":22},"end":{"line":202,"column":42}},{"start":{"line":202,"column":42},"end":{"line":202,"column":null}}],"line":202},"3":{"loc":{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},"type":"if","locations":[{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},{"start":{"line":212,"column":9},"end":{"line":229,"column":null}}],"line":205},"4":{"loc":{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":213},"5":{"loc":{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},{"start":{},"end":{}}],"line":221},"6":{"loc":{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},"type":"if","locations":[{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},{"start":{},"end":{}}],"line":231},"7":{"loc":{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},{"start":{},"end":{}}],"line":240},"8":{"loc":{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},"type":"if","locations":[{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},{"start":{},"end":{}}],"line":250},"9":{"loc":{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},"type":"if","locations":[{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},{"start":{"line":271,"column":9},"end":{"line":327,"column":null}}],"line":264},"10":{"loc":{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},"type":"if","locations":[{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},{"start":{},"end":{}}],"line":272},"11":{"loc":{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":280},"12":{"loc":{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},"type":"if","locations":[{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},{"start":{},"end":{}}],"line":289},"13":{"loc":{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},"type":"if","locations":[{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},{"start":{},"end":{}}],"line":297},"14":{"loc":{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},"type":"if","locations":[{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},{"start":{},"end":{}}],"line":308},"15":{"loc":{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},{"start":{},"end":{}}],"line":319}},"s":{"0":3,"1":3,"2":3,"3":3,"4":426,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":61,"13":61,"14":44,"15":44,"16":44,"17":44,"18":44,"19":44,"20":3,"21":41,"22":11,"23":41,"24":10,"25":44,"26":8,"27":44,"28":11,"29":44,"30":334,"31":3,"32":3,"33":44,"34":44,"35":44,"36":3,"37":41,"38":13,"39":41,"40":1,"41":41,"42":1,"43":1,"44":1,"45":1,"46":41,"47":465,"48":3,"49":3,"50":41,"51":1,"52":44,"53":3},"f":{"0":426,"1":61,"2":44},"b":{"0":[61,1],"1":[44,0],"2":[44,0],"3":[3,41],"4":[11,30],"5":[10,31],"6":[8,36],"7":[11,33],"8":[3,331],"9":[3,41],"10":[13,28],"11":[1,40],"12":[1,40],"13":[1,0],"14":[3,462],"15":[1,40]},"meta":{"lastBranch":16,"lastFunction":3,"lastStatement":54,"seen":{"s:52:33:57:Infinity":0,"s:60:31:65:Infinity":1,"s:68:31:73:Infinity":2,"s:76:58:92:Infinity":3,"f:97:9:97:22":0,"s:98:2:98:Infinity":4,"s:102:55:111:Infinity":5,"s:115:61:128:Infinity":6,"s:131:27:131:Infinity":7,"s:137:33:137:Infinity":8,"s:142:2:142:Infinity":9,"s:147:38:147:Infinity":10,"s:152:37:152:Infinity":11,"f:183:16:183:26":1,"s:184:14:184:Infinity":12,"s:185:2:185:Infinity":13,"b:185:9:185:30:185:30:185:Infinity":0,"f:194:16:194:Infinity":2,"s:198:42:198:Infinity":14,"s:199:17:199:Infinity":15,"s:201:16:201:Infinity":16,"b:201:16:201:30:201:30:201:Infinity":1,"s:202:22:202:Infinity":17,"b:202:22:202:42:202:42:202:Infinity":2,"s:204:19:204:Infinity":18,"b:205:2:229:Infinity:212:9:229:Infinity":3,"s:205:2:229:Infinity":19,"s:206:4:211:Infinity":20,"b:213:4:220:Infinity:undefined:undefined:undefined:undefined":4,"s:213:4:220:Infinity":21,"s:214:6:219:Infinity":22,"b:221:4:228:Infinity:undefined:undefined:undefined:undefined":5,"s:221:4:228:Infinity":23,"s:222:6:227:Infinity":24,"b:231:2:238:Infinity:undefined:undefined:undefined:undefined":6,"s:231:2:238:Infinity":25,"s:232:4:237:Infinity":26,"b:240:2:247:Infinity:undefined:undefined:undefined:undefined":7,"s:240:2:247:Infinity":27,"s:241:4:246:Infinity":28,"s:249:2:259:Infinity":29,"b:250:4:258:Infinity:undefined:undefined:undefined:undefined":8,"s:250:4:258:Infinity":30,"s:251:6:256:Infinity":31,"s:257:6:257:Infinity":32,"s:261:22:261:Infinity":33,"s:262:18:262:Infinity":34,"b:264:2:327:Infinity:271:9:327:Infinity":9,"s:264:2:327:Infinity":35,"s:265:4:270:Infinity":36,"b:272:4:279:Infinity:undefined:undefined:undefined:undefined":10,"s:272:4:279:Infinity":37,"s:273:6:278:Infinity":38,"b:280:4:287:Infinity:undefined:undefined:undefined:undefined":11,"s:280:4:287:Infinity":39,"s:281:6:286:Infinity":40,"b:289:4:305:Infinity:undefined:undefined:undefined:undefined":12,"s:289:4:305:Infinity":41,"s:290:6:295:Infinity":42,"s:296:23:296:Infinity":43,"b:297:6:304:Infinity:undefined:undefined:undefined:undefined":13,"s:297:6:304:Infinity":44,"s:298:8:303:Infinity":45,"s:307:4:317:Infinity":46,"b:308:6:316:Infinity:undefined:undefined:undefined:undefined":14,"s:308:6:316:Infinity":47,"s:309:8:314:Infinity":48,"s:315:8:315:Infinity":49,"b:319:4:326:Infinity:undefined:undefined:undefined:undefined":15,"s:319:4:326:Infinity":50,"s:320:6:325:Infinity":51,"s:329:2:333:Infinity":52,"s:336:24:341:Infinity":53}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/html-inspector.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/html-inspector.ts","statementMap":{"0":{"start":{"line":59,"column":16},"end":{"line":63,"column":null}},"1":{"start":{"line":69,"column":40},"end":{"line":76,"column":null}},"2":{"start":{"line":77,"column":2},"end":{"line":89,"column":null}},"3":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"4":{"start":{"line":79,"column":15},"end":{"line":79,"column":null}},"5":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"6":{"start":{"line":80,"column":15},"end":{"line":80,"column":null}},"7":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"8":{"start":{"line":81,"column":28},"end":{"line":81,"column":null}},"9":{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},"10":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"11":{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},"12":{"start":{"line":85,"column":10},"end":{"line":85,"column":null}},"13":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"14":{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},"15":{"start":{"line":98,"column":4},"end":{"line":98,"column":null}},"16":{"start":{"line":100,"column":2},"end":{"line":100,"column":null}},"17":{"start":{"line":107,"column":2},"end":{"line":113,"column":null}},"18":{"start":{"line":118,"column":12},"end":{"line":118,"column":null}},"19":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"20":{"start":{"line":127,"column":14},"end":{"line":127,"column":null}},"21":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"22":{"start":{"line":136,"column":14},"end":{"line":136,"column":null}},"23":{"start":{"line":137,"column":20},"end":{"line":137,"column":null}},"24":{"start":{"line":139,"column":2},"end":{"line":152,"column":null}},"25":{"start":{"line":140,"column":18},"end":{"line":140,"column":null}},"26":{"start":{"line":141,"column":20},"end":{"line":141,"column":null}},"27":{"start":{"line":142,"column":17},"end":{"line":142,"column":null}},"28":{"start":{"line":143,"column":21},"end":{"line":143,"column":null}},"29":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"30":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"31":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"32":{"start":{"line":146,"column":25},"end":{"line":146,"column":null}},"33":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"34":{"start":{"line":149,"column":18},"end":{"line":149,"column":null}},"35":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"36":{"start":{"line":150,"column":25},"end":{"line":150,"column":null}},"37":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"38":{"start":{"line":157,"column":40},"end":{"line":157,"column":null}},"39":{"start":{"line":158,"column":17},"end":{"line":158,"column":null}},"40":{"start":{"line":160,"column":2},"end":{"line":162,"column":null}},"41":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"42":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"43":{"start":{"line":171,"column":12},"end":{"line":171,"column":null}},"44":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"45":{"start":{"line":172,"column":10},"end":{"line":172,"column":null}},"46":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"47":{"start":{"line":174,"column":2},"end":{"line":174,"column":null}},"48":{"start":{"line":182,"column":19},"end":{"line":182,"column":null}},"49":{"start":{"line":183,"column":28},"end":{"line":183,"column":null}},"50":{"start":{"line":185,"column":2},"end":{"line":195,"column":null}},"51":{"start":{"line":186,"column":18},"end":{"line":186,"column":null}},"52":{"start":{"line":187,"column":10},"end":{"line":187,"column":null}},"53":{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},"54":{"start":{"line":188,"column":40},"end":{"line":188,"column":null}},"55":{"start":{"line":189,"column":17},"end":{"line":189,"column":null}},"56":{"start":{"line":190,"column":4},"end":{"line":194,"column":null}},"57":{"start":{"line":191,"column":6},"end":{"line":191,"column":null}},"58":{"start":{"line":196,"column":2},"end":{"line":196,"column":null}},"59":{"start":{"line":203,"column":2},"end":{"line":206,"column":null}},"60":{"start":{"line":204,"column":18},"end":{"line":204,"column":null}},"61":{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},"62":{"start":{"line":205,"column":15},"end":{"line":205,"column":null}},"63":{"start":{"line":207,"column":2},"end":{"line":207,"column":null}},"64":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"65":{"start":{"line":214,"column":45},"end":{"line":214,"column":null}},"66":{"start":{"line":215,"column":32},"end":{"line":215,"column":null}},"67":{"start":{"line":216,"column":17},"end":{"line":216,"column":null}},"68":{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},"69":{"start":{"line":218,"column":4},"end":{"line":218,"column":null}},"70":{"start":{"line":220,"column":2},"end":{"line":220,"column":null}},"71":{"start":{"line":221,"column":2},"end":{"line":226,"column":null}},"72":{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},"73":{"start":{"line":223,"column":17},"end":{"line":223,"column":null}},"74":{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},"75":{"start":{"line":224,"column":56},"end":{"line":224,"column":null}},"76":{"start":{"line":227,"column":2},"end":{"line":227,"column":null}},"77":{"start":{"line":236,"column":15},"end":{"line":236,"column":null}},"78":{"start":{"line":237,"column":2},"end":{"line":237,"column":null}},"79":{"start":{"line":246,"column":15},"end":{"line":246,"column":null}},"80":{"start":{"line":247,"column":16},"end":{"line":247,"column":null}},"81":{"start":{"line":249,"column":18},"end":{"line":249,"column":null}},"82":{"start":{"line":250,"column":23},"end":{"line":250,"column":null}},"83":{"start":{"line":252,"column":26},"end":{"line":252,"column":null}},"84":{"start":{"line":253,"column":18},"end":{"line":253,"column":null}},"85":{"start":{"line":254,"column":24},"end":{"line":254,"column":null}},"86":{"start":{"line":255,"column":23},"end":{"line":255,"column":null}},"87":{"start":{"line":256,"column":29},"end":{"line":256,"column":null}},"88":{"start":{"line":258,"column":25},"end":{"line":258,"column":null}},"89":{"start":{"line":259,"column":36},"end":{"line":259,"column":null}},"90":{"start":{"line":260,"column":28},"end":{"line":260,"column":null}},"91":{"start":{"line":262,"column":23},"end":{"line":262,"column":null}},"92":{"start":{"line":263,"column":24},"end":{"line":265,"column":null}},"93":{"start":{"line":267,"column":2},"end":{"line":280,"column":null}},"94":{"start":{"line":283,"column":24},"end":{"line":289,"column":null}}},"fnMap":{"0":{"name":"htmlDecode","decl":{"start":{"line":68,"column":9},"end":{"line":68,"column":20}},"loc":{"start":{"line":68,"column":39},"end":{"line":90,"column":null}},"line":68},"1":{"name":"(anonymous_1)","decl":{"start":{"line":77,"column":19},"end":{"line":77,"column":null}},"loc":{"start":{"line":78,"column":57},"end":{"line":89,"column":5}},"line":78},"2":{"name":"decodeCodePoint","decl":{"start":{"line":92,"column":9},"end":{"line":92,"column":25}},"loc":{"start":{"line":92,"column":66},"end":{"line":101,"column":null}},"line":92},"3":{"name":"stripTags","decl":{"start":{"line":106,"column":9},"end":{"line":106,"column":19}},"loc":{"start":{"line":106,"column":45},"end":{"line":114,"column":null}},"line":106},"4":{"name":"match1","decl":{"start":{"line":117,"column":9},"end":{"line":117,"column":16}},"loc":{"start":{"line":117,"column":50},"end":{"line":120,"column":null}},"line":117},"5":{"name":"extractMetaContent","decl":{"start":{"line":122,"column":9},"end":{"line":122,"column":null}},"loc":{"start":{"line":126,"column":10},"end":{"line":129,"column":null}},"line":126},"6":{"name":"parseAllMetaTags","decl":{"start":{"line":135,"column":9},"end":{"line":135,"column":26}},"loc":{"start":{"line":135,"column":61},"end":{"line":154,"column":null}},"line":135},"7":{"name":"parseAttributes","decl":{"start":{"line":156,"column":9},"end":{"line":156,"column":25}},"loc":{"start":{"line":156,"column":62},"end":{"line":164,"column":null}},"line":156},"8":{"name":"extractHtmlLang","decl":{"start":{"line":170,"column":9},"end":{"line":170,"column":25}},"loc":{"start":{"line":170,"column":47},"end":{"line":175,"column":null}},"line":170},"9":{"name":"parseAllJsonLdBlocks","decl":{"start":{"line":181,"column":9},"end":{"line":181,"column":30}},"loc":{"start":{"line":181,"column":64},"end":{"line":197,"column":null}},"line":181},"10":{"name":"readJsonLdFieldFromBlocks","decl":{"start":{"line":199,"column":9},"end":{"line":199,"column":null}},"loc":{"start":{"line":202,"column":10},"end":{"line":208,"column":null}},"line":202},"11":{"name":"readJsonLdField","decl":{"start":{"line":210,"column":9},"end":{"line":210,"column":null}},"loc":{"start":{"line":213,"column":10},"end":{"line":228,"column":null}},"line":213},"12":{"name":"inspectHtmlFile","decl":{"start":{"line":235,"column":16},"end":{"line":235,"column":32}},"loc":{"start":{"line":235,"column":67},"end":{"line":238,"column":null}},"line":235},"13":{"name":"inspectHtmlContent","decl":{"start":{"line":245,"column":16},"end":{"line":245,"column":35}},"loc":{"start":{"line":245,"column":89},"end":{"line":281,"column":null}},"line":245}},"branchMap":{"0":{"loc":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79},"1":{"loc":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"2":{"loc":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":81},"3":{"loc":{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":82},"4":{"loc":{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":84},"5":{"loc":{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":93},"6":{"loc":{"start":{"line":94,"column":4},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{"line":96,"column":5},"end":{"line":96,"column":24}},{"start":{"line":96,"column":24},"end":{"line":96,"column":null}}],"line":94},"7":{"loc":{"start":{"line":119,"column":9},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":13},"end":{"line":119,"column":45}},{"start":{"line":119,"column":45},"end":{"line":119,"column":null}}],"line":119},"8":{"loc":{"start":{"line":119,"column":24},"end":{"line":119,"column":34}},"type":"binary-expr","locations":[{"start":{"line":119,"column":24},"end":{"line":119,"column":32}},{"start":{"line":119,"column":32},"end":{"line":119,"column":34}}],"line":119},"9":{"loc":{"start":{"line":128,"column":9},"end":{"line":128,"column":null}},"type":"binary-expr","locations":[{"start":{"line":128,"column":9},"end":{"line":128,"column":70}},{"start":{"line":128,"column":70},"end":{"line":128,"column":null}}],"line":128},"10":{"loc":{"start":{"line":141,"column":31},"end":{"line":141,"column":50}},"type":"binary-expr","locations":[{"start":{"line":141,"column":31},"end":{"line":141,"column":48}},{"start":{"line":141,"column":48},"end":{"line":141,"column":50}}],"line":141},"11":{"loc":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":144},"12":{"loc":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":146},"13":{"loc":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},{"start":{},"end":{}}],"line":148},"14":{"loc":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},{"start":{},"end":{}}],"line":150},"15":{"loc":{"start":{"line":161,"column":33},"end":{"line":161,"column":null}},"type":"binary-expr","locations":[{"start":{"line":161,"column":33},"end":{"line":161,"column":41}},{"start":{"line":161,"column":41},"end":{"line":161,"column":49}},{"start":{"line":161,"column":49},"end":{"line":161,"column":57}},{"start":{"line":161,"column":57},"end":{"line":161,"column":null}}],"line":161},"16":{"loc":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":172},"17":{"loc":{"start":{"line":174,"column":20},"end":{"line":174,"column":36}},"type":"binary-expr","locations":[{"start":{"line":174,"column":20},"end":{"line":174,"column":34}},{"start":{"line":174,"column":34},"end":{"line":174,"column":36}}],"line":174},"18":{"loc":{"start":{"line":186,"column":45},"end":{"line":186,"column":56}},"type":"binary-expr","locations":[{"start":{"line":186,"column":45},"end":{"line":186,"column":53}},{"start":{"line":186,"column":53},"end":{"line":186,"column":56}}],"line":186},"19":{"loc":{"start":{"line":187,"column":18},"end":{"line":187,"column":34}},"type":"binary-expr","locations":[{"start":{"line":187,"column":18},"end":{"line":187,"column":32}},{"start":{"line":187,"column":32},"end":{"line":187,"column":34}}],"line":187},"20":{"loc":{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},{"start":{},"end":{}}],"line":188},"21":{"loc":{"start":{"line":189,"column":17},"end":{"line":189,"column":null}},"type":"binary-expr","locations":[{"start":{"line":189,"column":17},"end":{"line":189,"column":25}},{"start":{"line":189,"column":25},"end":{"line":189,"column":null}}],"line":189},"22":{"loc":{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},"type":"if","locations":[{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},{"start":{},"end":{}}],"line":205},"23":{"loc":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"24":{"loc":{"start":{"line":214,"column":6},"end":{"line":214,"column":45}},"type":"binary-expr","locations":[{"start":{"line":214,"column":6},"end":{"line":214,"column":17}},{"start":{"line":214,"column":17},"end":{"line":214,"column":45}}],"line":214},"25":{"loc":{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},"type":"if","locations":[{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},{"start":{},"end":{}}],"line":217},"26":{"loc":{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},{"start":{},"end":{}}],"line":222},"27":{"loc":{"start":{"line":222,"column":8},"end":{"line":222,"column":36}},"type":"binary-expr","locations":[{"start":{"line":222,"column":8},"end":{"line":222,"column":13}},{"start":{"line":222,"column":13},"end":{"line":222,"column":36}}],"line":222},"28":{"loc":{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},"type":"if","locations":[{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},{"start":{},"end":{}}],"line":224},"29":{"loc":{"start":{"line":224,"column":10},"end":{"line":224,"column":56}},"type":"binary-expr","locations":[{"start":{"line":224,"column":10},"end":{"line":224,"column":35}},{"start":{"line":224,"column":35},"end":{"line":224,"column":56}}],"line":224},"30":{"loc":{"start":{"line":245,"column":49},"end":{"line":245,"column":89}},"type":"default-arg","locations":[{"start":{"line":245,"column":68},"end":{"line":245,"column":89}}],"line":245},"31":{"loc":{"start":{"line":252,"column":26},"end":{"line":252,"column":null}},"type":"binary-expr","locations":[{"start":{"line":252,"column":26},"end":{"line":252,"column":61}},{"start":{"line":252,"column":61},"end":{"line":252,"column":null}}],"line":252},"32":{"loc":{"start":{"line":253,"column":18},"end":{"line":253,"column":null}},"type":"binary-expr","locations":[{"start":{"line":253,"column":18},"end":{"line":253,"column":54}},{"start":{"line":253,"column":54},"end":{"line":253,"column":null}}],"line":253},"33":{"loc":{"start":{"line":254,"column":24},"end":{"line":254,"column":null}},"type":"binary-expr","locations":[{"start":{"line":254,"column":24},"end":{"line":254,"column":66}},{"start":{"line":254,"column":66},"end":{"line":254,"column":null}}],"line":254},"34":{"loc":{"start":{"line":255,"column":23},"end":{"line":255,"column":null}},"type":"binary-expr","locations":[{"start":{"line":255,"column":23},"end":{"line":255,"column":60}},{"start":{"line":255,"column":60},"end":{"line":255,"column":null}}],"line":255},"35":{"loc":{"start":{"line":256,"column":29},"end":{"line":256,"column":null}},"type":"binary-expr","locations":[{"start":{"line":256,"column":29},"end":{"line":256,"column":72}},{"start":{"line":256,"column":72},"end":{"line":256,"column":null}}],"line":256},"36":{"loc":{"start":{"line":263,"column":24},"end":{"line":265,"column":null}},"type":"cond-expr","locations":[{"start":{"line":264,"column":6},"end":{"line":264,"column":null}},{"start":{"line":265,"column":6},"end":{"line":265,"column":null}}],"line":263},"37":{"loc":{"start":{"line":264,"column":16},"end":{"line":264,"column":37}},"type":"binary-expr","locations":[{"start":{"line":264,"column":16},"end":{"line":264,"column":35}},{"start":{"line":264,"column":35},"end":{"line":264,"column":37}}],"line":264}},"s":{"0":3,"1":93,"2":93,"3":11,"4":5,"5":6,"6":6,"7":3,"8":0,"9":3,"10":3,"11":3,"12":3,"13":0,"14":8,"15":3,"16":5,"17":21,"18":27,"19":27,"20":0,"21":0,"22":27,"23":27,"24":27,"25":31,"26":31,"27":31,"28":31,"29":31,"30":23,"31":23,"32":23,"33":31,"34":8,"35":8,"36":8,"37":27,"38":68,"39":68,"40":68,"41":97,"42":68,"43":27,"44":27,"45":0,"46":27,"47":27,"48":27,"49":27,"50":27,"51":10,"52":10,"53":10,"54":1,"55":9,"56":10,"57":10,"58":27,"59":81,"60":24,"61":24,"62":13,"63":68,"64":24,"65":0,"66":24,"67":24,"68":24,"69":3,"70":24,"71":24,"72":26,"73":26,"74":26,"75":13,"76":11,"77":10,"78":10,"79":27,"80":27,"81":27,"82":27,"83":27,"84":27,"85":27,"86":27,"87":27,"88":27,"89":27,"90":27,"91":27,"92":27,"93":27,"94":3},"f":{"0":93,"1":11,"2":8,"3":21,"4":27,"5":0,"6":27,"7":68,"8":27,"9":27,"10":81,"11":24,"12":10,"13":27},"b":{"0":[5,6],"1":[3,3],"2":[0,3],"3":[3,0],"4":[3,0],"5":[3,5],"6":[8,8,6,1],"7":[27,0],"8":[27,0],"9":[0,0],"10":[31,0],"11":[23,8],"12":[23,0],"13":[8,23],"14":[8,0],"15":[97,5,3,0],"16":[0,27],"17":[27,2],"18":[10,0],"19":[10,1],"20":[1,9],"21":[9,0],"22":[13,11],"23":[0,24],"24":[24,24],"25":[3,21],"26":[26,0],"27":[26,26],"28":[13,13],"29":[26,13],"30":[27],"31":[27,12],"32":[27,23],"33":[27,23],"34":[27,23],"35":[27,23],"36":[16,11],"37":[16,0]},"meta":{"lastBranch":38,"lastFunction":14,"lastStatement":95,"seen":{"s:59:16:63:Infinity":0,"f:68:9:68:20":0,"s:69:40:76:Infinity":1,"s:77:2:89:Infinity":2,"f:77:19:77:Infinity":1,"b:79:6:79:Infinity:undefined:undefined:undefined:undefined":0,"s:79:6:79:Infinity":3,"s:79:15:79:Infinity":4,"b:80:6:80:Infinity:undefined:undefined:undefined:undefined":1,"s:80:6:80:Infinity":5,"s:80:15:80:Infinity":6,"b:81:6:81:Infinity:undefined:undefined:undefined:undefined":2,"s:81:6:81:Infinity":7,"s:81:28:81:Infinity":8,"b:82:6:87:Infinity:undefined:undefined:undefined:undefined":3,"s:82:6:87:Infinity":9,"s:83:22:83:Infinity":10,"b:84:8:86:Infinity:undefined:undefined:undefined:undefined":4,"s:84:8:86:Infinity":11,"s:85:10:85:Infinity":12,"s:88:6:88:Infinity":13,"f:92:9:92:25":2,"b:93:2:99:Infinity:undefined:undefined:undefined:undefined":5,"s:93:2:99:Infinity":14,"b:94:4:94:Infinity:95:4:95:Infinity:96:5:96:24:96:24:96:Infinity":6,"s:98:4:98:Infinity":15,"s:100:2:100:Infinity":16,"f:106:9:106:19":3,"s:107:2:113:Infinity":17,"f:117:9:117:16":4,"s:118:12:118:Infinity":18,"s:119:2:119:Infinity":19,"b:119:13:119:45:119:45:119:Infinity":7,"b:119:24:119:32:119:32:119:34":8,"f:122:9:122:Infinity":5,"s:127:14:127:Infinity":20,"s:128:2:128:Infinity":21,"b:128:9:128:70:128:70:128:Infinity":9,"f:135:9:135:26":6,"s:136:14:136:Infinity":22,"s:137:20:137:Infinity":23,"s:139:2:152:Infinity":24,"s:140:18:140:Infinity":25,"s:141:20:141:Infinity":26,"b:141:31:141:48:141:48:141:50":10,"s:142:17:142:Infinity":27,"s:143:21:143:Infinity":28,"b:144:4:147:Infinity:undefined:undefined:undefined:undefined":11,"s:144:4:147:Infinity":29,"s:145:18:145:Infinity":30,"b:146:6:146:Infinity:undefined:undefined:undefined:undefined":12,"s:146:6:146:Infinity":31,"s:146:25:146:Infinity":32,"b:148:4:151:Infinity:undefined:undefined:undefined:undefined":13,"s:148:4:151:Infinity":33,"s:149:18:149:Infinity":34,"b:150:6:150:Infinity:undefined:undefined:undefined:undefined":14,"s:150:6:150:Infinity":35,"s:150:25:150:Infinity":36,"s:153:2:153:Infinity":37,"f:156:9:156:25":7,"s:157:40:157:Infinity":38,"s:158:17:158:Infinity":39,"s:160:2:162:Infinity":40,"s:161:4:161:Infinity":41,"b:161:33:161:41:161:41:161:49:161:49:161:57:161:57:161:Infinity":15,"s:163:2:163:Infinity":42,"f:170:9:170:25":8,"s:171:12:171:Infinity":43,"b:172:2:172:Infinity:undefined:undefined:undefined:undefined":16,"s:172:2:172:Infinity":44,"s:172:10:172:Infinity":45,"s:173:16:173:Infinity":46,"s:174:2:174:Infinity":47,"b:174:20:174:34:174:34:174:36":17,"f:181:9:181:30":9,"s:182:19:182:Infinity":48,"s:183:28:183:Infinity":49,"s:185:2:195:Infinity":50,"s:186:18:186:Infinity":51,"b:186:45:186:53:186:53:186:56":18,"s:187:10:187:Infinity":52,"b:187:18:187:32:187:32:187:34":19,"b:188:4:188:Infinity:undefined:undefined:undefined:undefined":20,"s:188:4:188:Infinity":53,"s:188:40:188:Infinity":54,"s:189:17:189:Infinity":55,"b:189:17:189:25:189:25:189:Infinity":21,"s:190:4:194:Infinity":56,"s:191:6:191:Infinity":57,"s:196:2:196:Infinity":58,"f:199:9:199:Infinity":10,"s:203:2:206:Infinity":59,"s:204:18:204:Infinity":60,"b:205:4:205:Infinity:undefined:undefined:undefined:undefined":22,"s:205:4:205:Infinity":61,"s:205:15:205:Infinity":62,"s:207:2:207:Infinity":63,"f:210:9:210:Infinity":11,"b:214:2:214:Infinity:undefined:undefined:undefined:undefined":23,"s:214:2:214:Infinity":64,"b:214:6:214:17:214:17:214:45":24,"s:214:45:214:Infinity":65,"s:215:32:215:Infinity":66,"s:216:17:216:Infinity":67,"b:217:2:219:Infinity:undefined:undefined:undefined:undefined":25,"s:217:2:219:Infinity":68,"s:218:4:218:Infinity":69,"s:220:2:220:Infinity":70,"s:221:2:226:Infinity":71,"b:222:4:225:Infinity:undefined:undefined:undefined:undefined":26,"s:222:4:225:Infinity":72,"b:222:8:222:13:222:13:222:36":27,"s:223:17:223:Infinity":73,"b:224:6:224:Infinity:undefined:undefined:undefined:undefined":28,"s:224:6:224:Infinity":74,"b:224:10:224:35:224:35:224:56":29,"s:224:56:224:Infinity":75,"s:227:2:227:Infinity":76,"f:235:16:235:32":12,"s:236:15:236:Infinity":77,"s:237:2:237:Infinity":78,"f:245:16:245:35":13,"b:245:68:245:89":30,"s:246:15:246:Infinity":79,"s:247:16:247:Infinity":80,"s:249:18:249:Infinity":81,"s:250:23:250:Infinity":82,"s:252:26:252:Infinity":83,"b:252:26:252:61:252:61:252:Infinity":31,"s:253:18:253:Infinity":84,"b:253:18:253:54:253:54:253:Infinity":32,"s:254:24:254:Infinity":85,"b:254:24:254:66:254:66:254:Infinity":33,"s:255:23:255:Infinity":86,"b:255:23:255:60:255:60:255:Infinity":34,"s:256:29:256:Infinity":87,"b:256:29:256:72:256:72:256:Infinity":35,"s:258:25:258:Infinity":88,"s:259:36:259:Infinity":89,"s:260:28:260:Infinity":90,"s:262:23:262:Infinity":91,"s:263:24:265:Infinity":92,"b:264:6:264:Infinity:265:6:265:Infinity":36,"b:264:16:264:35:264:35:264:37":37,"s:267:2:280:Infinity":93,"s:283:24:289:Infinity":94}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/report-writer.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/report-writer.ts","statementMap":{"0":{"start":{"line":40,"column":27},"end":{"line":51,"column":null}},"1":{"start":{"line":69,"column":12},"end":{"line":69,"column":null}},"2":{"start":{"line":70,"column":23},"end":{"line":70,"column":null}},"3":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"4":{"start":{"line":71,"column":21},"end":{"line":71,"column":null}},"5":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"6":{"start":{"line":77,"column":2},"end":{"line":88,"column":null}},"7":{"start":{"line":107,"column":28},"end":{"line":107,"column":null}},"8":{"start":{"line":108,"column":16},"end":{"line":108,"column":null}},"9":{"start":{"line":109,"column":2},"end":{"line":140,"column":null}},"10":{"start":{"line":110,"column":23},"end":{"line":110,"column":null}},"11":{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},"12":{"start":{"line":112,"column":6},"end":{"line":123,"column":null}},"13":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"14":{"start":{"line":126,"column":4},"end":{"line":139,"column":null}},"15":{"start":{"line":127,"column":6},"end":{"line":138,"column":null}},"16":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"17":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}},"18":{"start":{"line":161,"column":13},"end":{"line":161,"column":null}},"19":{"start":{"line":162,"column":2},"end":{"line":171,"column":null}},"20":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"21":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"22":{"start":{"line":165,"column":4},"end":{"line":168,"column":null}},"23":{"start":{"line":166,"column":6},"end":{"line":166,"column":null}},"24":{"start":{"line":167,"column":6},"end":{"line":167,"column":null}},"25":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"26":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"27":{"start":{"line":175,"column":24},"end":{"line":177,"column":null}}},"fnMap":{"0":{"name":"quoteField","decl":{"start":{"line":68,"column":16},"end":{"line":68,"column":27}},"loc":{"start":{"line":68,"column":69},"end":{"line":73,"column":null}},"line":68},"1":{"name":"serialiseRow","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":29}},"loc":{"start":{"line":76,"column":53},"end":{"line":89,"column":null}},"line":76},"2":{"name":"rowsForArticle","decl":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"loc":{"start":{"line":106,"column":24},"end":{"line":142,"column":null}},"line":106},"3":{"name":"writeReport","decl":{"start":{"line":156,"column":16},"end":{"line":156,"column":null}},"loc":{"start":{"line":159,"column":10},"end":{"line":173,"column":null}},"line":159}},"branchMap":{"0":{"loc":{"start":{"line":69,"column":12},"end":{"line":69,"column":null}},"type":"binary-expr","locations":[{"start":{"line":69,"column":12},"end":{"line":69,"column":21}},{"start":{"line":69,"column":21},"end":{"line":69,"column":null}}],"line":69},"1":{"loc":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":71},"2":{"loc":{"start":{"line":108,"column":16},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":50},"end":{"line":108,"column":73}},{"start":{"line":108,"column":73},"end":{"line":108,"column":null}}],"line":108},"3":{"loc":{"start":{"line":110,"column":23},"end":{"line":110,"column":null}},"type":"cond-expr","locations":[{"start":{"line":110,"column":30},"end":{"line":110,"column":75}},{"start":{"line":110,"column":75},"end":{"line":110,"column":null}}],"line":110},"4":{"loc":{"start":{"line":110,"column":30},"end":{"line":110,"column":75}},"type":"binary-expr","locations":[{"start":{"line":110,"column":30},"end":{"line":110,"column":70}},{"start":{"line":110,"column":70},"end":{"line":110,"column":75}}],"line":110},"5":{"loc":{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":111},"6":{"loc":{"start":{"line":114,"column":14},"end":{"line":114,"column":null}},"type":"binary-expr","locations":[{"start":{"line":114,"column":14},"end":{"line":114,"column":25}},{"start":{"line":114,"column":25},"end":{"line":114,"column":null}}],"line":114},"7":{"loc":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":19},"end":{"line":115,"column":35}},{"start":{"line":115,"column":35},"end":{"line":115,"column":null}}],"line":115},"8":{"loc":{"start":{"line":129,"column":14},"end":{"line":129,"column":null}},"type":"binary-expr","locations":[{"start":{"line":129,"column":14},"end":{"line":129,"column":25}},{"start":{"line":129,"column":25},"end":{"line":129,"column":null}}],"line":129},"9":{"loc":{"start":{"line":130,"column":19},"end":{"line":130,"column":null}},"type":"binary-expr","locations":[{"start":{"line":130,"column":19},"end":{"line":130,"column":35}},{"start":{"line":130,"column":35},"end":{"line":130,"column":null}}],"line":130},"10":{"loc":{"start":{"line":137,"column":16},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":137,"column":29},"end":{"line":137,"column":61}},{"start":{"line":137,"column":61},"end":{"line":137,"column":null}}],"line":137}},"s":{"0":1,"1":357,"2":357,"3":357,"4":334,"5":23,"6":35,"7":11,"8":11,"9":11,"10":15,"11":15,"12":1,"13":1,"14":14,"15":40,"16":11,"17":8,"18":8,"19":8,"20":8,"21":8,"22":8,"23":34,"24":34,"25":8,"26":8,"27":1},"f":{"0":357,"1":35,"2":11,"3":8},"b":{"0":[357,2],"1":[334,23],"2":[11,0],"3":[15,0],"4":[15,0],"5":[1,14],"6":[1,0],"7":[1,0],"8":[40,0],"9":[40,0],"10":[40,0]},"meta":{"lastBranch":11,"lastFunction":4,"lastStatement":28,"seen":{"s:40:27:51:Infinity":0,"f:68:16:68:27":0,"s:69:12:69:Infinity":1,"b:69:12:69:21:69:21:69:Infinity":0,"s:70:23:70:Infinity":2,"b:71:2:71:Infinity:undefined:undefined:undefined:undefined":1,"s:71:2:71:Infinity":3,"s:71:21:71:Infinity":4,"s:72:2:72:Infinity":5,"f:76:16:76:29":1,"s:77:2:88:Infinity":6,"f:102:16:102:Infinity":2,"s:107:28:107:Infinity":7,"s:108:16:108:Infinity":8,"b:108:50:108:73:108:73:108:Infinity":2,"s:109:2:140:Infinity":9,"s:110:23:110:Infinity":10,"b:110:30:110:75:110:75:110:Infinity":3,"b:110:30:110:70:110:70:110:75":4,"b:111:4:125:Infinity:undefined:undefined:undefined:undefined":5,"s:111:4:125:Infinity":11,"s:112:6:123:Infinity":12,"b:114:14:114:25:114:25:114:Infinity":6,"b:115:19:115:35:115:35:115:Infinity":7,"s:124:6:124:Infinity":13,"s:126:4:139:Infinity":14,"s:127:6:138:Infinity":15,"b:129:14:129:25:129:25:129:Infinity":8,"b:130:19:130:35:130:35:130:Infinity":9,"b:137:29:137:61:137:61:137:Infinity":10,"s:141:2:141:Infinity":16,"f:156:16:156:Infinity":3,"s:160:2:160:Infinity":17,"s:161:13:161:Infinity":18,"s:162:2:171:Infinity":19,"s:163:4:163:Infinity":20,"s:164:4:164:Infinity":21,"s:165:4:168:Infinity":22,"s:166:6:166:Infinity":23,"s:167:6:167:Infinity":24,"s:170:4:170:Infinity":25,"s:172:2:172:Infinity":26,"s:175:24:177:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-news-og-locale-alternate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-news-og-locale-alternate.ts","statementMap":{"0":{"start":{"line":58,"column":61},"end":{"line":62,"column":null}},"1":{"start":{"line":64,"column":46},"end":{"line":67,"column":null}},"2":{"start":{"line":73,"column":6},"end":{"line":77,"column":null}},"3":{"start":{"line":74,"column":40},"end":{"line":74,"column":null}},"4":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"5":{"start":{"line":75,"column":29},"end":{"line":75,"column":null}},"6":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"7":{"start":{"line":95,"column":60},"end":{"line":98,"column":null}},"8":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"9":{"start":{"line":113,"column":32},"end":{"line":113,"column":null}},"10":{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},"11":{"start":{"line":141,"column":4},"end":{"line":141,"column":null}},"12":{"start":{"line":143,"column":16},"end":{"line":143,"column":null}},"13":{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},"14":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"15":{"start":{"line":147,"column":48},"end":{"line":147,"column":null}},"16":{"start":{"line":152,"column":26},"end":{"line":152,"column":null}},"17":{"start":{"line":153,"column":15},"end":{"line":153,"column":null}},"18":{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},"19":{"start":{"line":155,"column":4},"end":{"line":155,"column":null}},"20":{"start":{"line":157,"column":21},"end":{"line":157,"column":null}},"21":{"start":{"line":158,"column":24},"end":{"line":160,"column":null}},"22":{"start":{"line":161,"column":21},"end":{"line":164,"column":null}},"23":{"start":{"line":162,"column":19},"end":{"line":162,"column":29}},"24":{"start":{"line":163,"column":16},"end":{"line":163,"column":93}},"25":{"start":{"line":165,"column":15},"end":{"line":165,"column":null}},"26":{"start":{"line":166,"column":2},"end":{"line":166,"column":null}},"27":{"start":{"line":175,"column":18},"end":{"line":175,"column":null}},"28":{"start":{"line":176,"column":24},"end":{"line":176,"column":null}},"29":{"start":{"line":179,"column":4},"end":{"line":183,"column":null}},"30":{"start":{"line":180,"column":6},"end":{"line":180,"column":null}},"31":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"32":{"start":{"line":184,"column":4},"end":{"line":191,"column":null}},"33":{"start":{"line":185,"column":19},"end":{"line":185,"column":null}},"34":{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},"35":{"start":{"line":187,"column":8},"end":{"line":187,"column":null}},"36":{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},"37":{"start":{"line":189,"column":8},"end":{"line":189,"column":null}},"38":{"start":{"line":193,"column":2},"end":{"line":193,"column":null}},"39":{"start":{"line":194,"column":2},"end":{"line":194,"column":null}},"40":{"start":{"line":223,"column":16},"end":{"line":223,"column":null}},"41":{"start":{"line":224,"column":16},"end":{"line":224,"column":null}},"42":{"start":{"line":225,"column":19},"end":{"line":225,"column":null}},"43":{"start":{"line":226,"column":24},"end":{"line":226,"column":null}},"44":{"start":{"line":227,"column":19},"end":{"line":227,"column":null}},"45":{"start":{"line":228,"column":22},"end":{"line":228,"column":null}},"46":{"start":{"line":229,"column":2},"end":{"line":250,"column":null}},"47":{"start":{"line":230,"column":17},"end":{"line":230,"column":null}},"48":{"start":{"line":231,"column":19},"end":{"line":231,"column":null}},"49":{"start":{"line":232,"column":4},"end":{"line":249,"column":null}},"50":{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},"51":{"start":{"line":235,"column":10},"end":{"line":235,"column":null}},"52":{"start":{"line":237,"column":8},"end":{"line":237,"column":null}},"53":{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},"54":{"start":{"line":238,"column":31},"end":{"line":238,"column":null}},"55":{"start":{"line":239,"column":8},"end":{"line":239,"column":null}},"56":{"start":{"line":241,"column":8},"end":{"line":241,"column":null}},"57":{"start":{"line":242,"column":8},"end":{"line":242,"column":null}},"58":{"start":{"line":244,"column":8},"end":{"line":244,"column":null}},"59":{"start":{"line":245,"column":8},"end":{"line":245,"column":null}},"60":{"start":{"line":247,"column":8},"end":{"line":247,"column":null}},"61":{"start":{"line":248,"column":8},"end":{"line":248,"column":null}},"62":{"start":{"line":251,"column":2},"end":{"line":258,"column":null}},"63":{"start":{"line":264,"column":15},"end":{"line":264,"column":null}},"64":{"start":{"line":265,"column":17},"end":{"line":265,"column":null}},"65":{"start":{"line":266,"column":16},"end":{"line":266,"column":null}},"66":{"start":{"line":267,"column":19},"end":{"line":267,"column":null}},"67":{"start":{"line":269,"column":18},"end":{"line":269,"column":null}},"68":{"start":{"line":271,"column":2},"end":{"line":271,"column":null}},"69":{"start":{"line":272,"column":2},"end":{"line":272,"column":null}},"70":{"start":{"line":273,"column":2},"end":{"line":273,"column":null}},"71":{"start":{"line":274,"column":2},"end":{"line":274,"column":null}},"72":{"start":{"line":275,"column":2},"end":{"line":275,"column":null}},"73":{"start":{"line":276,"column":2},"end":{"line":276,"column":null}},"74":{"start":{"line":277,"column":2},"end":{"line":277,"column":null}},"75":{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},"76":{"start":{"line":280,"column":4},"end":{"line":282,"column":null}},"77":{"start":{"line":283,"column":4},"end":{"line":283,"column":null}},"78":{"start":{"line":284,"column":4},"end":{"line":284,"column":null}},"79":{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},"80":{"start":{"line":295,"column":2},"end":{"line":298,"column":null}},"81":{"start":{"line":296,"column":4},"end":{"line":296,"column":null}},"82":{"start":{"line":297,"column":4},"end":{"line":297,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":73,"column":6},"end":{"line":73,"column":69}},"loc":{"start":{"line":73,"column":69},"end":{"line":77,"column":1}},"line":73},"1":{"name":"backfillHtml","decl":{"start":{"line":139,"column":16},"end":{"line":139,"column":29}},"loc":{"start":{"line":139,"column":134},"end":{"line":167,"column":null}},"line":139},"2":{"name":"(anonymous_2)","decl":{"start":{"line":162,"column":5},"end":{"line":162,"column":13}},"loc":{"start":{"line":162,"column":19},"end":{"line":162,"column":29}},"line":162},"3":{"name":"(anonymous_3)","decl":{"start":{"line":163,"column":5},"end":{"line":163,"column":10}},"loc":{"start":{"line":163,"column":16},"end":{"line":163,"column":93}},"line":163},"4":{"name":"listNewsFiles","decl":{"start":{"line":174,"column":22},"end":{"line":174,"column":36}},"loc":{"start":{"line":174,"column":73},"end":{"line":195,"column":null}},"line":174},"5":{"name":"walk","decl":{"start":{"line":177,"column":17},"end":{"line":177,"column":22}},"loc":{"start":{"line":177,"column":50},"end":{"line":192,"column":null}},"line":177},"6":{"name":"runBackfill","decl":{"start":{"line":222,"column":22},"end":{"line":222,"column":34}},"loc":{"start":{"line":222,"column":96},"end":{"line":259,"column":null}},"line":222},"7":{"name":"main","decl":{"start":{"line":263,"column":15},"end":{"line":263,"column":37}},"loc":{"start":{"line":263,"column":37},"end":{"line":286,"column":null}},"line":263},"8":{"name":"(anonymous_8)","decl":{"start":{"line":295,"column":9},"end":{"line":295,"column":16}},"loc":{"start":{"line":295,"column":24},"end":{"line":298,"column":3}},"line":295}},"branchMap":{"0":{"loc":{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":140},"1":{"loc":{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":144},"2":{"loc":{"start":{"line":152,"column":26},"end":{"line":152,"column":null}},"type":"binary-expr","locations":[{"start":{"line":152,"column":26},"end":{"line":152,"column":63}},{"start":{"line":152,"column":63},"end":{"line":152,"column":null}}],"line":152},"3":{"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},{"start":{},"end":{}}],"line":154},"4":{"loc":{"start":{"line":158,"column":24},"end":{"line":160,"column":null}},"type":"cond-expr","locations":[{"start":{"line":159,"column":6},"end":{"line":159,"column":null}},{"start":{"line":160,"column":6},"end":{"line":160,"column":null}}],"line":158},"5":{"loc":{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},{"start":{"line":188,"column":13},"end":{"line":190,"column":null}}],"line":186},"6":{"loc":{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},{"start":{},"end":{}}],"line":188},"7":{"loc":{"start":{"line":188,"column":17},"end":{"line":188,"column":65}},"type":"binary-expr","locations":[{"start":{"line":188,"column":17},"end":{"line":188,"column":35}},{"start":{"line":188,"column":35},"end":{"line":188,"column":65}}],"line":188},"8":{"loc":{"start":{"line":222,"column":52},"end":{"line":222,"column":96}},"type":"default-arg","locations":[{"start":{"line":222,"column":71},"end":{"line":222,"column":96}}],"line":222},"9":{"loc":{"start":{"line":232,"column":4},"end":{"line":249,"column":null}},"type":"switch","locations":[{"start":{"line":233,"column":6},"end":{"line":239,"column":null}},{"start":{"line":240,"column":6},"end":{"line":242,"column":null}},{"start":{"line":243,"column":6},"end":{"line":245,"column":null}},{"start":{"line":246,"column":6},"end":{"line":248,"column":null}}],"line":232},"10":{"loc":{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},"type":"if","locations":[{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},{"start":{},"end":{}}],"line":234},"11":{"loc":{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},"type":"if","locations":[{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},{"start":{},"end":{}}],"line":238},"12":{"loc":{"start":{"line":265,"column":17},"end":{"line":265,"column":null}},"type":"binary-expr","locations":[{"start":{"line":265,"column":17},"end":{"line":265,"column":42}},{"start":{"line":265,"column":42},"end":{"line":265,"column":null}}],"line":265},"13":{"loc":{"start":{"line":273,"column":68},"end":{"line":273,"column":107}},"type":"cond-expr","locations":[{"start":{"line":273,"column":77},"end":{"line":273,"column":103}},{"start":{"line":273,"column":103},"end":{"line":273,"column":107}}],"line":273},"14":{"loc":{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},"type":"if","locations":[{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},{"start":{},"end":{}}],"line":279},"15":{"loc":{"start":{"line":279,"column":6},"end":{"line":279,"column":36}},"type":"binary-expr","locations":[{"start":{"line":279,"column":6},"end":{"line":279,"column":15}},{"start":{"line":279,"column":15},"end":{"line":279,"column":36}}],"line":279},"16":{"loc":{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},"type":"if","locations":[{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},{"start":{},"end":{}}],"line":289},"17":{"loc":{"start":{"line":290,"column":2},"end":{"line":293,"column":null}},"type":"binary-expr","locations":[{"start":{"line":290,"column":2},"end":{"line":290,"column":null}},{"start":{"line":291,"column":2},"end":{"line":291,"column":null}},{"start":{"line":292,"column":2},"end":{"line":292,"column":null}},{"start":{"line":293,"column":2},"end":{"line":293,"column":null}}],"line":290}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":14,"6":1,"7":1,"8":1,"9":1,"10":27,"11":3,"12":24,"13":24,"14":1,"15":23,"16":23,"17":27,"18":27,"19":1,"20":22,"21":22,"22":27,"23":308,"24":286,"25":27,"26":27,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":1,"80":0,"81":0,"82":0},"f":{"0":1,"1":27,"2":308,"3":286,"4":0,"5":0,"6":0,"7":0,"8":0},"b":{"0":[3,24],"1":[1,23],"2":[23,20],"3":[1,26],"4":[3,19],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0],"9":[0,0,0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,1],"17":[1,1,1,1]},"meta":{"lastBranch":18,"lastFunction":9,"lastStatement":83,"seen":{"s:58:61:62:Infinity":0,"s:64:46:67:Infinity":1,"s:73:6:77:Infinity":2,"f:73:6:73:69":0,"s:74:40:74:Infinity":3,"s:75:2:75:Infinity":4,"s:75:29:75:Infinity":5,"s:76:2:76:Infinity":6,"s:95:60:98:Infinity":7,"s:110:2:110:Infinity":8,"s:113:32:113:Infinity":9,"f:139:16:139:29":1,"b:140:2:142:Infinity:undefined:undefined:undefined:undefined":0,"s:140:2:142:Infinity":10,"s:141:4:141:Infinity":11,"s:143:16:143:Infinity":12,"b:144:2:146:Infinity:undefined:undefined:undefined:undefined":1,"s:144:2:146:Infinity":13,"s:145:4:145:Infinity":14,"s:147:48:147:Infinity":15,"s:152:26:152:Infinity":16,"b:152:26:152:63:152:63:152:Infinity":2,"s:153:15:153:Infinity":17,"b:154:2:156:Infinity:undefined:undefined:undefined:undefined":3,"s:154:2:156:Infinity":18,"s:155:4:155:Infinity":19,"s:157:21:157:Infinity":20,"s:158:24:160:Infinity":21,"b:159:6:159:Infinity:160:6:160:Infinity":4,"s:161:21:164:Infinity":22,"f:162:5:162:13":2,"s:162:19:162:29":23,"f:163:5:163:10":3,"s:163:16:163:93":24,"s:165:15:165:Infinity":25,"s:166:2:166:Infinity":26,"f:174:22:174:36":4,"s:175:18:175:Infinity":27,"s:176:24:176:Infinity":28,"f:177:17:177:22":5,"s:179:4:183:Infinity":29,"s:180:6:180:Infinity":30,"s:182:6:182:Infinity":31,"s:184:4:191:Infinity":32,"s:185:19:185:Infinity":33,"b:186:6:190:Infinity:188:13:190:Infinity":5,"s:186:6:190:Infinity":34,"s:187:8:187:Infinity":35,"b:188:13:190:Infinity:undefined:undefined:undefined:undefined":6,"s:188:13:190:Infinity":36,"b:188:17:188:35:188:35:188:65":7,"s:189:8:189:Infinity":37,"s:193:2:193:Infinity":38,"s:194:2:194:Infinity":39,"f:222:22:222:34":6,"b:222:71:222:96":8,"s:223:16:223:Infinity":40,"s:224:16:224:Infinity":41,"s:225:19:225:Infinity":42,"s:226:24:226:Infinity":43,"s:227:19:227:Infinity":44,"s:228:22:228:Infinity":45,"s:229:2:250:Infinity":46,"s:230:17:230:Infinity":47,"s:231:19:231:Infinity":48,"b:233:6:239:Infinity:240:6:242:Infinity:243:6:245:Infinity:246:6:248:Infinity":9,"s:232:4:249:Infinity":49,"b:234:8:236:Infinity:undefined:undefined:undefined:undefined":10,"s:234:8:236:Infinity":50,"s:235:10:235:Infinity":51,"s:237:8:237:Infinity":52,"b:238:8:238:Infinity:undefined:undefined:undefined:undefined":11,"s:238:8:238:Infinity":53,"s:238:31:238:Infinity":54,"s:239:8:239:Infinity":55,"s:241:8:241:Infinity":56,"s:242:8:242:Infinity":57,"s:244:8:244:Infinity":58,"s:245:8:245:Infinity":59,"s:247:8:247:Infinity":60,"s:248:8:248:Infinity":61,"s:251:2:258:Infinity":62,"f:263:15:263:37":7,"s:264:15:264:Infinity":63,"s:265:17:265:Infinity":64,"b:265:17:265:42:265:42:265:Infinity":12,"s:266:16:266:Infinity":65,"s:267:19:267:Infinity":66,"s:269:18:269:Infinity":67,"s:271:2:271:Infinity":68,"s:272:2:272:Infinity":69,"s:273:2:273:Infinity":70,"b:273:77:273:103:273:103:273:107":13,"s:274:2:274:Infinity":71,"s:275:2:275:Infinity":72,"s:276:2:276:Infinity":73,"s:277:2:277:Infinity":74,"b:279:2:285:Infinity:undefined:undefined:undefined:undefined":14,"s:279:2:285:Infinity":75,"b:279:6:279:15:279:15:279:36":15,"s:280:4:282:Infinity":76,"s:283:4:283:Infinity":77,"s:284:4:284:Infinity":78,"b:289:0:299:Infinity:undefined:undefined:undefined:undefined":16,"s:289:0:299:Infinity":79,"b:290:2:290:Infinity:291:2:291:Infinity:292:2:292:Infinity:293:2:293:Infinity":17,"s:295:2:298:Infinity":80,"f:295:9:295:16":8,"s:296:4:296:Infinity":81,"s:297:4:297:Infinity":82}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/calendar-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/calendar-fetch.ts","statementMap":{"0":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":46},"end":{"line":37,"column":null}},"3":{"start":{"line":44,"column":58},"end":{"line":57,"column":null}},"4":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"5":{"start":{"line":46,"column":146},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"7":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"8":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"9":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"10":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"11":{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},"12":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"13":{"start":{"line":63,"column":69},"end":{"line":63,"column":null}},"14":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"15":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"16":{"start":{"line":66,"column":69},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":80,"column":20},"end":{"line":80,"column":null}},"19":{"start":{"line":81,"column":2},"end":{"line":164,"column":null}},"20":{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},"21":{"start":{"line":85,"column":21},"end":{"line":85,"column":null}},"22":{"start":{"line":86,"column":22},"end":{"line":88,"column":null}},"23":{"start":{"line":87,"column":42},"end":{"line":87,"column":71}},"24":{"start":{"line":89,"column":21},"end":{"line":89,"column":null}},"25":{"start":{"line":90,"column":41},"end":{"line":107,"column":null}},"26":{"start":{"line":108,"column":6},"end":{"line":108,"column":null}},"27":{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},"28":{"start":{"line":113,"column":18},"end":{"line":113,"column":null}},"29":{"start":{"line":114,"column":18},"end":{"line":114,"column":null}},"30":{"start":{"line":115,"column":44},"end":{"line":115,"column":null}},"31":{"start":{"line":116,"column":21},"end":{"line":116,"column":null}},"32":{"start":{"line":116,"column":40},"end":{"line":116,"column":72}},"33":{"start":{"line":117,"column":22},"end":{"line":119,"column":null}},"34":{"start":{"line":118,"column":35},"end":{"line":118,"column":64}},"35":{"start":{"line":120,"column":6},"end":{"line":131,"column":null}},"36":{"start":{"line":133,"column":26},"end":{"line":133,"column":null}},"37":{"start":{"line":134,"column":19},"end":{"line":134,"column":null}},"38":{"start":{"line":135,"column":20},"end":{"line":137,"column":null}},"39":{"start":{"line":136,"column":40},"end":{"line":136,"column":69}},"40":{"start":{"line":138,"column":4},"end":{"line":149,"column":null}},"41":{"start":{"line":151,"column":4},"end":{"line":163,"column":null}},"42":{"start":{"line":168,"column":2},"end":{"line":168,"column":null}},"43":{"start":{"line":169,"column":2},"end":{"line":169,"column":null}},"44":{"start":{"line":170,"column":2},"end":{"line":170,"column":null}},"45":{"start":{"line":174,"column":13},"end":{"line":174,"column":null}},"46":{"start":{"line":175,"column":11},"end":{"line":175,"column":null}},"47":{"start":{"line":176,"column":27},"end":{"line":176,"column":null}},"48":{"start":{"line":177,"column":27},"end":{"line":177,"column":null}},"49":{"start":{"line":178,"column":15},"end":{"line":178,"column":null}},"50":{"start":{"line":179,"column":16},"end":{"line":179,"column":null}},"51":{"start":{"line":180,"column":2},"end":{"line":211,"column":null}},"52":{"start":{"line":180,"column":15},"end":{"line":180,"column":18}},"53":{"start":{"line":181,"column":18},"end":{"line":181,"column":null}},"54":{"start":{"line":182,"column":17},"end":{"line":182,"column":null}},"55":{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},"56":{"start":{"line":184,"column":6},"end":{"line":184,"column":null}},"57":{"start":{"line":185,"column":6},"end":{"line":185,"column":null}},"58":{"start":{"line":186,"column":6},"end":{"line":186,"column":null}},"59":{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},"60":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"61":{"start":{"line":190,"column":6},"end":{"line":190,"column":null}},"62":{"start":{"line":191,"column":6},"end":{"line":191,"column":null}},"63":{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},"64":{"start":{"line":194,"column":6},"end":{"line":194,"column":null}},"65":{"start":{"line":195,"column":6},"end":{"line":195,"column":null}},"66":{"start":{"line":196,"column":6},"end":{"line":196,"column":null}},"67":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"68":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"69":{"start":{"line":200,"column":6},"end":{"line":200,"column":null}},"70":{"start":{"line":201,"column":6},"end":{"line":201,"column":null}},"71":{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},"72":{"start":{"line":204,"column":6},"end":{"line":204,"column":null}},"73":{"start":{"line":205,"column":6},"end":{"line":205,"column":null}},"74":{"start":{"line":206,"column":6},"end":{"line":206,"column":null}},"75":{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},"76":{"start":{"line":209,"column":6},"end":{"line":209,"column":null}},"77":{"start":{"line":212,"column":2},"end":{"line":212,"column":null}},"78":{"start":{"line":216,"column":15},"end":{"line":216,"column":null}},"79":{"start":{"line":217,"column":17},"end":{"line":217,"column":null}},"80":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"81":{"start":{"line":219,"column":4},"end":{"line":219,"column":null}},"82":{"start":{"line":221,"column":2},"end":{"line":221,"column":null}},"83":{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},"84":{"start":{"line":225,"column":2},"end":{"line":228,"column":null}},"85":{"start":{"line":226,"column":4},"end":{"line":226,"column":null}},"86":{"start":{"line":227,"column":4},"end":{"line":227,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":44,"column":58},"end":{"line":44,"column":65}},"loc":{"start":{"line":44,"column":78},"end":{"line":57,"column":null}},"line":44},"1":{"name":"matchesScope","decl":{"start":{"line":59,"column":9},"end":{"line":59,"column":22}},"loc":{"start":{"line":59,"column":93},"end":{"line":69,"column":null}},"line":59},"2":{"name":"fetchCalendarStatus","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":null}},"loc":{"start":{"line":79,"column":27},"end":{"line":165,"column":null}},"line":79},"3":{"name":"(anonymous_3)","decl":{"start":{"line":87,"column":24},"end":{"line":87,"column":32}},"loc":{"start":{"line":87,"column":42},"end":{"line":87,"column":71}},"line":87},"4":{"name":"(anonymous_4)","decl":{"start":{"line":116,"column":25},"end":{"line":116,"column":30}},"loc":{"start":{"line":116,"column":40},"end":{"line":116,"column":72}},"line":116},"5":{"name":"(anonymous_5)","decl":{"start":{"line":118,"column":17},"end":{"line":118,"column":25}},"loc":{"start":{"line":118,"column":35},"end":{"line":118,"column":64}},"line":118},"6":{"name":"(anonymous_6)","decl":{"start":{"line":136,"column":22},"end":{"line":136,"column":30}},"loc":{"start":{"line":136,"column":40},"end":{"line":136,"column":69}},"line":136},"7":{"name":"persistCalendarStatus","decl":{"start":{"line":167,"column":16},"end":{"line":167,"column":38}},"loc":{"start":{"line":167,"column":115},"end":{"line":171,"column":null}},"line":167},"8":{"name":"parseArgs","decl":{"start":{"line":173,"column":9},"end":{"line":173,"column":19}},"loc":{"start":{"line":173,"column":148},"end":{"line":213,"column":null}},"line":173},"9":{"name":"main","decl":{"start":{"line":215,"column":15},"end":{"line":215,"column":37}},"loc":{"start":{"line":215,"column":37},"end":{"line":222,"column":null}},"line":215},"10":{"name":"(anonymous_10)","decl":{"start":{"line":225,"column":9},"end":{"line":225,"column":16}},"loc":{"start":{"line":225,"column":35},"end":{"line":228,"column":3}},"line":225}},"branchMap":{"0":{"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"4":{"loc":{"start":{"line":63,"column":8},"end":{"line":63,"column":69}},"type":"binary-expr","locations":[{"start":{"line":63,"column":8},"end":{"line":63,"column":22}},{"start":{"line":63,"column":22},"end":{"line":63,"column":69}}],"line":63},"5":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65},"6":{"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":66},"7":{"loc":{"start":{"line":66,"column":8},"end":{"line":66,"column":69}},"type":"binary-expr","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":22}},{"start":{"line":66,"column":22},"end":{"line":66,"column":69}}],"line":66},"8":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"default-arg","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":null}}],"line":74},"9":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"default-arg","locations":[{"start":{"line":75,"column":23},"end":{"line":75,"column":null}}],"line":75},"10":{"loc":{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},{"start":{},"end":{}}],"line":84},"11":{"loc":{"start":{"line":86,"column":22},"end":{"line":88,"column":null}},"type":"cond-expr","locations":[{"start":{"line":87,"column":10},"end":{"line":87,"column":null}},{"start":{"line":88,"column":10},"end":{"line":88,"column":null}}],"line":86},"12":{"loc":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":22},"end":{"line":86,"column":29}},{"start":{"line":86,"column":29},"end":{"line":86,"column":null}}],"line":86},"13":{"loc":{"start":{"line":98,"column":16},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":25},"end":{"line":98,"column":32}},{"start":{"line":98,"column":32},"end":{"line":98,"column":null}}],"line":98},"14":{"loc":{"start":{"line":101,"column":12},"end":{"line":106,"column":null}},"type":"cond-expr","locations":[{"start":{"line":102,"column":12},"end":{"line":105,"column":null}},{"start":{"line":106,"column":12},"end":{"line":106,"column":null}}],"line":101},"15":{"loc":{"start":{"line":101,"column":12},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":101,"column":12},"end":{"line":101,"column":35}},{"start":{"line":101,"column":35},"end":{"line":101,"column":null}}],"line":101},"16":{"loc":{"start":{"line":103,"column":14},"end":{"line":103,"column":null}},"type":"cond-expr","locations":[{"start":{"line":103,"column":36},"end":{"line":103,"column":72}},{"start":{"line":103,"column":72},"end":{"line":103,"column":null}}],"line":103},"17":{"loc":{"start":{"line":104,"column":14},"end":{"line":104,"column":null}},"type":"cond-expr","locations":[{"start":{"line":104,"column":37},"end":{"line":104,"column":75}},{"start":{"line":104,"column":75},"end":{"line":104,"column":null}}],"line":104},"18":{"loc":{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":112},"19":{"loc":{"start":{"line":117,"column":22},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":10},"end":{"line":118,"column":null}},{"start":{"line":119,"column":10},"end":{"line":119,"column":null}}],"line":117},"20":{"loc":{"start":{"line":117,"column":22},"end":{"line":117,"column":null}},"type":"binary-expr","locations":[{"start":{"line":117,"column":22},"end":{"line":117,"column":29}},{"start":{"line":117,"column":29},"end":{"line":117,"column":null}}],"line":117},"21":{"loc":{"start":{"line":135,"column":20},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":8},"end":{"line":136,"column":null}},{"start":{"line":137,"column":8},"end":{"line":137,"column":null}}],"line":135},"22":{"loc":{"start":{"line":135,"column":20},"end":{"line":135,"column":null}},"type":"binary-expr","locations":[{"start":{"line":135,"column":20},"end":{"line":135,"column":27}},{"start":{"line":135,"column":27},"end":{"line":135,"column":null}}],"line":135},"23":{"loc":{"start":{"line":146,"column":14},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":39},"end":{"line":146,"column":46}},{"start":{"line":146,"column":46},"end":{"line":146,"column":null}}],"line":146},"24":{"loc":{"start":{"line":162,"column":13},"end":{"line":162,"column":null}},"type":"cond-expr","locations":[{"start":{"line":162,"column":38},"end":{"line":162,"column":54}},{"start":{"line":162,"column":54},"end":{"line":162,"column":null}}],"line":162},"25":{"loc":{"start":{"line":167,"column":62},"end":{"line":167,"column":115}},"type":"default-arg","locations":[{"start":{"line":167,"column":75},"end":{"line":167,"column":115}}],"line":167},"26":{"loc":{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":183},"27":{"loc":{"start":{"line":183,"column":8},"end":{"line":183,"column":36}},"type":"binary-expr","locations":[{"start":{"line":183,"column":8},"end":{"line":183,"column":30}},{"start":{"line":183,"column":30},"end":{"line":183,"column":36}}],"line":183},"28":{"loc":{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":188},"29":{"loc":{"start":{"line":188,"column":8},"end":{"line":188,"column":34}},"type":"binary-expr","locations":[{"start":{"line":188,"column":8},"end":{"line":188,"column":28}},{"start":{"line":188,"column":28},"end":{"line":188,"column":34}}],"line":188},"30":{"loc":{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":193},"31":{"loc":{"start":{"line":193,"column":8},"end":{"line":193,"column":35}},"type":"binary-expr","locations":[{"start":{"line":193,"column":8},"end":{"line":193,"column":29}},{"start":{"line":193,"column":29},"end":{"line":193,"column":35}}],"line":193},"32":{"loc":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"type":"if","locations":[{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},{"start":{},"end":{}}],"line":198},"33":{"loc":{"start":{"line":198,"column":8},"end":{"line":198,"column":35}},"type":"binary-expr","locations":[{"start":{"line":198,"column":8},"end":{"line":198,"column":29}},{"start":{"line":198,"column":29},"end":{"line":198,"column":35}}],"line":198},"34":{"loc":{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},{"start":{},"end":{}}],"line":203},"35":{"loc":{"start":{"line":203,"column":8},"end":{"line":203,"column":38}},"type":"binary-expr","locations":[{"start":{"line":203,"column":8},"end":{"line":203,"column":32}},{"start":{"line":203,"column":32},"end":{"line":203,"column":38}}],"line":203},"36":{"loc":{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},"type":"if","locations":[{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},{"start":{},"end":{}}],"line":208},"37":{"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"38":{"loc":{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},"type":"if","locations":[{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},{"start":{},"end":{}}],"line":224},"39":{"loc":{"start":{"line":224,"column":66},"end":{"line":224,"column":87}},"type":"binary-expr","locations":[{"start":{"line":224,"column":66},"end":{"line":224,"column":85}},{"start":{"line":224,"column":85},"end":{"line":224,"column":87}}],"line":224},"40":{"loc":{"start":{"line":226,"column":37},"end":{"line":226,"column":93}},"type":"cond-expr","locations":[{"start":{"line":226,"column":62},"end":{"line":226,"column":78}},{"start":{"line":226,"column":78},"end":{"line":226,"column":93}}],"line":226}},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":4,"12":4,"13":2,"14":2,"15":0,"16":0,"17":2,"18":3,"19":3,"20":3,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":3,"28":3,"29":3,"30":2,"31":2,"32":4,"33":2,"34":4,"35":3,"36":0,"37":0,"38":0,"39":0,"40":3,"41":1,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":1,"84":0,"85":0,"86":0},"f":{"0":0,"1":4,"2":3,"3":0,"4":4,"5":4,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[0,0],"1":[0,0],"2":[4,0],"3":[2,2],"4":[4,3],"5":[0,2],"6":[0,0],"7":[0,0],"8":[3],"9":[3],"10":[0,3],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0],"18":[3,0],"19":[2,0],"20":[2,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[1,0],"25":[0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,0],"35":[0,0],"36":[0,0],"37":[0,0],"38":[0,1],"39":[1,0],"40":[0,0]},"meta":{"lastBranch":41,"lastFunction":11,"lastStatement":87,"seen":{"s:35:18:35:Infinity":0,"s:36:18:36:Infinity":1,"s:37:46:37:Infinity":2,"s:44:58:57:Infinity":3,"f:44:58:44:65":0,"s:45:17:45:Infinity":4,"s:46:146:49:Infinity":5,"b:50:2:52:Infinity:undefined:undefined:undefined:undefined":0,"s:50:2:52:Infinity":6,"s:51:4:51:Infinity":7,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:55:Infinity":8,"s:54:4:54:Infinity":9,"s:56:2:56:Infinity":10,"f:59:9:59:22":1,"b:62:2:64:Infinity:undefined:undefined:undefined:undefined":2,"s:62:2:64:Infinity":11,"b:63:4:63:Infinity:undefined:undefined:undefined:undefined":3,"s:63:4:63:Infinity":12,"b:63:8:63:22:63:22:63:69":4,"s:63:69:63:Infinity":13,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":5,"s:65:2:67:Infinity":14,"b:66:4:66:Infinity:undefined:undefined:undefined:undefined":6,"s:66:4:66:Infinity":15,"b:66:8:66:22:66:22:66:69":7,"s:66:69:66:Infinity":16,"s:68:2:68:Infinity":17,"f:71:22:71:Infinity":2,"b:74:23:74:Infinity":8,"b:75:23:75:Infinity":9,"s:80:20:80:Infinity":18,"s:81:2:164:Infinity":19,"b:84:4:109:Infinity:undefined:undefined:undefined:undefined":10,"s:84:4:109:Infinity":20,"s:85:21:85:Infinity":21,"s:86:22:88:Infinity":22,"b:87:10:87:Infinity:88:10:88:Infinity":11,"b:86:22:86:29:86:29:86:Infinity":12,"f:87:24:87:32":3,"s:87:42:87:71":23,"s:89:21:89:Infinity":24,"s:90:41:107:Infinity":25,"b:98:25:98:32:98:32:98:Infinity":13,"b:102:12:105:Infinity:106:12:106:Infinity":14,"b:101:12:101:35:101:35:101:Infinity":15,"b:103:36:103:72:103:72:103:Infinity":16,"b:104:37:104:75:104:75:104:Infinity":17,"s:108:6:108:Infinity":26,"b:112:4:132:Infinity:undefined:undefined:undefined:undefined":18,"s:112:4:132:Infinity":27,"s:113:18:113:Infinity":28,"s:114:18:114:Infinity":29,"s:115:44:115:Infinity":30,"s:116:21:116:Infinity":31,"f:116:25:116:30":4,"s:116:40:116:72":32,"s:117:22:119:Infinity":33,"b:118:10:118:Infinity:119:10:119:Infinity":19,"b:117:22:117:29:117:29:117:Infinity":20,"f:118:17:118:25":5,"s:118:35:118:64":34,"s:120:6:131:Infinity":35,"s:133:26:133:Infinity":36,"s:134:19:134:Infinity":37,"s:135:20:137:Infinity":38,"b:136:8:136:Infinity:137:8:137:Infinity":21,"b:135:20:135:27:135:27:135:Infinity":22,"f:136:22:136:30":6,"s:136:40:136:69":39,"s:138:4:149:Infinity":40,"b:146:39:146:46:146:46:146:Infinity":23,"s:151:4:163:Infinity":41,"b:162:38:162:54:162:54:162:Infinity":24,"f:167:16:167:38":7,"b:167:75:167:115":25,"s:168:2:168:Infinity":42,"s:169:2:169:Infinity":43,"s:170:2:170:Infinity":44,"f:173:9:173:19":8,"s:174:13:174:Infinity":45,"s:175:11:175:Infinity":46,"s:176:27:176:Infinity":47,"s:177:27:177:Infinity":48,"s:178:15:178:Infinity":49,"s:179:16:179:Infinity":50,"s:180:2:211:Infinity":51,"s:180:15:180:18":52,"s:181:18:181:Infinity":53,"s:182:17:182:Infinity":54,"b:183:4:187:Infinity:undefined:undefined:undefined:undefined":26,"s:183:4:187:Infinity":55,"b:183:8:183:30:183:30:183:36":27,"s:184:6:184:Infinity":56,"s:185:6:185:Infinity":57,"s:186:6:186:Infinity":58,"b:188:4:192:Infinity:undefined:undefined:undefined:undefined":28,"s:188:4:192:Infinity":59,"b:188:8:188:28:188:28:188:34":29,"s:189:6:189:Infinity":60,"s:190:6:190:Infinity":61,"s:191:6:191:Infinity":62,"b:193:4:197:Infinity:undefined:undefined:undefined:undefined":30,"s:193:4:197:Infinity":63,"b:193:8:193:29:193:29:193:35":31,"s:194:6:194:Infinity":64,"s:195:6:195:Infinity":65,"s:196:6:196:Infinity":66,"b:198:4:202:Infinity:undefined:undefined:undefined:undefined":32,"s:198:4:202:Infinity":67,"b:198:8:198:29:198:29:198:35":33,"s:199:6:199:Infinity":68,"s:200:6:200:Infinity":69,"s:201:6:201:Infinity":70,"b:203:4:207:Infinity:undefined:undefined:undefined:undefined":34,"s:203:4:207:Infinity":71,"b:203:8:203:32:203:32:203:38":35,"s:204:6:204:Infinity":72,"s:205:6:205:Infinity":73,"s:206:6:206:Infinity":74,"b:208:4:210:Infinity:undefined:undefined:undefined:undefined":36,"s:208:4:210:Infinity":75,"s:209:6:209:Infinity":76,"s:212:2:212:Infinity":77,"f:215:15:215:37":9,"s:216:15:216:Infinity":78,"s:217:17:217:Infinity":79,"b:218:2:220:Infinity:undefined:undefined:undefined:undefined":37,"s:218:2:220:Infinity":80,"s:219:4:219:Infinity":81,"s:221:2:221:Infinity":82,"b:224:0:229:Infinity:undefined:undefined:undefined:undefined":38,"s:224:0:229:Infinity":83,"b:224:66:224:85:224:85:224:87":39,"s:225:2:228:Infinity":84,"f:225:9:225:16":10,"s:226:4:226:Infinity":85,"b:226:62:226:78:226:78:226:93":40,"s:227:4:227:Infinity":86}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/bake-stats-html.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/bake-stats-html.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":45,"column":63},"end":{"line":71,"column":null}},"2":{"start":{"line":85,"column":16},"end":{"line":85,"column":null}},"3":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"4":{"start":{"line":86,"column":26},"end":{"line":86,"column":null}},"5":{"start":{"line":87,"column":18},"end":{"line":87,"column":null}},"6":{"start":{"line":87,"column":49},"end":{"line":87,"column":57}},"7":{"start":{"line":88,"column":31},"end":{"line":88,"column":null}},"8":{"start":{"line":89,"column":2},"end":{"line":98,"column":null}},"9":{"start":{"line":89,"column":15},"end":{"line":89,"column":18}},"10":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"11":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"12":{"start":{"line":91,"column":14},"end":{"line":91,"column":null}},"13":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"14":{"start":{"line":93,"column":40},"end":{"line":93,"column":null}},"15":{"start":{"line":94,"column":4},"end":{"line":96,"column":null}},"16":{"start":{"line":94,"column":17},"end":{"line":94,"column":20}},"17":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"18":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"19":{"start":{"line":99,"column":2},"end":{"line":99,"column":null}},"20":{"start":{"line":111,"column":15},"end":{"line":111,"column":null}},"21":{"start":{"line":112,"column":43},"end":{"line":112,"column":null}},"22":{"start":{"line":113,"column":2},"end":{"line":118,"column":null}},"23":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"24":{"start":{"line":114,"column":34},"end":{"line":114,"column":null}},"25":{"start":{"line":115,"column":14},"end":{"line":115,"column":null}},"26":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"27":{"start":{"line":116,"column":29},"end":{"line":116,"column":null}},"28":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"29":{"start":{"line":119,"column":38},"end":{"line":119,"column":null}},"30":{"start":{"line":120,"column":2},"end":{"line":125,"column":null}},"31":{"start":{"line":121,"column":18},"end":{"line":121,"column":null}},"32":{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},"33":{"start":{"line":123,"column":6},"end":{"line":123,"column":null}},"34":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"35":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"36":{"start":{"line":146,"column":17},"end":{"line":146,"column":null}},"37":{"start":{"line":147,"column":20},"end":{"line":152,"column":null}},"38":{"start":{"line":148,"column":18},"end":{"line":148,"column":null}},"39":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"40":{"start":{"line":149,"column":29},"end":{"line":149,"column":null}},"41":{"start":{"line":150,"column":4},"end":{"line":150,"column":null}},"42":{"start":{"line":151,"column":4},"end":{"line":151,"column":null}},"43":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"44":{"start":{"line":167,"column":2},"end":{"line":167,"column":null}},"45":{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},"46":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"47":{"start":{"line":177,"column":18},"end":{"line":177,"column":null}},"48":{"start":{"line":178,"column":17},"end":{"line":178,"column":null}},"49":{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},"50":{"start":{"line":180,"column":4},"end":{"line":182,"column":null}},"51":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"52":{"start":{"line":186,"column":18},"end":{"line":186,"column":null}},"53":{"start":{"line":187,"column":56},"end":{"line":187,"column":null}},"54":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"55":{"start":{"line":189,"column":2},"end":{"line":200,"column":null}},"56":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"57":{"start":{"line":190,"column":23},"end":{"line":190,"column":null}},"58":{"start":{"line":191,"column":17},"end":{"line":191,"column":null}},"59":{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},"60":{"start":{"line":192,"column":37},"end":{"line":192,"column":null}},"61":{"start":{"line":193,"column":19},"end":{"line":193,"column":null}},"62":{"start":{"line":194,"column":38},"end":{"line":194,"column":null}},"63":{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},"64":{"start":{"line":196,"column":6},"end":{"line":196,"column":null}},"65":{"start":{"line":198,"column":4},"end":{"line":198,"column":null}},"66":{"start":{"line":199,"column":4},"end":{"line":199,"column":null}},"67":{"start":{"line":201,"column":2},"end":{"line":201,"column":null}},"68":{"start":{"line":206,"column":2},"end":{"line":206,"column":null}},"69":{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},"70":{"start":{"line":208,"column":18},"end":{"line":208,"column":null}},"71":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"72":{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},"73":{"start":{"line":212,"column":4},"end":{"line":212,"column":null}},"74":{"start":{"line":213,"column":4},"end":{"line":213,"column":null}},"75":{"start":{"line":215,"column":35},"end":{"line":215,"column":null}},"76":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"77":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"78":{"start":{"line":219,"column":2},"end":{"line":221,"column":null}},"79":{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},"80":{"start":{"line":223,"column":4},"end":{"line":225,"column":null}},"81":{"start":{"line":226,"column":4},"end":{"line":226,"column":null}}},"fnMap":{"0":{"name":"parseCsv","decl":{"start":{"line":84,"column":9},"end":{"line":84,"column":18}},"loc":{"start":{"line":84,"column":49},"end":{"line":100,"column":null}},"line":84},"1":{"name":"(anonymous_1)","decl":{"start":{"line":87,"column":38},"end":{"line":87,"column":43}},"loc":{"start":{"line":87,"column":49},"end":{"line":87,"column":57}},"line":87},"2":{"name":"buildStatLookup","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":32}},"loc":{"start":{"line":110,"column":73},"end":{"line":127,"column":null}},"line":110},"3":{"name":"bakeHtml","decl":{"start":{"line":137,"column":16},"end":{"line":137,"column":null}},"loc":{"start":{"line":140,"column":38},"end":{"line":154,"column":null}},"line":140},"4":{"name":"(anonymous_4)","decl":{"start":{"line":147,"column":33},"end":{"line":147,"column":42}},"loc":{"start":{"line":147,"column":80},"end":{"line":152,"column":3}},"line":147},"5":{"name":"defaultFilter","decl":{"start":{"line":166,"column":9},"end":{"line":166,"column":23}},"loc":{"start":{"line":166,"column":45},"end":{"line":168,"column":null}},"line":166},"6":{"name":"bakeStatsHtml","decl":{"start":{"line":170,"column":16},"end":{"line":170,"column":30}},"loc":{"start":{"line":173,"column":2},"end":{"line":202,"column":null}},"line":173}},"branchMap":{"0":{"loc":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"1":{"loc":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"2":{"loc":{"start":{"line":95,"column":25},"end":{"line":95,"column":39}},"type":"binary-expr","locations":[{"start":{"line":95,"column":25},"end":{"line":95,"column":37}},{"start":{"line":95,"column":37},"end":{"line":95,"column":39}}],"line":95},"3":{"loc":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"4":{"loc":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":116},"5":{"loc":{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":122},"6":{"loc":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":149},"7":{"loc":{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},"type":"if","locations":[{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},{"start":{},"end":{}}],"line":174},"8":{"loc":{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},{"start":{},"end":{}}],"line":179},"9":{"loc":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":17},"end":{"line":185,"column":32}},{"start":{"line":185,"column":32},"end":{"line":185,"column":null}}],"line":185},"10":{"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},{"start":{},"end":{}}],"line":190},"11":{"loc":{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":192},"12":{"loc":{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":195},"13":{"loc":{"start":{"line":195,"column":8},"end":{"line":195,"column":42}},"type":"binary-expr","locations":[{"start":{"line":195,"column":8},"end":{"line":195,"column":24}},{"start":{"line":195,"column":24},"end":{"line":195,"column":42}}],"line":195},"14":{"loc":{"start":{"line":206,"column":2},"end":{"line":206,"column":null}},"type":"binary-expr","locations":[{"start":{"line":206,"column":2},"end":{"line":206,"column":21}},{"start":{"line":206,"column":21},"end":{"line":206,"column":null}}],"line":206},"15":{"loc":{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},{"start":{},"end":{}}],"line":207},"16":{"loc":{"start":{"line":208,"column":18},"end":{"line":208,"column":null}},"type":"binary-expr","locations":[{"start":{"line":208,"column":18},"end":{"line":208,"column":37}},{"start":{"line":208,"column":37},"end":{"line":208,"column":null}}],"line":208},"17":{"loc":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"type":"binary-expr","locations":[{"start":{"line":210,"column":4},"end":{"line":210,"column":23}},{"start":{"line":210,"column":23},"end":{"line":210,"column":null}}],"line":210},"18":{"loc":{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":211},"19":{"loc":{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},{"start":{},"end":{}}],"line":222}},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":1,"6":6,"7":1,"8":1,"9":1,"10":7,"11":7,"12":0,"13":7,"14":7,"15":7,"16":7,"17":42,"18":7,"19":1,"20":1,"21":1,"22":1,"23":7,"24":1,"25":6,"26":6,"27":0,"28":6,"29":1,"30":1,"31":21,"32":21,"33":6,"34":1,"35":3,"36":3,"37":3,"38":5,"39":5,"40":2,"41":3,"42":3,"43":3,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":1,"69":1,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0},"f":{"0":1,"1":6,"2":1,"3":3,"4":5,"5":0,"6":0},"b":{"0":[0,1],"1":[0,7],"2":[42,0],"3":[1,6],"4":[0,6],"5":[6,15],"6":[2,3],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[1,1],"15":[0,1],"16":[0,0],"17":[0,0],"18":[0,0],"19":[0,0]},"meta":{"lastBranch":20,"lastFunction":7,"lastStatement":82,"seen":{"s:38:19:38:Infinity":0,"s:45:63:71:Infinity":1,"f:84:9:84:18":0,"s:85:16:85:Infinity":2,"b:86:2:86:Infinity:undefined:undefined:undefined:undefined":0,"s:86:2:86:Infinity":3,"s:86:26:86:Infinity":4,"s:87:18:87:Infinity":5,"f:87:38:87:43":1,"s:87:49:87:57":6,"s:88:31:88:Infinity":7,"s:89:2:98:Infinity":8,"s:89:15:89:18":9,"s:90:16:90:Infinity":10,"b:91:4:91:Infinity:undefined:undefined:undefined:undefined":1,"s:91:4:91:Infinity":11,"s:91:14:91:Infinity":12,"s:92:18:92:Infinity":13,"s:93:40:93:Infinity":14,"s:94:4:96:Infinity":15,"s:94:17:94:20":16,"s:95:6:95:Infinity":17,"b:95:25:95:37:95:37:95:39":2,"s:97:4:97:Infinity":18,"s:99:2:99:Infinity":19,"f:110:16:110:32":2,"s:111:15:111:Infinity":20,"s:112:43:112:Infinity":21,"s:113:2:118:Infinity":22,"b:114:4:114:Infinity:undefined:undefined:undefined:undefined":3,"s:114:4:114:Infinity":23,"s:114:34:114:Infinity":24,"s:115:14:115:Infinity":25,"b:116:4:116:Infinity:undefined:undefined:undefined:undefined":4,"s:116:4:116:Infinity":26,"s:116:29:116:Infinity":27,"s:117:4:117:Infinity":28,"s:119:38:119:Infinity":29,"s:120:2:125:Infinity":30,"s:121:18:121:Infinity":31,"b:122:4:124:Infinity:undefined:undefined:undefined:undefined":5,"s:122:4:124:Infinity":32,"s:123:6:123:Infinity":33,"s:126:2:126:Infinity":34,"f:137:16:137:Infinity":3,"s:145:4:145:Infinity":35,"s:146:17:146:Infinity":36,"s:147:20:152:Infinity":37,"f:147:33:147:42":4,"s:148:18:148:Infinity":38,"b:149:4:149:Infinity:undefined:undefined:undefined:undefined":6,"s:149:4:149:Infinity":39,"s:149:29:149:Infinity":40,"s:150:4:150:Infinity":41,"s:151:4:151:Infinity":42,"s:153:2:153:Infinity":43,"f:166:9:166:23":5,"s:167:2:167:Infinity":44,"f:170:16:170:30":6,"b:174:2:176:Infinity:undefined:undefined:undefined:undefined":7,"s:174:2:176:Infinity":45,"s:175:4:175:Infinity":46,"s:177:18:177:Infinity":47,"s:178:17:178:Infinity":48,"b:179:2:183:Infinity:undefined:undefined:undefined:undefined":8,"s:179:2:183:Infinity":49,"s:180:4:182:Infinity":50,"s:185:17:185:Infinity":51,"b:185:17:185:32:185:32:185:Infinity":9,"s:186:18:186:Infinity":52,"s:187:56:187:Infinity":53,"s:188:22:188:Infinity":54,"s:189:2:200:Infinity":55,"b:190:4:190:Infinity:undefined:undefined:undefined:undefined":10,"s:190:4:190:Infinity":56,"s:190:23:190:Infinity":57,"s:191:17:191:Infinity":58,"b:192:4:192:Infinity:undefined:undefined:undefined:undefined":11,"s:192:4:192:Infinity":59,"s:192:37:192:Infinity":60,"s:193:19:193:Infinity":61,"s:194:38:194:Infinity":62,"b:195:4:197:Infinity:undefined:undefined:undefined:undefined":12,"s:195:4:197:Infinity":63,"b:195:8:195:24:195:24:195:42":13,"s:196:6:196:Infinity":64,"s:198:4:198:Infinity":65,"s:199:4:199:Infinity":66,"s:201:2:201:Infinity":67,"s:206:2:206:Infinity":68,"b:206:2:206:21:206:21:206:Infinity":14,"b:207:0:228:Infinity:undefined:undefined:undefined:undefined":15,"s:207:0:228:Infinity":69,"s:208:18:208:Infinity":70,"b:208:18:208:37:208:37:208:Infinity":16,"s:210:4:210:Infinity":71,"b:210:4:210:23:210:23:210:Infinity":17,"b:211:2:214:Infinity:undefined:undefined:undefined:undefined":18,"s:211:2:214:Infinity":72,"s:212:4:212:Infinity":73,"s:213:4:213:Infinity":74,"s:215:35:215:Infinity":75,"s:216:2:218:Infinity":76,"s:217:4:217:Infinity":77,"s:219:2:221:Infinity":78,"b:222:2:227:Infinity:undefined:undefined:undefined:undefined":19,"s:222:2:227:Infinity":79,"s:223:4:225:Infinity":80,"s:226:4:226:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-analysis-language.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-analysis-language.ts","statementMap":{"0":{"start":{"line":20,"column":24},"end":{"line":34,"column":null}},"1":{"start":{"line":37,"column":34},"end":{"line":37,"column":null}},"2":{"start":{"line":40,"column":28},"end":{"line":40,"column":null}},"3":{"start":{"line":57,"column":13},"end":{"line":57,"column":null}},"4":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"5":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"6":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"7":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"8":{"start":{"line":79,"column":2},"end":{"line":82,"column":null}},"9":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"10":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"11":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"12":{"start":{"line":93,"column":36},"end":{"line":93,"column":51}},"13":{"start":{"line":105,"column":18},"end":{"line":105,"column":null}},"14":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"15":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"16":{"start":{"line":109,"column":21},"end":{"line":109,"column":null}},"17":{"start":{"line":110,"column":29},"end":{"line":110,"column":null}},"18":{"start":{"line":110,"column":47},"end":{"line":110,"column":69}},"19":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"20":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"21":{"start":{"line":127,"column":26},"end":{"line":127,"column":null}},"22":{"start":{"line":130,"column":20},"end":{"line":130,"column":null}},"23":{"start":{"line":132,"column":4},"end":{"line":154,"column":null}},"24":{"start":{"line":133,"column":23},"end":{"line":133,"column":null}},"25":{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},"26":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"27":{"start":{"line":137,"column":66},"end":{"line":137,"column":null}},"28":{"start":{"line":138,"column":8},"end":{"line":138,"column":null}},"29":{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},"30":{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},"31":{"start":{"line":141,"column":63},"end":{"line":141,"column":null}},"32":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"33":{"start":{"line":144,"column":56},"end":{"line":144,"column":null}},"34":{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},"35":{"start":{"line":147,"column":56},"end":{"line":147,"column":null}},"36":{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},"37":{"start":{"line":150,"column":40},"end":{"line":150,"column":null}},"38":{"start":{"line":152,"column":8},"end":{"line":152,"column":null}},"39":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"40":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"41":{"start":{"line":174,"column":42},"end":{"line":174,"column":null}},"42":{"start":{"line":175,"column":16},"end":{"line":175,"column":null}},"43":{"start":{"line":177,"column":2},"end":{"line":190,"column":null}},"44":{"start":{"line":178,"column":56},"end":{"line":178,"column":null}},"45":{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},"46":{"start":{"line":182,"column":6},"end":{"line":188,"column":null}},"47":{"start":{"line":192,"column":2},"end":{"line":192,"column":null}},"48":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},"49":{"start":{"line":199,"column":31},"end":{"line":199,"column":null}},"50":{"start":{"line":201,"column":17},"end":{"line":201,"column":null}},"51":{"start":{"line":202,"column":20},"end":{"line":202,"column":null}},"52":{"start":{"line":203,"column":15},"end":{"line":205,"column":null}},"53":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"54":{"start":{"line":207,"column":2},"end":{"line":207,"column":null}},"55":{"start":{"line":223,"column":15},"end":{"line":223,"column":null}},"56":{"start":{"line":224,"column":22},"end":{"line":224,"column":null}},"57":{"start":{"line":227,"column":2},"end":{"line":236,"column":null}},"58":{"start":{"line":228,"column":18},"end":{"line":228,"column":null}},"59":{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},"60":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"61":{"start":{"line":231,"column":6},"end":{"line":231,"column":null}},"62":{"start":{"line":234,"column":4},"end":{"line":234,"column":null}},"63":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"64":{"start":{"line":238,"column":21},"end":{"line":238,"column":null}},"65":{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},"66":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"67":{"start":{"line":242,"column":4},"end":{"line":242,"column":null}},"68":{"start":{"line":243,"column":4},"end":{"line":243,"column":null}},"69":{"start":{"line":247,"column":21},"end":{"line":247,"column":null}},"70":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"71":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"72":{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},"73":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}}},"fnMap":{"0":{"name":"stripMarkdownCodeAndFrontmatter","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":48}},"loc":{"start":{"line":56,"column":73},"end":{"line":85,"column":null}},"line":56},"1":{"name":"tokenizeWords","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":30}},"loc":{"start":{"line":91,"column":54},"end":{"line":94,"column":null}},"line":91},"2":{"name":"(anonymous_2)","decl":{"start":{"line":93,"column":27},"end":{"line":93,"column":31}},"loc":{"start":{"line":93,"column":36},"end":{"line":93,"column":51}},"line":93},"3":{"name":"calculateSwedishDensity","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":40}},"loc":{"start":{"line":104,"column":2},"end":{"line":114,"column":null}},"line":104},"4":{"name":"(anonymous_4)","decl":{"start":{"line":110,"column":35},"end":{"line":110,"column":42}},"loc":{"start":{"line":110,"column":47},"end":{"line":110,"column":69}},"line":110},"5":{"name":"findAnalysisMarkdownFiles","decl":{"start":{"line":126,"column":16},"end":{"line":126,"column":42}},"loc":{"start":{"line":126,"column":65},"end":{"line":159,"column":null}},"line":126},"6":{"name":"walk","decl":{"start":{"line":129,"column":11},"end":{"line":129,"column":16}},"loc":{"start":{"line":129,"column":36},"end":{"line":155,"column":null}},"line":129},"7":{"name":"validateAnalysisLanguage","decl":{"start":{"line":173,"column":16},"end":{"line":173,"column":41}},"loc":{"start":{"line":173,"column":83},"end":{"line":193,"column":null}},"line":173},"8":{"name":"formatViolationTable","decl":{"start":{"line":198,"column":16},"end":{"line":198,"column":37}},"loc":{"start":{"line":198,"column":78},"end":{"line":208,"column":null}},"line":198},"9":{"name":"(anonymous_9)","decl":{"start":{"line":203,"column":26},"end":{"line":203,"column":30}},"loc":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"line":204},"10":{"name":"main","decl":{"start":{"line":222,"column":22},"end":{"line":222,"column":29}},"loc":{"start":{"line":222,"column":29},"end":{"line":250,"column":null}},"line":222}},"branchMap":{"0":{"loc":{"start":{"line":93,"column":9},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":19},"end":{"line":93,"column":55}},{"start":{"line":93,"column":55},"end":{"line":93,"column":null}}],"line":93},"1":{"loc":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":35},"end":{"line":111,"column":69}},{"start":{"line":111,"column":69},"end":{"line":111,"column":null}}],"line":111},"2":{"loc":{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},{"start":{"line":139,"column":13},"end":{"line":153,"column":null}}],"line":135},"3":{"loc":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":137},"4":{"loc":{"start":{"line":137,"column":12},"end":{"line":137,"column":66}},"type":"binary-expr","locations":[{"start":{"line":137,"column":12},"end":{"line":137,"column":38}},{"start":{"line":137,"column":38},"end":{"line":137,"column":66}}],"line":137},"5":{"loc":{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},{"start":{},"end":{}}],"line":139},"6":{"loc":{"start":{"line":139,"column":17},"end":{"line":139,"column":63}},"type":"binary-expr","locations":[{"start":{"line":139,"column":17},"end":{"line":139,"column":35}},{"start":{"line":139,"column":35},"end":{"line":139,"column":63}}],"line":139},"7":{"loc":{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"8":{"loc":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},{"start":{},"end":{}}],"line":144},"9":{"loc":{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":147},"10":{"loc":{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},{"start":{},"end":{}}],"line":150},"11":{"loc":{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},{"start":{},"end":{}}],"line":181},"12":{"loc":{"start":{"line":181,"column":8},"end":{"line":181,"column":90}},"type":"binary-expr","locations":[{"start":{"line":181,"column":8},"end":{"line":181,"column":47}},{"start":{"line":181,"column":47},"end":{"line":181,"column":90}}],"line":181},"13":{"loc":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},"type":"if","locations":[{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},{"start":{},"end":{}}],"line":199},"14":{"loc":{"start":{"line":224,"column":22},"end":{"line":224,"column":null}},"type":"cond-expr","locations":[{"start":{"line":224,"column":61},"end":{"line":224,"column":71}},{"start":{"line":224,"column":71},"end":{"line":224,"column":null}}],"line":224},"15":{"loc":{"start":{"line":224,"column":22},"end":{"line":224,"column":61}},"type":"binary-expr","locations":[{"start":{"line":224,"column":22},"end":{"line":224,"column":33}},{"start":{"line":224,"column":33},"end":{"line":224,"column":61}}],"line":224},"16":{"loc":{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},"type":"if","locations":[{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},{"start":{},"end":{}}],"line":229},"17":{"loc":{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":240},"18":{"loc":{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},"type":"if","locations":[{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},{"start":{},"end":{}}],"line":253}},"s":{"0":3,"1":3,"2":3,"3":1205,"4":1205,"5":1205,"6":1205,"7":1205,"8":1205,"9":1205,"10":1204,"11":1204,"12":45361,"13":11,"14":11,"15":11,"16":11,"17":11,"18":214,"19":11,"20":11,"21":12,"22":12,"23":12,"24":20,"25":20,"26":2,"27":2,"28":0,"29":18,"30":18,"31":3,"32":15,"33":0,"34":15,"35":1,"36":14,"37":0,"38":14,"39":12,"40":12,"41":7,"42":7,"43":7,"44":8,"45":8,"46":2,"47":7,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":3,"73":0},"f":{"0":1205,"1":1204,"2":45361,"3":11,"4":214,"5":12,"6":12,"7":7,"8":0,"9":0,"10":0},"b":{"0":[1202,2],"1":[10,1],"2":[2,18],"3":[2,0],"4":[2,1],"5":[18,0],"6":[18,18],"7":[3,15],"8":[0,15],"9":[1,14],"10":[0,14],"11":[2,6],"12":[8,3],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0],"18":[0,3]},"meta":{"lastBranch":19,"lastFunction":11,"lastStatement":74,"seen":{"s:20:24:34:Infinity":0,"s:37:34:37:Infinity":1,"s:40:28:40:Infinity":2,"f:56:16:56:48":0,"s:57:13:57:Infinity":3,"s:63:2:63:Infinity":4,"s:66:2:66:Infinity":5,"s:69:2:69:Infinity":6,"s:73:2:73:Infinity":7,"s:79:2:82:Infinity":8,"s:84:2:84:Infinity":9,"f:91:16:91:30":1,"s:92:18:92:Infinity":10,"s:93:2:93:Infinity":11,"b:93:19:93:55:93:55:93:Infinity":0,"f:93:27:93:31":2,"s:93:36:93:51":12,"f:100:16:100:40":3,"s:105:18:105:Infinity":13,"s:106:16:106:Infinity":14,"s:107:16:107:Infinity":15,"s:109:21:109:Infinity":16,"s:110:29:110:Infinity":17,"f:110:35:110:42":4,"s:110:47:110:69":18,"s:111:18:111:Infinity":19,"b:111:35:111:69:111:69:111:Infinity":1,"s:113:2:113:Infinity":20,"f:126:16:126:42":5,"s:127:26:127:Infinity":21,"f:129:11:129:16":6,"s:130:20:130:Infinity":22,"s:132:4:154:Infinity":23,"s:133:23:133:Infinity":24,"b:135:6:153:Infinity:139:13:153:Infinity":2,"s:135:6:153:Infinity":25,"b:137:8:137:Infinity:undefined:undefined:undefined:undefined":3,"s:137:8:137:Infinity":26,"b:137:12:137:38:137:38:137:66":4,"s:137:66:137:Infinity":27,"s:138:8:138:Infinity":28,"b:139:13:153:Infinity:undefined:undefined:undefined:undefined":5,"s:139:13:153:Infinity":29,"b:139:17:139:35:139:35:139:63":6,"b:141:8:141:Infinity:undefined:undefined:undefined:undefined":7,"s:141:8:141:Infinity":30,"s:141:63:141:Infinity":31,"b:144:8:144:Infinity:undefined:undefined:undefined:undefined":8,"s:144:8:144:Infinity":32,"s:144:56:144:Infinity":33,"b:147:8:147:Infinity:undefined:undefined:undefined:undefined":9,"s:147:8:147:Infinity":34,"s:147:56:147:Infinity":35,"b:150:8:150:Infinity:undefined:undefined:undefined:undefined":10,"s:150:8:150:Infinity":36,"s:150:40:150:Infinity":37,"s:152:8:152:Infinity":38,"s:157:2:157:Infinity":39,"s:158:2:158:Infinity":40,"f:173:16:173:41":7,"s:174:42:174:Infinity":41,"s:175:16:175:Infinity":42,"s:177:2:190:Infinity":43,"s:178:56:178:Infinity":44,"b:181:4:189:Infinity:undefined:undefined:undefined:undefined":11,"s:181:4:189:Infinity":45,"b:181:8:181:47:181:47:181:90":12,"s:182:6:188:Infinity":46,"s:192:2:192:Infinity":47,"f:198:16:198:37":8,"b:199:2:199:Infinity:undefined:undefined:undefined:undefined":13,"s:199:2:199:Infinity":48,"s:199:31:199:Infinity":49,"s:201:17:201:Infinity":50,"s:202:20:202:Infinity":51,"s:203:15:205:Infinity":52,"f:203:26:203:30":9,"s:204:4:204:Infinity":53,"s:207:2:207:Infinity":54,"f:222:22:222:29":10,"s:223:15:223:Infinity":55,"s:224:22:224:Infinity":56,"b:224:61:224:71:224:71:224:Infinity":14,"b:224:22:224:33:224:33:224:61":15,"s:227:2:236:Infinity":57,"s:228:18:228:Infinity":58,"b:229:4:232:Infinity:undefined:undefined:undefined:undefined":16,"s:229:4:232:Infinity":59,"s:230:6:230:Infinity":60,"s:231:6:231:Infinity":61,"s:234:4:234:Infinity":62,"s:235:4:235:Infinity":63,"s:238:21:238:Infinity":64,"b:240:2:244:Infinity:undefined:undefined:undefined:undefined":17,"s:240:2:244:Infinity":65,"s:241:4:241:Infinity":66,"s:242:4:242:Infinity":67,"s:243:4:243:Infinity":68,"s:247:21:247:Infinity":69,"s:248:2:248:Infinity":70,"s:249:2:249:Infinity":71,"b:253:0:255:Infinity:undefined:undefined:undefined:undefined":18,"s:253:0:255:Infinity":72,"s:254:2:254:Infinity":73}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-brief-language.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-brief-language.ts","statementMap":{"0":{"start":{"line":62,"column":52},"end":{"line":79,"column":null}},"1":{"start":{"line":100,"column":41},"end":{"line":100,"column":null}},"2":{"start":{"line":101,"column":45},"end":{"line":101,"column":null}},"3":{"start":{"line":102,"column":45},"end":{"line":102,"column":null}},"4":{"start":{"line":105,"column":35},"end":{"line":105,"column":null}},"5":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"6":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"7":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"8":{"start":{"line":119,"column":27},"end":{"line":119,"column":null}},"9":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"10":{"start":{"line":120,"column":27},"end":{"line":120,"column":null}},"11":{"start":{"line":121,"column":2},"end":{"line":121,"column":null}},"12":{"start":{"line":141,"column":16},"end":{"line":141,"column":null}},"13":{"start":{"line":142,"column":16},"end":{"line":142,"column":null}},"14":{"start":{"line":143,"column":21},"end":{"line":143,"column":null}},"15":{"start":{"line":144,"column":29},"end":{"line":144,"column":null}},"16":{"start":{"line":144,"column":49},"end":{"line":144,"column":71}},"17":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"18":{"start":{"line":146,"column":2},"end":{"line":146,"column":null}},"19":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"20":{"start":{"line":154,"column":56},"end":{"line":154,"column":null}},"21":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"22":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"23":{"start":{"line":172,"column":22},"end":{"line":172,"column":null}},"24":{"start":{"line":181,"column":27},"end":{"line":181,"column":null}},"25":{"start":{"line":184,"column":4},"end":{"line":188,"column":null}},"26":{"start":{"line":185,"column":6},"end":{"line":185,"column":null}},"27":{"start":{"line":187,"column":6},"end":{"line":187,"column":null}},"28":{"start":{"line":189,"column":4},"end":{"line":198,"column":null}},"29":{"start":{"line":190,"column":23},"end":{"line":190,"column":null}},"30":{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},"31":{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},"32":{"start":{"line":192,"column":66},"end":{"line":192,"column":null}},"33":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"34":{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},"35":{"start":{"line":195,"column":18},"end":{"line":195,"column":null}},"36":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"37":{"start":{"line":196,"column":32},"end":{"line":196,"column":null}},"38":{"start":{"line":200,"column":2},"end":{"line":200,"column":null}},"39":{"start":{"line":201,"column":2},"end":{"line":201,"column":null}},"40":{"start":{"line":219,"column":47},"end":{"line":219,"column":null}},"41":{"start":{"line":220,"column":17},"end":{"line":220,"column":null}},"42":{"start":{"line":222,"column":2},"end":{"line":240,"column":null}},"43":{"start":{"line":224,"column":4},"end":{"line":228,"column":null}},"44":{"start":{"line":225,"column":6},"end":{"line":225,"column":null}},"45":{"start":{"line":227,"column":6},"end":{"line":227,"column":null}},"46":{"start":{"line":229,"column":20},"end":{"line":229,"column":null}},"47":{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},"48":{"start":{"line":231,"column":6},"end":{"line":238,"column":null}},"49":{"start":{"line":241,"column":2},"end":{"line":241,"column":null}},"50":{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},"51":{"start":{"line":245,"column":31},"end":{"line":245,"column":null}},"52":{"start":{"line":246,"column":26},"end":{"line":246,"column":null}},"53":{"start":{"line":247,"column":2},"end":{"line":254,"column":null}},"54":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"55":{"start":{"line":249,"column":4},"end":{"line":252,"column":null}},"56":{"start":{"line":253,"column":4},"end":{"line":253,"column":null}},"57":{"start":{"line":255,"column":2},"end":{"line":255,"column":null}},"58":{"start":{"line":275,"column":15},"end":{"line":275,"column":null}},"59":{"start":{"line":276,"column":22},"end":{"line":276,"column":null}},"60":{"start":{"line":278,"column":2},"end":{"line":287,"column":null}},"61":{"start":{"line":279,"column":18},"end":{"line":279,"column":null}},"62":{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},"63":{"start":{"line":281,"column":6},"end":{"line":281,"column":null}},"64":{"start":{"line":282,"column":6},"end":{"line":282,"column":null}},"65":{"start":{"line":285,"column":4},"end":{"line":285,"column":null}},"66":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"67":{"start":{"line":289,"column":21},"end":{"line":289,"column":null}},"68":{"start":{"line":290,"column":23},"end":{"line":290,"column":null}},"69":{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},"70":{"start":{"line":293,"column":4},"end":{"line":295,"column":null}},"71":{"start":{"line":296,"column":4},"end":{"line":296,"column":null}},"72":{"start":{"line":297,"column":4},"end":{"line":302,"column":null}},"73":{"start":{"line":303,"column":4},"end":{"line":303,"column":null}},"74":{"start":{"line":306,"column":2},"end":{"line":308,"column":null}},"75":{"start":{"line":309,"column":2},"end":{"line":309,"column":null}},"76":{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},"77":{"start":{"line":314,"column":2},"end":{"line":314,"column":null}}},"fnMap":{"0":{"name":"thresholdForLanguage","decl":{"start":{"line":118,"column":16},"end":{"line":118,"column":37}},"loc":{"start":{"line":118,"column":59},"end":{"line":122,"column":null}},"line":118},"1":{"name":"calculateEnglishDensity","decl":{"start":{"line":140,"column":16},"end":{"line":140,"column":40}},"loc":{"start":{"line":140,"column":74},"end":{"line":147,"column":null}},"line":140},"2":{"name":"(anonymous_2)","decl":{"start":{"line":144,"column":35},"end":{"line":144,"column":43}},"loc":{"start":{"line":144,"column":49},"end":{"line":144,"column":71}},"line":144},"3":{"name":"exceedsEnglishThreshold","decl":{"start":{"line":153,"column":16},"end":{"line":153,"column":40}},"loc":{"start":{"line":153,"column":88},"end":{"line":157,"column":null}},"line":153},"4":{"name":"findTranslatedBriefs","decl":{"start":{"line":180,"column":16},"end":{"line":180,"column":37}},"loc":{"start":{"line":180,"column":63},"end":{"line":202,"column":null}},"line":180},"5":{"name":"walk","decl":{"start":{"line":182,"column":11},"end":{"line":182,"column":16}},"loc":{"start":{"line":182,"column":42},"end":{"line":199,"column":null}},"line":182},"6":{"name":"validateBriefLanguages","decl":{"start":{"line":218,"column":16},"end":{"line":218,"column":39}},"loc":{"start":{"line":218,"column":86},"end":{"line":242,"column":null}},"line":218},"7":{"name":"formatViolationReport","decl":{"start":{"line":244,"column":16},"end":{"line":244,"column":38}},"loc":{"start":{"line":244,"column":93},"end":{"line":256,"column":null}},"line":244},"8":{"name":"main","decl":{"start":{"line":274,"column":22},"end":{"line":274,"column":44}},"loc":{"start":{"line":274,"column":44},"end":{"line":310,"column":null}},"line":274}},"branchMap":{"0":{"loc":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},{"start":{},"end":{}}],"line":119},"1":{"loc":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":120},"2":{"loc":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":35},"end":{"line":145,"column":69}},{"start":{"line":145,"column":69},"end":{"line":145,"column":null}}],"line":145},"3":{"loc":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":154},"4":{"loc":{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},{"start":{"line":194,"column":13},"end":{"line":197,"column":null}}],"line":191},"5":{"loc":{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":192},"6":{"loc":{"start":{"line":192,"column":12},"end":{"line":192,"column":66}},"type":"binary-expr","locations":[{"start":{"line":192,"column":12},"end":{"line":192,"column":38}},{"start":{"line":192,"column":38},"end":{"line":192,"column":66}}],"line":192},"7":{"loc":{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":194},"8":{"loc":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":196},"9":{"loc":{"start":{"line":196,"column":12},"end":{"line":196,"column":32}},"type":"binary-expr","locations":[{"start":{"line":196,"column":12},"end":{"line":196,"column":17}},{"start":{"line":196,"column":17},"end":{"line":196,"column":32}}],"line":196},"10":{"loc":{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},"type":"if","locations":[{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},{"start":{},"end":{}}],"line":230},"11":{"loc":{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},"type":"if","locations":[{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},{"start":{},"end":{}}],"line":245},"12":{"loc":{"start":{"line":276,"column":22},"end":{"line":276,"column":null}},"type":"cond-expr","locations":[{"start":{"line":276,"column":61},"end":{"line":276,"column":71}},{"start":{"line":276,"column":71},"end":{"line":276,"column":null}}],"line":276},"13":{"loc":{"start":{"line":276,"column":22},"end":{"line":276,"column":61}},"type":"binary-expr","locations":[{"start":{"line":276,"column":22},"end":{"line":276,"column":33}},{"start":{"line":276,"column":33},"end":{"line":276,"column":61}}],"line":276},"14":{"loc":{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},{"start":{},"end":{}}],"line":280},"15":{"loc":{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},"type":"if","locations":[{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},{"start":{},"end":{}}],"line":292},"16":{"loc":{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":313}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":14,"8":3,"9":11,"10":11,"11":8,"12":1190,"13":1190,"14":1190,"15":1190,"16":45140,"17":1190,"18":1190,"19":16,"20":2,"21":14,"22":14,"23":2,"24":5,"25":15,"26":15,"27":0,"28":15,"29":21,"30":21,"31":12,"32":2,"33":10,"34":9,"35":9,"36":9,"37":6,"38":5,"39":5,"40":3,"41":3,"42":3,"43":3,"44":3,"45":0,"46":3,"47":3,"48":2,"49":3,"50":2,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":2,"77":0},"f":{"0":14,"1":1190,"2":45140,"3":16,"4":5,"5":15,"6":3,"7":2,"8":0},"b":{"0":[3,11],"1":[3,8],"2":[1190,0],"3":[2,14],"4":[12,9],"5":[2,10],"6":[12,11],"7":[9,0],"8":[6,3],"9":[9,7],"10":[2,1],"11":[1,1],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,2]},"meta":{"lastBranch":17,"lastFunction":9,"lastStatement":78,"seen":{"s:62:52:79:Infinity":0,"s:100:41:100:Infinity":1,"s:101:45:101:Infinity":2,"s:102:45:102:Infinity":3,"s:105:35:105:Infinity":4,"s:108:18:108:Infinity":5,"s:111:18:111:Infinity":6,"f:118:16:118:37":0,"b:119:2:119:Infinity:undefined:undefined:undefined:undefined":0,"s:119:2:119:Infinity":7,"s:119:27:119:Infinity":8,"b:120:2:120:Infinity:undefined:undefined:undefined:undefined":1,"s:120:2:120:Infinity":9,"s:120:27:120:Infinity":10,"s:121:2:121:Infinity":11,"f:140:16:140:40":1,"s:141:16:141:Infinity":12,"s:142:16:142:Infinity":13,"s:143:21:143:Infinity":14,"s:144:29:144:Infinity":15,"f:144:35:144:43":2,"s:144:49:144:71":16,"s:145:18:145:Infinity":17,"b:145:35:145:69:145:69:145:Infinity":2,"s:146:2:146:Infinity":18,"f:153:16:153:40":3,"b:154:2:154:Infinity:undefined:undefined:undefined:undefined":3,"s:154:2:154:Infinity":19,"s:154:56:154:Infinity":20,"s:155:20:155:Infinity":21,"s:156:2:156:Infinity":22,"s:172:22:172:Infinity":23,"f:180:16:180:37":4,"s:181:27:181:Infinity":24,"f:182:11:182:16":5,"s:184:4:188:Infinity":25,"s:185:6:185:Infinity":26,"s:187:6:187:Infinity":27,"s:189:4:198:Infinity":28,"s:190:23:190:Infinity":29,"b:191:6:197:Infinity:194:13:197:Infinity":4,"s:191:6:197:Infinity":30,"b:192:8:192:Infinity:undefined:undefined:undefined:undefined":5,"s:192:8:192:Infinity":31,"b:192:12:192:38:192:38:192:66":6,"s:192:66:192:Infinity":32,"s:193:8:193:Infinity":33,"b:194:13:197:Infinity:undefined:undefined:undefined:undefined":7,"s:194:13:197:Infinity":34,"s:195:18:195:Infinity":35,"b:196:8:196:Infinity:undefined:undefined:undefined:undefined":8,"s:196:8:196:Infinity":36,"b:196:12:196:17:196:17:196:32":9,"s:196:32:196:Infinity":37,"s:200:2:200:Infinity":38,"s:201:2:201:Infinity":39,"f:218:16:218:39":6,"s:219:47:219:Infinity":40,"s:220:17:220:Infinity":41,"s:222:2:240:Infinity":42,"s:224:4:228:Infinity":43,"s:225:6:225:Infinity":44,"s:227:6:227:Infinity":45,"s:229:20:229:Infinity":46,"b:230:4:239:Infinity:undefined:undefined:undefined:undefined":10,"s:230:4:239:Infinity":47,"s:231:6:238:Infinity":48,"s:241:2:241:Infinity":49,"f:244:16:244:38":7,"b:245:2:245:Infinity:undefined:undefined:undefined:undefined":11,"s:245:2:245:Infinity":50,"s:245:31:245:Infinity":51,"s:246:26:246:Infinity":52,"s:247:2:254:Infinity":53,"s:248:4:248:Infinity":54,"s:249:4:252:Infinity":55,"s:253:4:253:Infinity":56,"s:255:2:255:Infinity":57,"f:274:22:274:44":8,"s:275:15:275:Infinity":58,"s:276:22:276:Infinity":59,"b:276:61:276:71:276:71:276:Infinity":12,"b:276:22:276:33:276:33:276:61":13,"s:278:2:287:Infinity":60,"s:279:18:279:Infinity":61,"b:280:4:283:Infinity:undefined:undefined:undefined:undefined":14,"s:280:4:283:Infinity":62,"s:281:6:281:Infinity":63,"s:282:6:282:Infinity":64,"s:285:4:285:Infinity":65,"s:286:4:286:Infinity":66,"s:289:21:289:Infinity":67,"s:290:23:290:Infinity":68,"b:292:2:304:Infinity:undefined:undefined:undefined:undefined":15,"s:292:2:304:Infinity":69,"s:293:4:295:Infinity":70,"s:296:4:296:Infinity":71,"s:297:4:302:Infinity":72,"s:303:4:303:Infinity":73,"s:306:2:308:Infinity":74,"s:309:2:309:Infinity":75,"b:313:0:315:Infinity:undefined:undefined:undefined:undefined":16,"s:313:0:315:Infinity":76,"s:314:2:314:Infinity":77}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-headline-quality.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-headline-quality.ts","statementMap":{"0":{"start":{"line":66,"column":2},"end":{"line":70,"column":null}},"1":{"start":{"line":69,"column":19},"end":{"line":69,"column":63}},"2":{"start":{"line":95,"column":39},"end":{"line":130,"column":null}},"3":{"start":{"line":134,"column":18},"end":{"line":134,"column":null}},"4":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"5":{"start":{"line":135,"column":16},"end":{"line":135,"column":null}},"6":{"start":{"line":136,"column":15},"end":{"line":136,"column":null}},"7":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"8":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"9":{"start":{"line":138,"column":42},"end":{"line":138,"column":null}},"10":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"11":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"12":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"13":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"14":{"start":{"line":161,"column":28},"end":{"line":161,"column":null}},"15":{"start":{"line":164,"column":15},"end":{"line":164,"column":null}},"16":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"17":{"start":{"line":172,"column":28},"end":{"line":172,"column":null}},"18":{"start":{"line":177,"column":29},"end":{"line":177,"column":null}},"19":{"start":{"line":180,"column":2},"end":{"line":183,"column":null}},"20":{"start":{"line":202,"column":93},"end":{"line":209,"column":null}},"21":{"start":{"line":212,"column":25},"end":{"line":212,"column":null}},"22":{"start":{"line":213,"column":2},"end":{"line":215,"column":null}},"23":{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},"24":{"start":{"line":214,"column":21},"end":{"line":214,"column":null}},"25":{"start":{"line":216,"column":2},"end":{"line":216,"column":null}},"26":{"start":{"line":231,"column":2},"end":{"line":235,"column":null}},"27":{"start":{"line":248,"column":15},"end":{"line":248,"column":null}},"28":{"start":{"line":249,"column":14},"end":{"line":249,"column":null}},"29":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"30":{"start":{"line":250,"column":41},"end":{"line":250,"column":null}},"31":{"start":{"line":253,"column":16},"end":{"line":253,"column":null}},"32":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},"33":{"start":{"line":254,"column":26},"end":{"line":254,"column":null}},"34":{"start":{"line":255,"column":2},"end":{"line":255,"column":null}},"35":{"start":{"line":264,"column":2},"end":{"line":268,"column":null}},"36":{"start":{"line":267,"column":18},"end":{"line":267,"column":42}},"37":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"38":{"start":{"line":280,"column":18},"end":{"line":280,"column":null}},"39":{"start":{"line":281,"column":19},"end":{"line":281,"column":null}},"40":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"41":{"start":{"line":282,"column":17},"end":{"line":282,"column":null}},"42":{"start":{"line":283,"column":20},"end":{"line":283,"column":null}},"43":{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},"44":{"start":{"line":284,"column":43},"end":{"line":284,"column":null}},"45":{"start":{"line":285,"column":19},"end":{"line":285,"column":null}},"46":{"start":{"line":286,"column":15},"end":{"line":286,"column":null}},"47":{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},"48":{"start":{"line":287,"column":13},"end":{"line":287,"column":null}},"49":{"start":{"line":288,"column":20},"end":{"line":288,"column":null}},"50":{"start":{"line":289,"column":2},"end":{"line":289,"column":null}},"51":{"start":{"line":305,"column":15},"end":{"line":305,"column":null}},"52":{"start":{"line":306,"column":12},"end":{"line":306,"column":null}},"53":{"start":{"line":307,"column":2},"end":{"line":307,"column":null}},"54":{"start":{"line":321,"column":24},"end":{"line":321,"column":null}},"55":{"start":{"line":324,"column":4},"end":{"line":328,"column":null}},"56":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"57":{"start":{"line":327,"column":6},"end":{"line":327,"column":null}},"58":{"start":{"line":329,"column":4},"end":{"line":337,"column":null}},"59":{"start":{"line":330,"column":23},"end":{"line":330,"column":null}},"60":{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},"61":{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},"62":{"start":{"line":332,"column":66},"end":{"line":332,"column":null}},"63":{"start":{"line":333,"column":8},"end":{"line":333,"column":null}},"64":{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},"65":{"start":{"line":335,"column":8},"end":{"line":335,"column":null}},"66":{"start":{"line":339,"column":2},"end":{"line":339,"column":null}},"67":{"start":{"line":340,"column":2},"end":{"line":340,"column":null}},"68":{"start":{"line":366,"column":27},"end":{"line":366,"column":null}},"69":{"start":{"line":369,"column":22},"end":{"line":369,"column":null}},"70":{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},"71":{"start":{"line":371,"column":4},"end":{"line":371,"column":null}},"72":{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},"73":{"start":{"line":376,"column":4},"end":{"line":376,"column":null}},"74":{"start":{"line":380,"column":14},"end":{"line":380,"column":null}},"75":{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},"76":{"start":{"line":382,"column":4},"end":{"line":382,"column":null}},"77":{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},"78":{"start":{"line":385,"column":4},"end":{"line":385,"column":null}},"79":{"start":{"line":389,"column":22},"end":{"line":389,"column":null}},"80":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"81":{"start":{"line":391,"column":4},"end":{"line":391,"column":null}},"82":{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},"83":{"start":{"line":396,"column":4},"end":{"line":398,"column":null}},"84":{"start":{"line":401,"column":2},"end":{"line":401,"column":null}},"85":{"start":{"line":406,"column":42},"end":{"line":406,"column":null}},"86":{"start":{"line":407,"column":17},"end":{"line":407,"column":null}},"87":{"start":{"line":409,"column":2},"end":{"line":428,"column":null}},"88":{"start":{"line":411,"column":4},"end":{"line":415,"column":null}},"89":{"start":{"line":412,"column":6},"end":{"line":412,"column":null}},"90":{"start":{"line":414,"column":6},"end":{"line":414,"column":null}},"91":{"start":{"line":416,"column":15},"end":{"line":416,"column":null}},"92":{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},"93":{"start":{"line":417,"column":13},"end":{"line":417,"column":null}},"94":{"start":{"line":418,"column":22},"end":{"line":418,"column":null}},"95":{"start":{"line":419,"column":19},"end":{"line":419,"column":null}},"96":{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},"97":{"start":{"line":421,"column":6},"end":{"line":426,"column":null}},"98":{"start":{"line":429,"column":2},"end":{"line":429,"column":null}},"99":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"100":{"start":{"line":433,"column":31},"end":{"line":433,"column":null}},"101":{"start":{"line":434,"column":26},"end":{"line":434,"column":null}},"102":{"start":{"line":435,"column":2},"end":{"line":442,"column":null}},"103":{"start":{"line":436,"column":4},"end":{"line":436,"column":null}},"104":{"start":{"line":437,"column":4},"end":{"line":437,"column":null}},"105":{"start":{"line":438,"column":4},"end":{"line":440,"column":null}},"106":{"start":{"line":439,"column":6},"end":{"line":439,"column":null}},"107":{"start":{"line":441,"column":4},"end":{"line":441,"column":null}},"108":{"start":{"line":443,"column":2},"end":{"line":443,"column":null}},"109":{"start":{"line":462,"column":15},"end":{"line":462,"column":null}},"110":{"start":{"line":463,"column":22},"end":{"line":463,"column":null}},"111":{"start":{"line":465,"column":2},"end":{"line":474,"column":null}},"112":{"start":{"line":466,"column":18},"end":{"line":466,"column":null}},"113":{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},"114":{"start":{"line":468,"column":6},"end":{"line":468,"column":null}},"115":{"start":{"line":469,"column":6},"end":{"line":469,"column":null}},"116":{"start":{"line":472,"column":4},"end":{"line":472,"column":null}},"117":{"start":{"line":473,"column":4},"end":{"line":473,"column":null}},"118":{"start":{"line":476,"column":21},"end":{"line":476,"column":null}},"119":{"start":{"line":477,"column":23},"end":{"line":477,"column":null}},"120":{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},"121":{"start":{"line":480,"column":4},"end":{"line":482,"column":null}},"122":{"start":{"line":483,"column":4},"end":{"line":483,"column":null}},"123":{"start":{"line":484,"column":4},"end":{"line":492,"column":null}},"124":{"start":{"line":493,"column":4},"end":{"line":493,"column":null}},"125":{"start":{"line":496,"column":2},"end":{"line":496,"column":null}},"126":{"start":{"line":497,"column":2},"end":{"line":497,"column":null}},"127":{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},"128":{"start":{"line":502,"column":2},"end":{"line":502,"column":null}}},"fnMap":{"0":{"name":"prettifySlugSegment","decl":{"start":{"line":65,"column":9},"end":{"line":65,"column":29}},"loc":{"start":{"line":65,"column":54},"end":{"line":71,"column":null}},"line":65},"1":{"name":"(anonymous_1)","decl":{"start":{"line":69,"column":5},"end":{"line":69,"column":10}},"loc":{"start":{"line":69,"column":19},"end":{"line":69,"column":63}},"line":69},"2":{"name":"findSwedishHeadlineTokens","decl":{"start":{"line":133,"column":16},"end":{"line":133,"column":42}},"loc":{"start":{"line":133,"column":64},"end":{"line":141,"column":null}},"line":133},"3":{"name":"hasWeekdayDatePrefix","decl":{"start":{"line":160,"column":16},"end":{"line":160,"column":37}},"loc":{"start":{"line":160,"column":58},"end":{"line":166,"column":null}},"line":160},"4":{"name":"hasIsoDateAffix","decl":{"start":{"line":179,"column":16},"end":{"line":179,"column":32}},"loc":{"start":{"line":179,"column":85},"end":{"line":184,"column":null}},"line":179},"5":{"name":"findBoilerplatePrefixes","decl":{"start":{"line":211,"column":16},"end":{"line":211,"column":40}},"loc":{"start":{"line":211,"column":62},"end":{"line":217,"column":null}},"line":211},"6":{"name":"normaliseHeadlineForCompare","decl":{"start":{"line":230,"column":16},"end":{"line":230,"column":44}},"loc":{"start":{"line":230,"column":66},"end":{"line":236,"column":null}},"line":230},"7":{"name":"subfolderFromBriefPath","decl":{"start":{"line":247,"column":16},"end":{"line":247,"column":39}},"loc":{"start":{"line":247,"column":72},"end":{"line":256,"column":null}},"line":247},"8":{"name":"prettifySubfolderPath","decl":{"start":{"line":263,"column":16},"end":{"line":263,"column":38}},"loc":{"start":{"line":263,"column":65},"end":{"line":269,"column":null}},"line":263},"9":{"name":"(anonymous_9)","decl":{"start":{"line":267,"column":5},"end":{"line":267,"column":10}},"loc":{"start":{"line":267,"column":18},"end":{"line":267,"column":42}},"line":267},"10":{"name":"matchesPrettifiedSubfolder","decl":{"start":{"line":279,"column":16},"end":{"line":279,"column":43}},"loc":{"start":{"line":279,"column":90},"end":{"line":290,"column":null}},"line":279},"11":{"name":"extractH1","decl":{"start":{"line":302,"column":16},"end":{"line":302,"column":26}},"loc":{"start":{"line":302,"column":59},"end":{"line":308,"column":null}},"line":302},"12":{"name":"findEnglishBriefs","decl":{"start":{"line":320,"column":16},"end":{"line":320,"column":34}},"loc":{"start":{"line":320,"column":57},"end":{"line":341,"column":null}},"line":320},"13":{"name":"walk","decl":{"start":{"line":322,"column":11},"end":{"line":322,"column":16}},"loc":{"start":{"line":322,"column":42},"end":{"line":338,"column":null}},"line":322},"14":{"name":"validateH1","decl":{"start":{"line":365,"column":16},"end":{"line":365,"column":27}},"loc":{"start":{"line":365,"column":76},"end":{"line":402,"column":null}},"line":365},"15":{"name":"validateHeadlines","decl":{"start":{"line":405,"column":16},"end":{"line":405,"column":34}},"loc":{"start":{"line":405,"column":76},"end":{"line":430,"column":null}},"line":405},"16":{"name":"formatViolationReport","decl":{"start":{"line":432,"column":16},"end":{"line":432,"column":38}},"loc":{"start":{"line":432,"column":79},"end":{"line":444,"column":null}},"line":432},"17":{"name":"main","decl":{"start":{"line":461,"column":22},"end":{"line":461,"column":44}},"loc":{"start":{"line":461,"column":44},"end":{"line":498,"column":null}},"line":461}},"branchMap":{"0":{"loc":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},{"start":{},"end":{}}],"line":135},"1":{"loc":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":138},"2":{"loc":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"3":{"loc":{"start":{"line":165,"column":9},"end":{"line":165,"column":null}},"type":"binary-expr","locations":[{"start":{"line":165,"column":9},"end":{"line":165,"column":37}},{"start":{"line":165,"column":37},"end":{"line":165,"column":60}},{"start":{"line":165,"column":60},"end":{"line":165,"column":null}}],"line":165},"4":{"loc":{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"5":{"loc":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"type":"if","locations":[{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},{"start":{},"end":{}}],"line":250},"6":{"loc":{"start":{"line":250,"column":6},"end":{"line":250,"column":41}},"type":"binary-expr","locations":[{"start":{"line":250,"column":6},"end":{"line":250,"column":17}},{"start":{"line":250,"column":17},"end":{"line":250,"column":41}}],"line":250},"7":{"loc":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":254},"8":{"loc":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},{"start":{},"end":{}}],"line":280},"9":{"loc":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":282},"10":{"loc":{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},"type":"if","locations":[{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},{"start":{},"end":{}}],"line":284},"11":{"loc":{"start":{"line":284,"column":6},"end":{"line":284,"column":43}},"type":"binary-expr","locations":[{"start":{"line":284,"column":6},"end":{"line":284,"column":19}},{"start":{"line":284,"column":19},"end":{"line":284,"column":43}}],"line":284},"12":{"loc":{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":287},"13":{"loc":{"start":{"line":289,"column":9},"end":{"line":289,"column":null}},"type":"binary-expr","locations":[{"start":{"line":289,"column":9},"end":{"line":289,"column":31}},{"start":{"line":289,"column":31},"end":{"line":289,"column":null}}],"line":289},"14":{"loc":{"start":{"line":307,"column":9},"end":{"line":307,"column":null}},"type":"cond-expr","locations":[{"start":{"line":307,"column":13},"end":{"line":307,"column":27}},{"start":{"line":307,"column":27},"end":{"line":307,"column":null}}],"line":307},"15":{"loc":{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},{"start":{"line":334,"column":13},"end":{"line":336,"column":null}}],"line":331},"16":{"loc":{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},"type":"if","locations":[{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},{"start":{},"end":{}}],"line":332},"17":{"loc":{"start":{"line":332,"column":12},"end":{"line":332,"column":66}},"type":"binary-expr","locations":[{"start":{"line":332,"column":12},"end":{"line":332,"column":38}},{"start":{"line":332,"column":38},"end":{"line":332,"column":66}}],"line":332},"18":{"loc":{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},{"start":{},"end":{}}],"line":334},"19":{"loc":{"start":{"line":334,"column":17},"end":{"line":334,"column":72}},"type":"binary-expr","locations":[{"start":{"line":334,"column":17},"end":{"line":334,"column":35}},{"start":{"line":334,"column":35},"end":{"line":334,"column":72}}],"line":334},"20":{"loc":{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},"type":"if","locations":[{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},{"start":{},"end":{}}],"line":370},"21":{"loc":{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},"type":"if","locations":[{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},{"start":{},"end":{}}],"line":375},"22":{"loc":{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},"type":"if","locations":[{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},{"start":{},"end":{}}],"line":381},"23":{"loc":{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},"type":"if","locations":[{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},{"start":{},"end":{}}],"line":384},"24":{"loc":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"type":"if","locations":[{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},{"start":{},"end":{}}],"line":390},"25":{"loc":{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},"type":"if","locations":[{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},{"start":{},"end":{}}],"line":395},"26":{"loc":{"start":{"line":395,"column":6},"end":{"line":395,"column":62}},"type":"binary-expr","locations":[{"start":{"line":395,"column":6},"end":{"line":395,"column":19}},{"start":{"line":395,"column":19},"end":{"line":395,"column":62}}],"line":395},"27":{"loc":{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},"type":"if","locations":[{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},{"start":{},"end":{}}],"line":417},"28":{"loc":{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},"type":"if","locations":[{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},{"start":{},"end":{}}],"line":420},"29":{"loc":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"type":"if","locations":[{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},{"start":{},"end":{}}],"line":433},"30":{"loc":{"start":{"line":463,"column":22},"end":{"line":463,"column":null}},"type":"cond-expr","locations":[{"start":{"line":463,"column":61},"end":{"line":463,"column":71}},{"start":{"line":463,"column":71},"end":{"line":463,"column":null}}],"line":463},"31":{"loc":{"start":{"line":463,"column":22},"end":{"line":463,"column":61}},"type":"binary-expr","locations":[{"start":{"line":463,"column":22},"end":{"line":463,"column":33}},{"start":{"line":463,"column":33},"end":{"line":463,"column":61}}],"line":463},"32":{"loc":{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},{"start":{},"end":{}}],"line":467},"33":{"loc":{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},{"start":{},"end":{}}],"line":479},"34":{"loc":{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},"type":"if","locations":[{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},{"start":{},"end":{}}],"line":501}},"s":{"0":21,"1":28,"2":1,"3":13,"4":13,"5":0,"6":13,"7":13,"8":62,"9":7,"10":13,"11":1,"12":1,"13":12,"14":6,"15":6,"16":6,"17":1,"18":1,"19":10,"20":1,"21":12,"22":12,"23":72,"24":6,"25":12,"26":23,"27":5,"28":5,"29":5,"30":2,"31":3,"32":3,"33":0,"34":3,"35":11,"36":17,"37":11,"38":2,"39":9,"40":9,"41":0,"42":9,"43":9,"44":5,"45":4,"46":4,"47":4,"48":0,"49":4,"50":4,"51":4,"52":4,"53":4,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":6,"69":6,"70":6,"71":1,"72":6,"73":1,"74":6,"75":6,"76":0,"77":6,"78":1,"79":6,"80":6,"81":1,"82":6,"83":1,"84":6,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":1,"128":0},"f":{"0":21,"1":28,"2":13,"3":12,"4":10,"5":12,"6":23,"7":5,"8":11,"9":17,"10":11,"11":4,"12":0,"13":0,"14":6,"15":0,"16":0,"17":0},"b":{"0":[0,13],"1":[7,55],"2":[6,6],"3":[6,4,4],"4":[6,66],"5":[2,3],"6":[5,4],"7":[0,3],"8":[2,9],"9":[0,9],"10":[5,4],"11":[9,9],"12":[0,4],"13":[4,4],"14":[3,1],"15":[0,0],"16":[0,0],"17":[0,0],"18":[0,0],"19":[0,0],"20":[1,5],"21":[1,5],"22":[0,6],"23":[1,5],"24":[1,5],"25":[1,5],"26":[6,1],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,1]},"meta":{"lastBranch":35,"lastFunction":18,"lastStatement":129,"seen":{"f:65:9:65:29":0,"s:66:2:70:Infinity":0,"f:69:5:69:10":1,"s:69:19:69:63":1,"s:95:39:130:Infinity":2,"f:133:16:133:42":2,"s:134:18:134:Infinity":3,"b:135:2:135:Infinity:undefined:undefined:undefined:undefined":0,"s:135:2:135:Infinity":4,"s:135:16:135:Infinity":5,"s:136:15:136:Infinity":6,"s:137:2:139:Infinity":7,"b:138:4:138:Infinity:undefined:undefined:undefined:undefined":1,"s:138:4:138:Infinity":8,"s:138:42:138:Infinity":9,"s:140:2:140:Infinity":10,"s:156:2:156:Infinity":11,"s:158:2:158:Infinity":12,"f:160:16:160:37":3,"b:161:2:161:Infinity:undefined:undefined:undefined:undefined":2,"s:161:2:161:Infinity":13,"s:161:28:161:Infinity":14,"s:164:15:164:Infinity":15,"s:165:2:165:Infinity":16,"b:165:9:165:37:165:37:165:60:165:60:165:Infinity":3,"s:172:28:172:Infinity":17,"s:177:29:177:Infinity":18,"f:179:16:179:32":4,"s:180:2:183:Infinity":19,"s:202:93:209:Infinity":20,"f:211:16:211:40":5,"s:212:25:212:Infinity":21,"s:213:2:215:Infinity":22,"b:214:4:214:Infinity:undefined:undefined:undefined:undefined":4,"s:214:4:214:Infinity":23,"s:214:21:214:Infinity":24,"s:216:2:216:Infinity":25,"f:230:16:230:44":6,"s:231:2:235:Infinity":26,"f:247:16:247:39":7,"s:248:15:248:Infinity":27,"s:249:14:249:Infinity":28,"b:250:2:250:Infinity:undefined:undefined:undefined:undefined":5,"s:250:2:250:Infinity":29,"b:250:6:250:17:250:17:250:41":6,"s:250:41:250:Infinity":30,"s:253:16:253:Infinity":31,"b:254:2:254:Infinity:undefined:undefined:undefined:undefined":7,"s:254:2:254:Infinity":32,"s:254:26:254:Infinity":33,"s:255:2:255:Infinity":34,"f:263:16:263:38":8,"s:264:2:268:Infinity":35,"f:267:5:267:10":9,"s:267:18:267:42":36,"f:279:16:279:43":10,"b:280:2:280:Infinity:undefined:undefined:undefined:undefined":8,"s:280:2:280:Infinity":37,"s:280:18:280:Infinity":38,"s:281:19:281:Infinity":39,"b:282:2:282:Infinity:undefined:undefined:undefined:undefined":9,"s:282:2:282:Infinity":40,"s:282:17:282:Infinity":41,"s:283:20:283:Infinity":42,"b:284:2:284:Infinity:undefined:undefined:undefined:undefined":10,"s:284:2:284:Infinity":43,"b:284:6:284:19:284:19:284:43":11,"s:284:43:284:Infinity":44,"s:285:19:285:Infinity":45,"s:286:15:286:Infinity":46,"b:287:2:287:Infinity:undefined:undefined:undefined:undefined":12,"s:287:2:287:Infinity":47,"s:287:13:287:Infinity":48,"s:288:20:288:Infinity":49,"s:289:2:289:Infinity":50,"b:289:9:289:31:289:31:289:Infinity":13,"f:302:16:302:26":11,"s:305:15:305:Infinity":51,"s:306:12:306:Infinity":52,"s:307:2:307:Infinity":53,"b:307:13:307:27:307:27:307:Infinity":14,"f:320:16:320:34":12,"s:321:24:321:Infinity":54,"f:322:11:322:16":13,"s:324:4:328:Infinity":55,"s:325:6:325:Infinity":56,"s:327:6:327:Infinity":57,"s:329:4:337:Infinity":58,"s:330:23:330:Infinity":59,"b:331:6:336:Infinity:334:13:336:Infinity":15,"s:331:6:336:Infinity":60,"b:332:8:332:Infinity:undefined:undefined:undefined:undefined":16,"s:332:8:332:Infinity":61,"b:332:12:332:38:332:38:332:66":17,"s:332:66:332:Infinity":62,"s:333:8:333:Infinity":63,"b:334:13:336:Infinity:undefined:undefined:undefined:undefined":18,"s:334:13:336:Infinity":64,"b:334:17:334:35:334:35:334:72":19,"s:335:8:335:Infinity":65,"s:339:2:339:Infinity":66,"s:340:2:340:Infinity":67,"f:365:16:365:27":14,"s:366:27:366:Infinity":68,"s:369:22:369:Infinity":69,"b:370:2:372:Infinity:undefined:undefined:undefined:undefined":20,"s:370:2:372:Infinity":70,"s:371:4:371:Infinity":71,"b:375:2:377:Infinity:undefined:undefined:undefined:undefined":21,"s:375:2:377:Infinity":72,"s:376:4:376:Infinity":73,"s:380:14:380:Infinity":74,"b:381:2:383:Infinity:undefined:undefined:undefined:undefined":22,"s:381:2:383:Infinity":75,"s:382:4:382:Infinity":76,"b:384:2:386:Infinity:undefined:undefined:undefined:undefined":23,"s:384:2:386:Infinity":77,"s:385:4:385:Infinity":78,"s:389:22:389:Infinity":79,"b:390:2:392:Infinity:undefined:undefined:undefined:undefined":24,"s:390:2:392:Infinity":80,"s:391:4:391:Infinity":81,"b:395:2:399:Infinity:undefined:undefined:undefined:undefined":25,"s:395:2:399:Infinity":82,"b:395:6:395:19:395:19:395:62":26,"s:396:4:398:Infinity":83,"s:401:2:401:Infinity":84,"f:405:16:405:34":15,"s:406:42:406:Infinity":85,"s:407:17:407:Infinity":86,"s:409:2:428:Infinity":87,"s:411:4:415:Infinity":88,"s:412:6:412:Infinity":89,"s:414:6:414:Infinity":90,"s:416:15:416:Infinity":91,"b:417:4:417:Infinity:undefined:undefined:undefined:undefined":27,"s:417:4:417:Infinity":92,"s:417:13:417:Infinity":93,"s:418:22:418:Infinity":94,"s:419:19:419:Infinity":95,"b:420:4:427:Infinity:undefined:undefined:undefined:undefined":28,"s:420:4:427:Infinity":96,"s:421:6:426:Infinity":97,"s:429:2:429:Infinity":98,"f:432:16:432:38":16,"b:433:2:433:Infinity:undefined:undefined:undefined:undefined":29,"s:433:2:433:Infinity":99,"s:433:31:433:Infinity":100,"s:434:26:434:Infinity":101,"s:435:2:442:Infinity":102,"s:436:4:436:Infinity":103,"s:437:4:437:Infinity":104,"s:438:4:440:Infinity":105,"s:439:6:439:Infinity":106,"s:441:4:441:Infinity":107,"s:443:2:443:Infinity":108,"f:461:22:461:44":17,"s:462:15:462:Infinity":109,"s:463:22:463:Infinity":110,"b:463:61:463:71:463:71:463:Infinity":30,"b:463:22:463:33:463:33:463:61":31,"s:465:2:474:Infinity":111,"s:466:18:466:Infinity":112,"b:467:4:470:Infinity:undefined:undefined:undefined:undefined":32,"s:467:4:470:Infinity":113,"s:468:6:468:Infinity":114,"s:469:6:469:Infinity":115,"s:472:4:472:Infinity":116,"s:473:4:473:Infinity":117,"s:476:21:476:Infinity":118,"s:477:23:477:Infinity":119,"b:479:2:494:Infinity:undefined:undefined:undefined:undefined":33,"s:479:2:494:Infinity":120,"s:480:4:482:Infinity":121,"s:483:4:483:Infinity":122,"s:484:4:492:Infinity":123,"s:493:4:493:Infinity":124,"s:496:2:496:Infinity":125,"s:497:2:497:Infinity":126,"b:501:0:503:Infinity:undefined:undefined:undefined:undefined":34,"s:501:0:503:Infinity":127,"s:502:2:502:Infinity":128}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-imf-connectivity.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-imf-connectivity.ts","statementMap":{"0":{"start":{"line":121,"column":28},"end":{"line":121,"column":null}},"1":{"start":{"line":135,"column":16},"end":{"line":135,"column":null}},"2":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},"3":{"start":{"line":136,"column":14},"end":{"line":136,"column":null}},"4":{"start":{"line":137,"column":15},"end":{"line":137,"column":null}},"5":{"start":{"line":138,"column":16},"end":{"line":138,"column":null}},"6":{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},"7":{"start":{"line":139,"column":57},"end":{"line":139,"column":null}},"8":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"9":{"start":{"line":140,"column":31},"end":{"line":140,"column":null}},"10":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"11":{"start":{"line":153,"column":17},"end":{"line":153,"column":null}},"12":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"13":{"start":{"line":154,"column":15},"end":{"line":154,"column":null}},"14":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"15":{"start":{"line":156,"column":24},"end":{"line":156,"column":null}},"16":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"17":{"start":{"line":168,"column":17},"end":{"line":168,"column":null}},"18":{"start":{"line":168,"column":45},"end":{"line":168,"column":50}},"19":{"start":{"line":169,"column":24},"end":{"line":171,"column":null}},"20":{"start":{"line":170,"column":24},"end":{"line":170,"column":81}},"21":{"start":{"line":172,"column":2},"end":{"line":186,"column":null}},"22":{"start":{"line":198,"column":25},"end":{"line":200,"column":null}},"23":{"start":{"line":201,"column":2},"end":{"line":208,"column":null}},"24":{"start":{"line":216,"column":17},"end":{"line":216,"column":null}},"25":{"start":{"line":216,"column":45},"end":{"line":216,"column":50}},"26":{"start":{"line":217,"column":24},"end":{"line":219,"column":null}},"27":{"start":{"line":218,"column":24},"end":{"line":218,"column":81}},"28":{"start":{"line":220,"column":2},"end":{"line":230,"column":null}},"29":{"start":{"line":246,"column":32},"end":{"line":246,"column":null}},"30":{"start":{"line":249,"column":40},"end":{"line":249,"column":null}},"31":{"start":{"line":262,"column":2},"end":{"line":262,"column":null}},"32":{"start":{"line":278,"column":23},"end":{"line":278,"column":null}},"33":{"start":{"line":279,"column":2},"end":{"line":291,"column":null}},"34":{"start":{"line":280,"column":18},"end":{"line":285,"column":null}},"35":{"start":{"line":283,"column":8},"end":{"line":283,"column":null}},"36":{"start":{"line":283,"column":33},"end":{"line":283,"column":55}},"37":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"38":{"start":{"line":288,"column":4},"end":{"line":288,"column":null}},"39":{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},"40":{"start":{"line":290,"column":15},"end":{"line":290,"column":null}},"41":{"start":{"line":305,"column":35},"end":{"line":305,"column":null}},"42":{"start":{"line":308,"column":18},"end":{"line":308,"column":null}},"43":{"start":{"line":309,"column":19},"end":{"line":312,"column":null}},"44":{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},"45":{"start":{"line":314,"column":6},"end":{"line":320,"column":null}},"46":{"start":{"line":322,"column":21},"end":{"line":322,"column":null}},"47":{"start":{"line":323,"column":6},"end":{"line":329,"column":null}},"48":{"start":{"line":334,"column":18},"end":{"line":334,"column":null}},"49":{"start":{"line":335,"column":19},"end":{"line":338,"column":null}},"50":{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},"51":{"start":{"line":340,"column":6},"end":{"line":346,"column":null}},"52":{"start":{"line":348,"column":21},"end":{"line":348,"column":null}},"53":{"start":{"line":349,"column":6},"end":{"line":355,"column":null}},"54":{"start":{"line":360,"column":18},"end":{"line":360,"column":null}},"55":{"start":{"line":361,"column":26},"end":{"line":361,"column":null}},"56":{"start":{"line":362,"column":19},"end":{"line":365,"column":null}},"57":{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},"58":{"start":{"line":367,"column":25},"end":{"line":367,"column":null}},"59":{"start":{"line":369,"column":8},"end":{"line":370,"column":null}},"60":{"start":{"line":371,"column":20},"end":{"line":373,"column":null}},"61":{"start":{"line":374,"column":6},"end":{"line":380,"column":null}},"62":{"start":{"line":382,"column":18},"end":{"line":382,"column":null}},"63":{"start":{"line":383,"column":20},"end":{"line":383,"column":null}},"64":{"start":{"line":384,"column":24},"end":{"line":384,"column":null}},"65":{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},"66":{"start":{"line":387,"column":25},"end":{"line":387,"column":null}},"67":{"start":{"line":388,"column":21},"end":{"line":388,"column":null}},"68":{"start":{"line":389,"column":25},"end":{"line":389,"column":null}},"69":{"start":{"line":390,"column":8},"end":{"line":392,"column":null}},"70":{"start":{"line":391,"column":10},"end":{"line":391,"column":null}},"71":{"start":{"line":394,"column":17},"end":{"line":394,"column":null}},"72":{"start":{"line":395,"column":6},"end":{"line":401,"column":null}},"73":{"start":{"line":405,"column":2},"end":{"line":405,"column":null}},"74":{"start":{"line":417,"column":20},"end":{"line":417,"column":null}},"75":{"start":{"line":418,"column":16},"end":{"line":418,"column":null}},"76":{"start":{"line":419,"column":21},"end":{"line":421,"column":null}},"77":{"start":{"line":420,"column":4},"end":{"line":420,"column":null}},"78":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"79":{"start":{"line":422,"column":20},"end":{"line":422,"column":null}},"80":{"start":{"line":422,"column":39},"end":{"line":422,"column":44}},"81":{"start":{"line":423,"column":50},"end":{"line":429,"column":null}},"82":{"start":{"line":430,"column":20},"end":{"line":430,"column":null}},"83":{"start":{"line":431,"column":21},"end":{"line":438,"column":null}},"84":{"start":{"line":439,"column":23},"end":{"line":445,"column":null}},"85":{"start":{"line":446,"column":2},"end":{"line":446,"column":null}},"86":{"start":{"line":459,"column":2},"end":{"line":459,"column":null}},"87":{"start":{"line":460,"column":22},"end":{"line":460,"column":null}},"88":{"start":{"line":461,"column":2},"end":{"line":461,"column":null}},"89":{"start":{"line":463,"column":19},"end":{"line":463,"column":null}},"90":{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},"91":{"start":{"line":465,"column":19},"end":{"line":465,"column":null}},"92":{"start":{"line":465,"column":47},"end":{"line":465,"column":52}},"93":{"start":{"line":465,"column":65},"end":{"line":465,"column":75}},"94":{"start":{"line":466,"column":21},"end":{"line":477,"column":null}},"95":{"start":{"line":478,"column":4},"end":{"line":478,"column":null}},"96":{"start":{"line":492,"column":13},"end":{"line":492,"column":null}},"97":{"start":{"line":512,"column":15},"end":{"line":512,"column":null}},"98":{"start":{"line":513,"column":18},"end":{"line":513,"column":null}},"99":{"start":{"line":514,"column":13},"end":{"line":514,"column":null}},"100":{"start":{"line":515,"column":2},"end":{"line":535,"column":null}},"101":{"start":{"line":515,"column":15},"end":{"line":515,"column":18}},"102":{"start":{"line":516,"column":18},"end":{"line":516,"column":null}},"103":{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},"104":{"start":{"line":518,"column":6},"end":{"line":518,"column":null}},"105":{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},"106":{"start":{"line":520,"column":6},"end":{"line":520,"column":null}},"107":{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},"108":{"start":{"line":522,"column":19},"end":{"line":522,"column":null}},"109":{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},"110":{"start":{"line":524,"column":8},"end":{"line":524,"column":null}},"111":{"start":{"line":525,"column":8},"end":{"line":525,"column":null}},"112":{"start":{"line":527,"column":6},"end":{"line":527,"column":null}},"113":{"start":{"line":528,"column":6},"end":{"line":528,"column":null}},"114":{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},"115":{"start":{"line":530,"column":6},"end":{"line":530,"column":null}},"116":{"start":{"line":532,"column":6},"end":{"line":532,"column":null}},"117":{"start":{"line":533,"column":6},"end":{"line":533,"column":null}},"118":{"start":{"line":536,"column":2},"end":{"line":536,"column":null}},"119":{"start":{"line":540,"column":15},"end":{"line":540,"column":null}},"120":{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},"121":{"start":{"line":542,"column":4},"end":{"line":542,"column":null}},"122":{"start":{"line":543,"column":4},"end":{"line":543,"column":null}},"123":{"start":{"line":546,"column":17},"end":{"line":546,"column":null}},"124":{"start":{"line":547,"column":17},"end":{"line":547,"column":null}},"125":{"start":{"line":548,"column":17},"end":{"line":548,"column":null}},"126":{"start":{"line":550,"column":2},"end":{"line":550,"column":null}},"127":{"start":{"line":552,"column":2},"end":{"line":552,"column":null}},"128":{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},"129":{"start":{"line":555,"column":4},"end":{"line":559,"column":null}},"130":{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},"131":{"start":{"line":561,"column":6},"end":{"line":561,"column":null}},"132":{"start":{"line":563,"column":4},"end":{"line":563,"column":null}},"133":{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},"134":{"start":{"line":567,"column":4},"end":{"line":575,"column":null}},"135":{"start":{"line":581,"column":6},"end":{"line":585,"column":null}},"136":{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},"137":{"start":{"line":582,"column":58},"end":{"line":582,"column":null}},"138":{"start":{"line":583,"column":16},"end":{"line":583,"column":null}},"139":{"start":{"line":584,"column":2},"end":{"line":584,"column":null}},"140":{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},"141":{"start":{"line":588,"column":2},"end":{"line":592,"column":null}},"142":{"start":{"line":589,"column":16},"end":{"line":589,"column":null}},"143":{"start":{"line":590,"column":4},"end":{"line":590,"column":null}},"144":{"start":{"line":591,"column":4},"end":{"line":591,"column":null}}},"fnMap":{"0":{"name":"parseVintage","decl":{"start":{"line":134,"column":16},"end":{"line":134,"column":29}},"loc":{"start":{"line":134,"column":86},"end":{"line":142,"column":null}},"line":134},"1":{"name":"vintageAgeMonths","decl":{"start":{"line":152,"column":16},"end":{"line":152,"column":33}},"loc":{"start":{"line":152,"column":82},"end":{"line":158,"column":null}},"line":152},"2":{"name":"formatUnavailableWarning","decl":{"start":{"line":167,"column":16},"end":{"line":167,"column":41}},"loc":{"start":{"line":167,"column":110},"end":{"line":187,"column":null}},"line":167},"3":{"name":"(anonymous_3)","decl":{"start":{"line":168,"column":31},"end":{"line":168,"column":39}},"loc":{"start":{"line":168,"column":45},"end":{"line":168,"column":50}},"line":168},"4":{"name":"(anonymous_4)","decl":{"start":{"line":170,"column":13},"end":{"line":170,"column":18}},"loc":{"start":{"line":170,"column":24},"end":{"line":170,"column":81}},"line":170},"5":{"name":"formatStaleVintageAnnotation","decl":{"start":{"line":197,"column":16},"end":{"line":197,"column":45}},"loc":{"start":{"line":197,"column":122},"end":{"line":209,"column":null}},"line":197},"6":{"name":"formatDegradedWarning","decl":{"start":{"line":215,"column":16},"end":{"line":215,"column":38}},"loc":{"start":{"line":215,"column":107},"end":{"line":231,"column":null}},"line":215},"7":{"name":"(anonymous_7)","decl":{"start":{"line":216,"column":31},"end":{"line":216,"column":39}},"loc":{"start":{"line":216,"column":45},"end":{"line":216,"column":50}},"line":216},"8":{"name":"(anonymous_8)","decl":{"start":{"line":218,"column":13},"end":{"line":218,"column":18}},"loc":{"start":{"line":218,"column":24},"end":{"line":218,"column":81}},"line":218},"9":{"name":"isProbeErr","decl":{"start":{"line":261,"column":9},"end":{"line":261,"column":20}},"loc":{"start":{"line":261,"column":70},"end":{"line":263,"column":null}},"line":261},"10":{"name":"withTimeout","decl":{"start":{"line":273,"column":15},"end":{"line":273,"column":null}},"loc":{"start":{"line":276,"column":27},"end":{"line":292,"column":null}},"line":276},"11":{"name":"(anonymous_11)","decl":{"start":{"line":282,"column":10},"end":{"line":282,"column":22}},"loc":{"start":{"line":282,"column":43},"end":{"line":284,"column":7}},"line":282},"12":{"name":"(anonymous_12)","decl":{"start":{"line":283,"column":16},"end":{"line":283,"column":33}},"loc":{"start":{"line":283,"column":33},"end":{"line":283,"column":55}},"line":283},"13":{"name":"runProbes","decl":{"start":{"line":304,"column":22},"end":{"line":304,"column":32}},"loc":{"start":{"line":304,"column":78},"end":{"line":406,"column":null}},"line":304},"14":{"name":"buildReport","decl":{"start":{"line":412,"column":16},"end":{"line":412,"column":null}},"loc":{"start":{"line":416,"column":25},"end":{"line":447,"column":null}},"line":416},"15":{"name":"(anonymous_15)","decl":{"start":{"line":419,"column":35},"end":{"line":419,"column":42}},"loc":{"start":{"line":420,"column":4},"end":{"line":420,"column":null}},"line":420},"16":{"name":"(anonymous_16)","decl":{"start":{"line":420,"column":11},"end":{"line":420,"column":17}},"loc":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"line":420},"17":{"name":"(anonymous_17)","decl":{"start":{"line":422,"column":27},"end":{"line":422,"column":33}},"loc":{"start":{"line":422,"column":39},"end":{"line":422,"column":44}},"line":422},"18":{"name":"writeReport","decl":{"start":{"line":458,"column":16},"end":{"line":458,"column":28}},"loc":{"start":{"line":458,"column":85},"end":{"line":480,"column":null}},"line":458},"19":{"name":"(anonymous_19)","decl":{"start":{"line":465,"column":33},"end":{"line":465,"column":41}},"loc":{"start":{"line":465,"column":47},"end":{"line":465,"column":52}},"line":465},"20":{"name":"(anonymous_20)","decl":{"start":{"line":465,"column":54},"end":{"line":465,"column":59}},"loc":{"start":{"line":465,"column":65},"end":{"line":465,"column":75}},"line":465},"21":{"name":"parseCliArgs","decl":{"start":{"line":511,"column":16},"end":{"line":511,"column":29}},"loc":{"start":{"line":511,"column":66},"end":{"line":537,"column":null}},"line":511},"22":{"name":"mainCli","decl":{"start":{"line":539,"column":15},"end":{"line":539,"column":40}},"loc":{"start":{"line":539,"column":40},"end":{"line":577,"column":null}},"line":539},"23":{"name":"(anonymous_23)","decl":{"start":{"line":581,"column":6},"end":{"line":581,"column":34}},"loc":{"start":{"line":581,"column":34},"end":{"line":585,"column":1}},"line":581},"24":{"name":"(anonymous_24)","decl":{"start":{"line":588,"column":12},"end":{"line":588,"column":19}},"loc":{"start":{"line":588,"column":36},"end":{"line":592,"column":3}},"line":588}},"branchMap":{"0":{"loc":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":136},"1":{"loc":{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":139},"2":{"loc":{"start":{"line":139,"column":6},"end":{"line":139,"column":57}},"type":"binary-expr","locations":[{"start":{"line":139,"column":6},"end":{"line":139,"column":32}},{"start":{"line":139,"column":32},"end":{"line":139,"column":57}}],"line":139},"3":{"loc":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":140},"4":{"loc":{"start":{"line":140,"column":6},"end":{"line":140,"column":31}},"type":"binary-expr","locations":[{"start":{"line":140,"column":6},"end":{"line":140,"column":19}},{"start":{"line":140,"column":19},"end":{"line":140,"column":31}}],"line":140},"5":{"loc":{"start":{"line":152,"column":50},"end":{"line":152,"column":82}},"type":"default-arg","locations":[{"start":{"line":152,"column":62},"end":{"line":152,"column":82}}],"line":152},"6":{"loc":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":154},"7":{"loc":{"start":{"line":169,"column":24},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},{"start":{"line":171,"column":6},"end":{"line":171,"column":null}}],"line":169},"8":{"loc":{"start":{"line":170,"column":59},"end":{"line":170,"column":81}},"type":"binary-expr","locations":[{"start":{"line":170,"column":59},"end":{"line":170,"column":70}},{"start":{"line":170,"column":70},"end":{"line":170,"column":81}}],"line":170},"9":{"loc":{"start":{"line":198,"column":25},"end":{"line":200,"column":null}},"type":"cond-expr","locations":[{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},{"start":{"line":200,"column":6},"end":{"line":200,"column":null}}],"line":198},"10":{"loc":{"start":{"line":217,"column":24},"end":{"line":219,"column":null}},"type":"cond-expr","locations":[{"start":{"line":218,"column":6},"end":{"line":218,"column":null}},{"start":{"line":219,"column":6},"end":{"line":219,"column":null}}],"line":217},"11":{"loc":{"start":{"line":218,"column":59},"end":{"line":218,"column":81}},"type":"binary-expr","locations":[{"start":{"line":218,"column":59},"end":{"line":218,"column":70}},{"start":{"line":218,"column":70},"end":{"line":218,"column":81}}],"line":218},"12":{"loc":{"start":{"line":288,"column":31},"end":{"line":288,"column":83}},"type":"cond-expr","locations":[{"start":{"line":288,"column":54},"end":{"line":288,"column":60}},{"start":{"line":288,"column":60},"end":{"line":288,"column":83}}],"line":288},"13":{"loc":{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},"type":"if","locations":[{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},{"start":{},"end":{}}],"line":290},"14":{"loc":{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},{"start":{"line":321,"column":11},"end":{"line":330,"column":null}}],"line":313},"15":{"loc":{"start":{"line":328,"column":12},"end":{"line":328,"column":null}},"type":"cond-expr","locations":[{"start":{"line":328,"column":34},"end":{"line":328,"column":62}},{"start":{"line":328,"column":62},"end":{"line":328,"column":null}}],"line":328},"16":{"loc":{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},"type":"if","locations":[{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},{"start":{"line":347,"column":11},"end":{"line":356,"column":null}}],"line":339},"17":{"loc":{"start":{"line":354,"column":12},"end":{"line":354,"column":null}},"type":"cond-expr","locations":[{"start":{"line":354,"column":34},"end":{"line":354,"column":62}},{"start":{"line":354,"column":62},"end":{"line":354,"column":null}}],"line":354},"18":{"loc":{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},"type":"if","locations":[{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},{"start":{"line":381,"column":11},"end":{"line":402,"column":null}}],"line":366},"19":{"loc":{"start":{"line":369,"column":8},"end":{"line":370,"column":null}},"type":"binary-expr","locations":[{"start":{"line":369,"column":8},"end":{"line":369,"column":null}},{"start":{"line":370,"column":8},"end":{"line":370,"column":null}}],"line":369},"20":{"loc":{"start":{"line":371,"column":20},"end":{"line":373,"column":null}},"type":"cond-expr","locations":[{"start":{"line":372,"column":10},"end":{"line":372,"column":null}},{"start":{"line":373,"column":10},"end":{"line":373,"column":null}}],"line":371},"21":{"loc":{"start":{"line":371,"column":20},"end":{"line":371,"column":null}},"type":"binary-expr","locations":[{"start":{"line":371,"column":20},"end":{"line":371,"column":38}},{"start":{"line":371,"column":38},"end":{"line":371,"column":null}}],"line":371},"22":{"loc":{"start":{"line":383,"column":20},"end":{"line":383,"column":null}},"type":"binary-expr","locations":[{"start":{"line":383,"column":20},"end":{"line":383,"column":36}},{"start":{"line":383,"column":36},"end":{"line":383,"column":null}}],"line":383},"23":{"loc":{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},"type":"if","locations":[{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},{"start":{},"end":{}}],"line":385},"24":{"loc":{"start":{"line":389,"column":25},"end":{"line":389,"column":null}},"type":"binary-expr","locations":[{"start":{"line":389,"column":25},"end":{"line":389,"column":46}},{"start":{"line":389,"column":46},"end":{"line":389,"column":63}},{"start":{"line":389,"column":63},"end":{"line":389,"column":null}}],"line":389},"25":{"loc":{"start":{"line":391,"column":37},"end":{"line":391,"column":53}},"type":"binary-expr","locations":[{"start":{"line":391,"column":37},"end":{"line":391,"column":51}},{"start":{"line":391,"column":51},"end":{"line":391,"column":53}}],"line":391},"26":{"loc":{"start":{"line":394,"column":17},"end":{"line":394,"column":null}},"type":"binary-expr","locations":[{"start":{"line":394,"column":17},"end":{"line":394,"column":26}},{"start":{"line":394,"column":26},"end":{"line":394,"column":null}}],"line":394},"27":{"loc":{"start":{"line":400,"column":12},"end":{"line":400,"column":null}},"type":"cond-expr","locations":[{"start":{"line":400,"column":17},"end":{"line":400,"column":22}},{"start":{"line":400,"column":22},"end":{"line":400,"column":null}}],"line":400},"28":{"loc":{"start":{"line":400,"column":31},"end":{"line":400,"column":83}},"type":"cond-expr","locations":[{"start":{"line":400,"column":39},"end":{"line":400,"column":61}},{"start":{"line":400,"column":61},"end":{"line":400,"column":83}}],"line":400},"29":{"loc":{"start":{"line":415,"column":2},"end":{"line":415,"column":null}},"type":"default-arg","locations":[{"start":{"line":415,"column":14},"end":{"line":415,"column":null}}],"line":415},"30":{"loc":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"type":"binary-expr","locations":[{"start":{"line":420,"column":23},"end":{"line":420,"column":50}},{"start":{"line":420,"column":50},"end":{"line":420,"column":54}}],"line":420},"31":{"loc":{"start":{"line":423,"column":50},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":424,"column":6},"end":{"line":424,"column":null}},{"start":{"line":425,"column":6},"end":{"line":429,"column":null}}],"line":423},"32":{"loc":{"start":{"line":425,"column":6},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":426,"column":8},"end":{"line":426,"column":null}},{"start":{"line":427,"column":8},"end":{"line":429,"column":null}}],"line":425},"33":{"loc":{"start":{"line":427,"column":8},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":428,"column":10},"end":{"line":428,"column":null}},{"start":{"line":429,"column":8},"end":{"line":429,"column":null}}],"line":427},"34":{"loc":{"start":{"line":434,"column":22},"end":{"line":434,"column":null}},"type":"cond-expr","locations":[{"start":{"line":434,"column":51},"end":{"line":434,"column":63}},{"start":{"line":434,"column":63},"end":{"line":434,"column":null}}],"line":434},"35":{"loc":{"start":{"line":439,"column":23},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},{"start":{"line":441,"column":6},"end":{"line":445,"column":null}}],"line":439},"36":{"loc":{"start":{"line":441,"column":6},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},{"start":{"line":443,"column":8},"end":{"line":445,"column":null}}],"line":441},"37":{"loc":{"start":{"line":443,"column":8},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":444,"column":10},"end":{"line":444,"column":null}},{"start":{"line":445,"column":10},"end":{"line":445,"column":null}}],"line":443},"38":{"loc":{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},"type":"if","locations":[{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},{"start":{},"end":{}}],"line":464},"39":{"loc":{"start":{"line":469,"column":29},"end":{"line":469,"column":null}},"type":"binary-expr","locations":[{"start":{"line":469,"column":29},"end":{"line":469,"column":39}},{"start":{"line":469,"column":39},"end":{"line":469,"column":null}}],"line":469},"40":{"loc":{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},{"start":{"line":519,"column":11},"end":{"line":534,"column":null}}],"line":517},"41":{"loc":{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},{"start":{"line":521,"column":11},"end":{"line":534,"column":null}}],"line":519},"42":{"loc":{"start":{"line":519,"column":15},"end":{"line":519,"column":53}},"type":"binary-expr","locations":[{"start":{"line":519,"column":15},"end":{"line":519,"column":37}},{"start":{"line":519,"column":37},"end":{"line":519,"column":53}}],"line":519},"43":{"loc":{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},{"start":{"line":529,"column":11},"end":{"line":534,"column":null}}],"line":521},"44":{"loc":{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},"type":"if","locations":[{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},{"start":{},"end":{}}],"line":523},"45":{"loc":{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},{"start":{"line":531,"column":11},"end":{"line":534,"column":null}}],"line":529},"46":{"loc":{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},"type":"if","locations":[{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},{"start":{},"end":{}}],"line":541},"47":{"loc":{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},"type":"if","locations":[{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},{"start":{},"end":{}}],"line":554},"48":{"loc":{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},"type":"if","locations":[{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},{"start":{},"end":{}}],"line":560},"49":{"loc":{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},"type":"if","locations":[{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},{"start":{},"end":{}}],"line":566},"50":{"loc":{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},"type":"if","locations":[{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},{"start":{},"end":{}}],"line":582},"51":{"loc":{"start":{"line":582,"column":6},"end":{"line":582,"column":58}},"type":"binary-expr","locations":[{"start":{"line":582,"column":6},"end":{"line":582,"column":40}},{"start":{"line":582,"column":40},"end":{"line":582,"column":58}}],"line":582},"52":{"loc":{"start":{"line":584,"column":9},"end":{"line":584,"column":null}},"type":"binary-expr","locations":[{"start":{"line":584,"column":9},"end":{"line":584,"column":56}},{"start":{"line":584,"column":56},"end":{"line":584,"column":null}}],"line":584},"53":{"loc":{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},"type":"if","locations":[{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},{"start":{},"end":{}}],"line":587},"54":{"loc":{"start":{"line":589,"column":16},"end":{"line":589,"column":null}},"type":"cond-expr","locations":[{"start":{"line":589,"column":39},"end":{"line":589,"column":53}},{"start":{"line":589,"column":53},"end":{"line":589,"column":null}}],"line":589}},"s":{"0":2,"1":20,"2":20,"3":5,"4":15,"5":15,"6":15,"7":0,"8":15,"9":1,"10":14,"11":14,"12":14,"13":2,"14":12,"15":12,"16":12,"17":3,"18":8,"19":3,"20":5,"21":3,"22":6,"23":6,"24":3,"25":8,"26":3,"27":3,"28":3,"29":2,"30":2,"31":33,"32":33,"33":33,"34":33,"35":33,"36":3,"37":22,"38":11,"39":33,"40":33,"41":11,"42":11,"43":11,"44":11,"45":2,"46":9,"47":9,"48":11,"49":11,"50":11,"51":2,"52":9,"53":9,"54":11,"55":11,"56":11,"57":11,"58":7,"59":7,"60":7,"61":7,"62":4,"63":4,"64":4,"65":4,"66":3,"67":3,"68":3,"69":3,"70":3,"71":4,"72":4,"73":11,"74":9,"75":9,"76":9,"77":16,"78":27,"79":9,"80":23,"81":9,"82":9,"83":9,"84":9,"85":9,"86":4,"87":4,"88":4,"89":4,"90":4,"91":1,"92":3,"93":3,"94":1,"95":1,"96":2,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":2,"136":2,"137":0,"138":2,"139":2,"140":2,"141":0,"142":0,"143":0,"144":0},"f":{"0":20,"1":14,"2":3,"3":8,"4":5,"5":6,"6":3,"7":8,"8":3,"9":33,"10":33,"11":33,"12":3,"13":11,"14":9,"15":16,"16":27,"17":23,"18":4,"19":3,"20":3,"21":0,"22":0,"23":2,"24":0},"b":{"0":[5,15],"1":[0,15],"2":[15,15],"3":[1,14],"4":[15,15],"5":[14],"6":[2,12],"7":[3,0],"8":[5,0],"9":[2,4],"10":[3,0],"11":[3,0],"12":[11,0],"13":[33,0],"14":[2,9],"15":[1,8],"16":[2,9],"17":[1,8],"18":[7,4],"19":[7,3],"20":[3,4],"21":[7,6],"22":[4,4],"23":[3,1],"24":[3,0,0],"25":[3,0],"26":[4,3],"27":[2,2],"28":[1,1],"29":[9],"30":[27,16],"31":[2,7],"32":[3,4],"33":[2,2],"34":[8,1],"35":[2,7],"36":[3,4],"37":[2,2],"38":[1,3],"39":[1,0],"40":[0,0],"41":[0,0],"42":[0,0],"43":[0,0],"44":[0,0],"45":[0,0],"46":[0,0],"47":[0,0],"48":[0,0],"49":[0,0],"50":[0,2],"51":[2,2],"52":[2,2],"53":[0,2],"54":[0,0]},"meta":{"lastBranch":55,"lastFunction":25,"lastStatement":145,"seen":{"s:121:28:121:Infinity":0,"f:134:16:134:29":0,"s:135:16:135:Infinity":1,"b:136:2:136:Infinity:undefined:undefined:undefined:undefined":0,"s:136:2:136:Infinity":2,"s:136:14:136:Infinity":3,"s:137:15:137:Infinity":4,"s:138:16:138:Infinity":5,"b:139:2:139:Infinity:undefined:undefined:undefined:undefined":1,"s:139:2:139:Infinity":6,"b:139:6:139:32:139:32:139:57":2,"s:139:57:139:Infinity":7,"b:140:2:140:Infinity:undefined:undefined:undefined:undefined":3,"s:140:2:140:Infinity":8,"b:140:6:140:19:140:19:140:31":4,"s:140:31:140:Infinity":9,"s:141:2:141:Infinity":10,"f:152:16:152:33":1,"b:152:62:152:82":5,"s:153:17:153:Infinity":11,"b:154:2:154:Infinity:undefined:undefined:undefined:undefined":6,"s:154:2:154:Infinity":12,"s:154:15:154:Infinity":13,"s:155:20:155:Infinity":14,"s:156:24:156:Infinity":15,"s:157:2:157:Infinity":16,"f:167:16:167:41":2,"s:168:17:168:Infinity":17,"f:168:31:168:39":3,"s:168:45:168:50":18,"s:169:24:171:Infinity":19,"b:170:6:170:Infinity:171:6:171:Infinity":7,"f:170:13:170:18":4,"s:170:24:170:81":20,"b:170:59:170:70:170:70:170:81":8,"s:172:2:186:Infinity":21,"f:197:16:197:45":5,"s:198:25:200:Infinity":22,"b:199:6:199:Infinity:200:6:200:Infinity":9,"s:201:2:208:Infinity":23,"f:215:16:215:38":6,"s:216:17:216:Infinity":24,"f:216:31:216:39":7,"s:216:45:216:50":25,"s:217:24:219:Infinity":26,"b:218:6:218:Infinity:219:6:219:Infinity":10,"f:218:13:218:18":8,"s:218:24:218:81":27,"b:218:59:218:70:218:70:218:81":11,"s:220:2:230:Infinity":28,"s:246:32:246:Infinity":29,"s:249:40:249:Infinity":30,"f:261:9:261:20":9,"s:262:2:262:Infinity":31,"f:273:15:273:Infinity":10,"s:278:23:278:Infinity":32,"s:279:2:291:Infinity":33,"s:280:18:285:Infinity":34,"f:282:10:282:22":11,"s:283:8:283:Infinity":35,"f:283:16:283:33":12,"s:283:33:283:55":36,"s:286:4:286:Infinity":37,"s:288:4:288:Infinity":38,"b:288:54:288:60:288:60:288:83":12,"b:290:4:290:Infinity:undefined:undefined:undefined:undefined":13,"s:290:4:290:Infinity":39,"s:290:15:290:Infinity":40,"f:304:22:304:32":13,"s:305:35:305:Infinity":41,"s:308:18:308:Infinity":42,"s:309:19:312:Infinity":43,"b:313:4:330:Infinity:321:11:330:Infinity":14,"s:313:4:330:Infinity":44,"s:314:6:320:Infinity":45,"s:322:21:322:Infinity":46,"s:323:6:329:Infinity":47,"b:328:34:328:62:328:62:328:Infinity":15,"s:334:18:334:Infinity":48,"s:335:19:338:Infinity":49,"b:339:4:356:Infinity:347:11:356:Infinity":16,"s:339:4:356:Infinity":50,"s:340:6:346:Infinity":51,"s:348:21:348:Infinity":52,"s:349:6:355:Infinity":53,"b:354:34:354:62:354:62:354:Infinity":17,"s:360:18:360:Infinity":54,"s:361:26:361:Infinity":55,"s:362:19:365:Infinity":56,"b:366:4:402:Infinity:381:11:402:Infinity":18,"s:366:4:402:Infinity":57,"s:367:25:367:Infinity":58,"s:369:8:370:Infinity":59,"b:369:8:369:Infinity:370:8:370:Infinity":19,"s:371:20:373:Infinity":60,"b:372:10:372:Infinity:373:10:373:Infinity":20,"b:371:20:371:38:371:38:371:Infinity":21,"s:374:6:380:Infinity":61,"s:382:18:382:Infinity":62,"s:383:20:383:Infinity":63,"b:383:20:383:36:383:36:383:Infinity":22,"s:384:24:384:Infinity":64,"b:385:6:393:Infinity:undefined:undefined:undefined:undefined":23,"s:385:6:393:Infinity":65,"s:387:25:387:Infinity":66,"s:388:21:388:Infinity":67,"s:389:25:389:Infinity":68,"b:389:25:389:46:389:46:389:63:389:63:389:Infinity":24,"s:390:8:392:Infinity":69,"s:391:10:391:Infinity":70,"b:391:37:391:51:391:51:391:53":25,"s:394:17:394:Infinity":71,"b:394:17:394:26:394:26:394:Infinity":26,"s:395:6:401:Infinity":72,"b:400:17:400:22:400:22:400:Infinity":27,"b:400:39:400:61:400:61:400:83":28,"s:405:2:405:Infinity":73,"f:412:16:412:Infinity":14,"b:415:14:415:Infinity":29,"s:417:20:417:Infinity":74,"s:418:16:418:Infinity":75,"s:419:21:421:Infinity":76,"f:419:35:419:42":15,"s:420:4:420:Infinity":77,"f:420:11:420:17":16,"s:420:23:420:54":78,"b:420:23:420:50:420:50:420:54":30,"s:422:20:422:Infinity":79,"f:422:27:422:33":17,"s:422:39:422:44":80,"s:423:50:429:Infinity":81,"b:424:6:424:Infinity:425:6:429:Infinity":31,"b:426:8:426:Infinity:427:8:429:Infinity":32,"b:428:10:428:Infinity:429:8:429:Infinity":33,"s:430:20:430:Infinity":82,"s:431:21:438:Infinity":83,"b:434:51:434:63:434:63:434:Infinity":34,"s:439:23:445:Infinity":84,"b:440:6:440:Infinity:441:6:445:Infinity":35,"b:442:8:442:Infinity:443:8:445:Infinity":36,"b:444:10:444:Infinity:445:10:445:Infinity":37,"s:446:2:446:Infinity":85,"f:458:16:458:28":18,"s:459:2:459:Infinity":86,"s:460:22:460:Infinity":87,"s:461:2:461:Infinity":88,"s:463:19:463:Infinity":89,"b:464:2:479:Infinity:undefined:undefined:undefined:undefined":38,"s:464:2:479:Infinity":90,"s:465:19:465:Infinity":91,"f:465:33:465:41":19,"s:465:47:465:52":92,"f:465:54:465:59":20,"s:465:65:465:75":93,"s:466:21:477:Infinity":94,"b:469:29:469:39:469:39:469:Infinity":39,"s:478:4:478:Infinity":95,"s:492:13:492:Infinity":96,"f:511:16:511:29":21,"s:512:15:512:Infinity":97,"s:513:18:513:Infinity":98,"s:514:13:514:Infinity":99,"s:515:2:535:Infinity":100,"s:515:15:515:18":101,"s:516:18:516:Infinity":102,"b:517:4:534:Infinity:519:11:534:Infinity":40,"s:517:4:534:Infinity":103,"s:518:6:518:Infinity":104,"b:519:11:534:Infinity:521:11:534:Infinity":41,"s:519:11:534:Infinity":105,"b:519:15:519:37:519:37:519:53":42,"s:520:6:520:Infinity":106,"b:521:11:534:Infinity:529:11:534:Infinity":43,"s:521:11:534:Infinity":107,"s:522:19:522:Infinity":108,"b:523:6:526:Infinity:undefined:undefined:undefined:undefined":44,"s:523:6:526:Infinity":109,"s:524:8:524:Infinity":110,"s:525:8:525:Infinity":111,"s:527:6:527:Infinity":112,"s:528:6:528:Infinity":113,"b:529:11:534:Infinity:531:11:534:Infinity":45,"s:529:11:534:Infinity":114,"s:530:6:530:Infinity":115,"s:532:6:532:Infinity":116,"s:533:6:533:Infinity":117,"s:536:2:536:Infinity":118,"f:539:15:539:40":22,"s:540:15:540:Infinity":119,"b:541:2:544:Infinity:undefined:undefined:undefined:undefined":46,"s:541:2:544:Infinity":120,"s:542:4:542:Infinity":121,"s:543:4:543:Infinity":122,"s:546:17:546:Infinity":123,"s:547:17:547:Infinity":124,"s:548:17:548:Infinity":125,"s:550:2:550:Infinity":126,"s:552:2:552:Infinity":127,"b:554:2:564:Infinity:undefined:undefined:undefined:undefined":47,"s:554:2:564:Infinity":128,"s:555:4:559:Infinity":129,"b:560:4:562:Infinity:undefined:undefined:undefined:undefined":48,"s:560:4:562:Infinity":130,"s:561:6:561:Infinity":131,"s:563:4:563:Infinity":132,"b:566:2:576:Infinity:undefined:undefined:undefined:undefined":49,"s:566:2:576:Infinity":133,"s:567:4:575:Infinity":134,"s:581:6:585:Infinity":135,"f:581:6:581:34":23,"b:582:2:582:Infinity:undefined:undefined:undefined:undefined":50,"s:582:2:582:Infinity":136,"b:582:6:582:40:582:40:582:58":51,"s:582:58:582:Infinity":137,"s:583:16:583:Infinity":138,"s:584:2:584:Infinity":139,"b:584:9:584:56:584:56:584:Infinity":52,"b:587:0:593:Infinity:undefined:undefined:undefined:undefined":53,"s:587:0:593:Infinity":140,"s:588:2:592:Infinity":141,"f:588:12:588:19":24,"s:589:16:589:Infinity":142,"b:589:39:589:53:589:53:589:Infinity":54,"s:590:4:590:Infinity":143,"s:591:4:591:Infinity":144}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/cli.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/cli.ts","statementMap":{"0":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"2":{"start":{"line":33,"column":16},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":35,"column":15},"end":{"line":35,"column":18}},"6":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"7":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"8":{"start":{"line":37,"column":43},"end":{"line":37,"column":null}},"9":{"start":{"line":38,"column":16},"end":{"line":38,"column":null}},"10":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"11":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"12":{"start":{"line":41,"column":6},"end":{"line":41,"column":null}},"13":{"start":{"line":42,"column":6},"end":{"line":42,"column":null}},"14":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"15":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"16":{"start":{"line":48,"column":15},"end":{"line":48,"column":null}},"17":{"start":{"line":49,"column":13},"end":{"line":49,"column":null}},"18":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"19":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"20":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"21":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"22":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"23":{"start":{"line":60,"column":15},"end":{"line":60,"column":null}},"24":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"25":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"26":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"27":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"28":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"29":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"30":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"31":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":2},"end":{"line":19,"column":14}},"loc":{"start":{"line":19,"column":31},"end":{"line":22,"column":null}},"line":19},"1":{"name":"parseCalendarArgs","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":34}},"loc":{"start":{"line":32,"column":2},"end":{"line":57,"column":null}},"line":32},"2":{"name":"main","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":44}},"loc":{"start":{"line":59,"column":44},"end":{"line":76,"column":null}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":37,"column":8},"end":{"line":37,"column":43}},"type":"binary-expr","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":18}},{"start":{"line":37,"column":18},"end":{"line":37,"column":43}}],"line":37},"2":{"loc":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},{"start":{"line":43,"column":11},"end":{"line":45,"column":null}}],"line":40},"3":{"loc":{"start":{"line":40,"column":8},"end":{"line":40,"column":54}},"type":"binary-expr","locations":[{"start":{"line":40,"column":8},"end":{"line":40,"column":30}},{"start":{"line":40,"column":30},"end":{"line":40,"column":54}}],"line":40},"4":{"loc":{"start":{"line":48,"column":15},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":15},"end":{"line":48,"column":36}},{"start":{"line":48,"column":36},"end":{"line":48,"column":null}}],"line":48},"5":{"loc":{"start":{"line":49,"column":13},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":13},"end":{"line":49,"column":32}},{"start":{"line":49,"column":32},"end":{"line":49,"column":52}},{"start":{"line":49,"column":52},"end":{"line":49,"column":null}}],"line":49},"6":{"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"7":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},{"start":{"line":69,"column":9},"end":{"line":71,"column":null}}],"line":67},"9":{"loc":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":73}},"s":{"0":5,"1":5,"2":9,"3":9,"4":9,"5":9,"6":17,"7":17,"8":0,"9":17,"10":17,"11":17,"12":16,"13":16,"14":1,"15":9,"16":9,"17":9,"18":9,"19":4,"20":5,"21":1,"22":4,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0},"f":{"0":5,"1":9,"2":0},"b":{"0":[0,17],"1":[17,17],"2":[16,1],"3":[17,16],"4":[9,2],"5":[9,2,1],"6":[4,5],"7":[1,4],"8":[0,0],"9":[0,0]},"meta":{"lastBranch":10,"lastFunction":3,"lastStatement":32,"seen":{"f:19:2:19:14":0,"s:20:4:20:Infinity":0,"s:21:4:21:Infinity":1,"f:28:16:28:34":1,"s:33:16:33:Infinity":2,"s:34:19:34:Infinity":3,"s:35:2:46:Infinity":4,"s:35:15:35:18":5,"s:36:18:36:Infinity":6,"b:37:4:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:37:Infinity":7,"b:37:8:37:18:37:18:37:43":1,"s:37:43:37:Infinity":8,"s:38:16:38:Infinity":9,"s:39:17:39:Infinity":10,"b:40:4:45:Infinity:43:11:45:Infinity":2,"s:40:4:45:Infinity":11,"b:40:8:40:30:40:30:40:54":3,"s:41:6:41:Infinity":12,"s:42:6:42:Infinity":13,"s:44:6:44:Infinity":14,"s:47:22:47:Infinity":15,"s:48:15:48:Infinity":16,"b:48:15:48:36:48:36:48:Infinity":4,"s:49:13:49:Infinity":17,"b:49:13:49:32:49:32:49:52:49:52:49:Infinity":5,"b:50:2:52:Infinity:undefined:undefined:undefined:undefined":6,"s:50:2:52:Infinity":18,"s:51:4:51:Infinity":19,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":7,"s:53:2:55:Infinity":20,"s:54:4:54:Infinity":21,"s:56:2:56:Infinity":22,"f:59:22:59:44":2,"s:60:15:60:Infinity":23,"s:61:2:61:Infinity":24,"s:63:17:63:Infinity":25,"s:65:2:65:Infinity":26,"b:67:2:71:Infinity:69:9:71:Infinity":8,"s:67:2:71:Infinity":27,"s:68:4:68:Infinity":28,"s:70:4:70:Infinity":29,"b:73:2:75:Infinity:undefined:undefined:undefined:undefined":9,"s:73:2:75:Infinity":30,"s:74:4:74:Infinity":31}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/manifest.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/manifest.ts","statementMap":{"0":{"start":{"line":20,"column":18},"end":{"line":20,"column":null}},"1":{"start":{"line":22,"column":18},"end":{"line":22,"column":null}},"2":{"start":{"line":23,"column":21},"end":{"line":23,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":21},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":18},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"10":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"11":{"start":{"line":60,"column":4},"end":{"line":64,"column":null}},"12":{"start":{"line":66,"column":16},"end":{"line":72,"column":null}},"13":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"14":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"15":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"16":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"17":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"persistCalendarJson","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":52,"column":null}},"line":37},"1":{"name":"formatManifestMarkdown","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":39}},"loc":{"start":{"line":58,"column":80},"end":{"line":80,"column":null}},"line":58}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":22},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":17},"end":{"line":39,"column":43}},{"start":{"line":39,"column":43},"end":{"line":39,"column":null}}],"line":39},"2":{"loc":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":47},"end":{"line":40,"column":74}},{"start":{"line":40,"column":74},"end":{"line":40,"column":null}}],"line":40},"3":{"loc":{"start":{"line":40,"column":19},"end":{"line":40,"column":47}},"type":"binary-expr","locations":[{"start":{"line":40,"column":19},"end":{"line":40,"column":29}},{"start":{"line":40,"column":29},"end":{"line":40,"column":47}}],"line":40},"4":{"loc":{"start":{"line":60,"column":4},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":null}},{"start":{"line":62,"column":8},"end":{"line":64,"column":null}}],"line":60},"5":{"loc":{"start":{"line":62,"column":8},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},{"start":{"line":64,"column":10},"end":{"line":64,"column":null}}],"line":62},"6":{"loc":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":73},"7":{"loc":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76}},"s":{"0":9,"1":9,"2":9,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":4,"10":4,"11":3,"12":3,"13":3,"14":2,"15":3,"16":1,"17":3},"f":{"0":4,"1":3},"b":{"0":[4],"1":[4,0],"2":[1,3],"3":[4,4],"4":[1,2],"5":[1,1],"6":[2,1],"7":[1,2]},"meta":{"lastBranch":8,"lastFunction":2,"lastStatement":18,"seen":{"s:20:18:20:Infinity":0,"s:22:18:22:Infinity":1,"s:23:21:23:Infinity":2,"f:33:16:33:Infinity":0,"b:36:22:36:Infinity":0,"s:38:2:38:Infinity":3,"s:39:17:39:Infinity":4,"b:39:17:39:43:39:43:39:Infinity":1,"s:40:19:40:Infinity":5,"b:40:47:40:74:40:74:40:Infinity":2,"b:40:19:40:29:40:29:40:47":3,"s:41:21:41:Infinity":6,"s:42:18:46:Infinity":7,"s:47:2:47:Infinity":8,"s:48:2:50:Infinity":9,"s:51:2:51:Infinity":10,"f:58:16:58:39":1,"s:60:4:64:Infinity":11,"b:61:8:61:Infinity:62:8:64:Infinity":4,"b:63:10:63:Infinity:64:10:64:Infinity":5,"s:66:16:72:Infinity":12,"b:73:2:75:Infinity:undefined:undefined:undefined:undefined":6,"s:73:2:75:Infinity":13,"s:74:4:74:Infinity":14,"b:76:2:78:Infinity:undefined:undefined:undefined:undefined":7,"s:76:2:78:Infinity":15,"s:77:4:77:Infinity":16,"s:79:2:79:Infinity":17}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/errors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/errors.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"1":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"2":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"3":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"4":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"8":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"isHtmlErrorResponse","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":36}},"loc":{"start":{"line":23,"column":59},"end":{"line":25,"column":null}},"line":23},"1":{"name":"isDegradedKalenderSentinel","decl":{"start":{"line":48,"column":16},"end":{"line":48,"column":43}},"loc":{"start":{"line":48,"column":84},"end":{"line":52,"column":null}},"line":48},"2":{"name":"(anonymous_2)","decl":{"start":{"line":61,"column":2},"end":{"line":61,"column":14}},"loc":{"start":{"line":61,"column":86},"end":{"line":66,"column":null}},"line":61}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":25},"end":{"line":49,"column":63}},{"start":{"line":49,"column":63},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":61}},{"start":{"line":50,"column":61},"end":{"line":50,"column":null}}],"line":50},"2":{"loc":{"start":{"line":51,"column":9},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":9},"end":{"line":51,"column":27}},{"start":{"line":51,"column":27},"end":{"line":51,"column":null}}],"line":51}},"s":{"0":41,"1":32,"2":38,"3":38,"4":38,"5":25,"6":25,"7":25,"8":25},"f":{"0":32,"1":38,"2":25},"b":{"0":[38,10],"1":[38,10],"2":[38,29]},"meta":{"lastBranch":3,"lastFunction":3,"lastStatement":9,"seen":{"s:17:2:17:Infinity":0,"f:23:16:23:36":0,"s:24:2:24:Infinity":1,"f:48:16:48:43":1,"s:49:25:49:Infinity":2,"b:49:25:49:63:49:63:49:Infinity":0,"s:50:21:50:Infinity":3,"b:50:21:50:61:50:61:50:Infinity":1,"s:51:2:51:Infinity":4,"b:51:9:51:27:51:27:51:Infinity":2,"f:61:2:61:14":2,"s:62:4:62:Infinity":5,"s:63:4:63:Infinity":6,"s:64:4:64:Infinity":7,"s:65:4:65:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/client.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":31},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":35},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":35},"end":{"line":22,"column":null}},"4":{"start":{"line":44,"column":13},"end":{"line":44,"column":null}},"5":{"start":{"line":57,"column":31},"end":{"line":62,"column":null}},"6":{"start":{"line":64,"column":21},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":14},"end":{"line":65,"column":null}},"8":{"start":{"line":65,"column":31},"end":{"line":65,"column":51}},"9":{"start":{"line":68,"column":2},"end":{"line":94,"column":null}},"10":{"start":{"line":69,"column":21},"end":{"line":77,"column":null}},"11":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"12":{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},"13":{"start":{"line":82,"column":6},"end":{"line":86,"column":null}},"14":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"15":{"start":{"line":89,"column":41},"end":{"line":89,"column":null}},"16":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"17":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"18":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"19":{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},"20":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"21":{"start":{"line":101,"column":2},"end":{"line":108,"column":null}},"22":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"23":{"start":{"line":104,"column":4},"end":{"line":107,"column":null}},"24":{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},"25":{"start":{"line":111,"column":16},"end":{"line":111,"column":null}},"26":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"27":{"start":{"line":115,"column":17},"end":{"line":115,"column":null}},"28":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"29":{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},"30":{"start":{"line":120,"column":4},"end":{"line":127,"column":null}},"31":{"start":{"line":121,"column":6},"end":{"line":121,"column":null}},"32":{"start":{"line":123,"column":6},"end":{"line":126,"column":null}},"33":{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},"34":{"start":{"line":132,"column":6},"end":{"line":136,"column":null}},"35":{"start":{"line":138,"column":19},"end":{"line":138,"column":null}},"36":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"37":{"start":{"line":139,"column":31},"end":{"line":139,"column":null}},"38":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"39":{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},"40":{"start":{"line":144,"column":4},"end":{"line":148,"column":null}},"41":{"start":{"line":151,"column":17},"end":{"line":151,"column":null}},"42":{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},"43":{"start":{"line":152,"column":29},"end":{"line":152,"column":null}},"44":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}}},"fnMap":{"0":{"name":"callMcpCalendarEvents","decl":{"start":{"line":52,"column":22},"end":{"line":52,"column":null}},"loc":{"start":{"line":56,"column":22},"end":{"line":155,"column":null}},"line":56},"1":{"name":"(anonymous_1)","decl":{"start":{"line":65,"column":14},"end":{"line":65,"column":31}},"loc":{"start":{"line":65,"column":31},"end":{"line":65,"column":51}},"line":65}},"branchMap":{"0":{"loc":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"type":"binary-expr","locations":[{"start":{"line":18,"column":2},"end":{"line":18,"column":35}},{"start":{"line":18,"column":35},"end":{"line":18,"column":null}}],"line":18},"1":{"loc":{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":81},"2":{"loc":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"type":"cond-expr","locations":[{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},{"start":{"line":84,"column":53},"end":{"line":84,"column":null}}],"line":84},"3":{"loc":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"4":{"loc":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":90,"column":39},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":null}}],"line":90},"5":{"loc":{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":96},"6":{"loc":{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":110},"7":{"loc":{"start":{"line":111,"column":16},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":16},"end":{"line":111,"column":37}},{"start":{"line":111,"column":37},"end":{"line":111,"column":null}}],"line":111},"8":{"loc":{"start":{"line":115,"column":17},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":17},"end":{"line":115,"column":31}},{"start":{"line":115,"column":31},"end":{"line":115,"column":null}}],"line":115},"9":{"loc":{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":118},"10":{"loc":{"start":{"line":118,"column":6},"end":{"line":118,"column":50}},"type":"binary-expr","locations":[{"start":{"line":118,"column":6},"end":{"line":118,"column":32}},{"start":{"line":118,"column":32},"end":{"line":118,"column":50}}],"line":118},"11":{"loc":{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":131},"12":{"loc":{"start":{"line":133,"column":45},"end":{"line":133,"column":84}},"type":"binary-expr","locations":[{"start":{"line":133,"column":45},"end":{"line":133,"column":63}},{"start":{"line":133,"column":63},"end":{"line":133,"column":84}}],"line":133},"13":{"loc":{"start":{"line":135,"column":8},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":135,"column":47},"end":{"line":135,"column":66}},{"start":{"line":135,"column":66},"end":{"line":135,"column":null}}],"line":135},"14":{"loc":{"start":{"line":138,"column":19},"end":{"line":138,"column":null}},"type":"binary-expr","locations":[{"start":{"line":138,"column":19},"end":{"line":138,"column":40}},{"start":{"line":138,"column":40},"end":{"line":138,"column":null}}],"line":138},"15":{"loc":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":139},"16":{"loc":{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":143},"17":{"loc":{"start":{"line":145,"column":43},"end":{"line":145,"column":83}},"type":"binary-expr","locations":[{"start":{"line":145,"column":43},"end":{"line":145,"column":62}},{"start":{"line":145,"column":62},"end":{"line":145,"column":83}}],"line":145},"18":{"loc":{"start":{"line":147,"column":6},"end":{"line":147,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":46},"end":{"line":147,"column":66}},{"start":{"line":147,"column":66},"end":{"line":147,"column":null}}],"line":147},"19":{"loc":{"start":{"line":151,"column":17},"end":{"line":151,"column":null}},"type":"binary-expr","locations":[{"start":{"line":151,"column":17},"end":{"line":151,"column":39}},{"start":{"line":151,"column":39},"end":{"line":151,"column":null}}],"line":151},"20":{"loc":{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},{"start":{},"end":{}}],"line":152}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":28,"6":28,"7":28,"8":0,"9":28,"10":28,"11":22,"12":22,"13":1,"14":7,"15":1,"16":6,"17":7,"18":28,"19":21,"20":4,"21":17,"22":17,"23":0,"24":17,"25":1,"26":1,"27":16,"28":28,"29":28,"30":11,"31":11,"32":1,"33":10,"34":4,"35":6,"36":11,"37":6,"38":0,"39":5,"40":2,"41":3,"42":28,"43":2,"44":1},"f":{"0":28,"1":0},"b":{"0":[9,9],"1":[1,21],"2":[0,1],"3":[1,6],"4":[6,0],"5":[4,17],"6":[1,16],"7":[1,0],"8":[16,0],"9":[11,17],"10":[28,11],"11":[4,6],"12":[4,0],"13":[3,1],"14":[6,0],"15":[6,5],"16":[2,3],"17":[2,1],"18":[1,1],"19":[3,2],"20":[2,26]},"meta":{"lastBranch":21,"lastFunction":2,"lastStatement":45,"seen":{"s:18:2:18:Infinity":0,"b:18:2:18:35:18:35:18:Infinity":0,"s:19:31:19:Infinity":1,"s:20:35:20:Infinity":2,"s:22:35:22:Infinity":3,"s:44:13:44:Infinity":4,"f:52:22:52:Infinity":0,"s:57:31:62:Infinity":5,"s:64:21:64:Infinity":6,"s:65:14:65:Infinity":7,"f:65:14:65:31":1,"s:65:31:65:51":8,"s:68:2:94:Infinity":9,"s:69:21:77:Infinity":10,"s:79:4:79:Infinity":11,"b:81:4:87:Infinity:undefined:undefined:undefined:undefined":1,"s:81:4:87:Infinity":12,"s:82:6:86:Infinity":13,"b:84:44:84:53:84:53:84:Infinity":2,"b:89:4:89:Infinity:undefined:undefined:undefined:undefined":3,"s:89:4:89:Infinity":14,"s:89:41:89:Infinity":15,"s:90:16:90:Infinity":16,"b:90:39:90:53:90:53:90:Infinity":4,"s:91:4:91:Infinity":17,"s:93:4:93:Infinity":18,"b:96:2:98:Infinity:undefined:undefined:undefined:undefined":5,"s:96:2:98:Infinity":19,"s:97:4:97:Infinity":20,"s:101:2:108:Infinity":21,"s:102:4:102:Infinity":22,"s:104:4:107:Infinity":23,"b:110:2:113:Infinity:undefined:undefined:undefined:undefined":6,"s:110:2:113:Infinity":24,"s:111:16:111:Infinity":25,"b:111:16:111:37:111:37:111:Infinity":7,"s:112:4:112:Infinity":26,"s:115:17:115:Infinity":27,"b:115:17:115:31:115:31:115:Infinity":8,"s:117:18:117:Infinity":28,"b:118:2:141:Infinity:undefined:undefined:undefined:undefined":9,"s:118:2:141:Infinity":29,"b:118:6:118:32:118:32:118:50":10,"s:120:4:127:Infinity":30,"s:121:6:121:Infinity":31,"s:123:6:126:Infinity":32,"b:131:4:137:Infinity:undefined:undefined:undefined:undefined":11,"s:131:4:137:Infinity":33,"s:132:6:136:Infinity":34,"b:133:45:133:63:133:63:133:84":12,"b:135:47:135:66:135:66:135:Infinity":13,"s:138:19:138:Infinity":35,"b:138:19:138:40:138:40:138:Infinity":14,"b:139:4:139:Infinity:undefined:undefined:undefined:undefined":15,"s:139:4:139:Infinity":36,"s:139:31:139:Infinity":37,"s:140:4:140:Infinity":38,"b:143:2:149:Infinity:undefined:undefined:undefined:undefined":16,"s:143:2:149:Infinity":39,"s:144:4:148:Infinity":40,"b:145:43:145:62:145:62:145:83":17,"b:147:46:147:66:147:66:147:Infinity":18,"s:151:17:151:Infinity":41,"b:151:17:151:39:151:39:151:Infinity":19,"b:152:2:152:Infinity:undefined:undefined:undefined:undefined":20,"s:152:2:152:Infinity":42,"s:152:29:152:Infinity":43,"s:154:2:154:Infinity":44}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/normaliser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/normaliser.ts","statementMap":{"0":{"start":{"line":21,"column":13},"end":{"line":21,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"3":{"start":{"line":25,"column":14},"end":{"line":25,"column":null}},"4":{"start":{"line":26,"column":14},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"6":{"start":{"line":29,"column":28},"end":{"line":29,"column":null}},"7":{"start":{"line":30,"column":2},"end":{"line":39,"column":null}},"8":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"11":{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},"12":{"start":{"line":35,"column":6},"end":{"line":37,"column":null}},"13":{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},"14":{"start":{"line":36,"column":53},"end":{"line":36,"column":null}},"15":{"start":{"line":41,"column":2},"end":{"line":49,"column":null}}},"fnMap":{"0":{"name":"normalizeMcpCalendarEvent","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":42}},"loc":{"start":{"line":20,"column":71},"end":{"line":50,"column":null}},"line":20}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":13},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":13},"end":{"line":21,"column":20}},{"start":{"line":21,"column":20},"end":{"line":21,"column":null}}],"line":21},"1":{"loc":{"start":{"line":23,"column":25},"end":{"line":23,"column":73}},"type":"binary-expr","locations":[{"start":{"line":23,"column":25},"end":{"line":23,"column":41}},{"start":{"line":23,"column":41},"end":{"line":23,"column":57}},{"start":{"line":23,"column":57},"end":{"line":23,"column":71}},{"start":{"line":23,"column":71},"end":{"line":23,"column":73}}],"line":23},"2":{"loc":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"type":"binary-expr","locations":[{"start":{"line":24,"column":16},"end":{"line":24,"column":77}},{"start":{"line":24,"column":77},"end":{"line":24,"column":null}}],"line":24},"3":{"loc":{"start":{"line":24,"column":23},"end":{"line":24,"column":65}},"type":"binary-expr","locations":[{"start":{"line":24,"column":23},"end":{"line":24,"column":37}},{"start":{"line":24,"column":37},"end":{"line":24,"column":51}},{"start":{"line":24,"column":51},"end":{"line":24,"column":63}},{"start":{"line":24,"column":63},"end":{"line":24,"column":65}}],"line":24},"4":{"loc":{"start":{"line":25,"column":21},"end":{"line":25,"column":78}},"type":"binary-expr","locations":[{"start":{"line":25,"column":21},"end":{"line":25,"column":35}},{"start":{"line":25,"column":35},"end":{"line":25,"column":47}},{"start":{"line":25,"column":47},"end":{"line":25,"column":59}},{"start":{"line":25,"column":59},"end":{"line":25,"column":76}},{"start":{"line":25,"column":76},"end":{"line":25,"column":78}}],"line":25},"5":{"loc":{"start":{"line":26,"column":21},"end":{"line":26,"column":77}},"type":"binary-expr","locations":[{"start":{"line":26,"column":21},"end":{"line":26,"column":33}},{"start":{"line":26,"column":33},"end":{"line":26,"column":45}},{"start":{"line":26,"column":45},"end":{"line":26,"column":58}},{"start":{"line":26,"column":58},"end":{"line":26,"column":75}},{"start":{"line":26,"column":75},"end":{"line":26,"column":77}}],"line":26},"6":{"loc":{"start":{"line":27,"column":25},"end":{"line":27,"column":87}},"type":"binary-expr","locations":[{"start":{"line":27,"column":25},"end":{"line":27,"column":41}},{"start":{"line":27,"column":41},"end":{"line":27,"column":57}},{"start":{"line":27,"column":57},"end":{"line":27,"column":71}},{"start":{"line":27,"column":71},"end":{"line":27,"column":85}},{"start":{"line":27,"column":85},"end":{"line":27,"column":87}}],"line":27},"7":{"loc":{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},{"start":{"line":34,"column":11},"end":{"line":38,"column":null}}],"line":32},"8":{"loc":{"start":{"line":32,"column":8},"end":{"line":32,"column":47}},"type":"binary-expr","locations":[{"start":{"line":32,"column":8},"end":{"line":32,"column":35}},{"start":{"line":32,"column":35},"end":{"line":32,"column":47}}],"line":32},"9":{"loc":{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":34},"10":{"loc":{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"11":{"loc":{"start":{"line":36,"column":12},"end":{"line":36,"column":53}},"type":"binary-expr","locations":[{"start":{"line":36,"column":12},"end":{"line":36,"column":40}},{"start":{"line":36,"column":40},"end":{"line":36,"column":53}}],"line":36},"12":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"type":"cond-expr","locations":[{"start":{"line":43,"column":16},"end":{"line":43,"column":28}},{"start":{"line":43,"column":28},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":14,"7":14,"8":84,"9":84,"10":6,"11":78,"12":1,"13":2,"14":2,"15":14},"f":{"0":14},"b":{"0":[14,1],"1":[14,2,1,1],"2":[14,12],"3":[14,12,12,12],"4":[14,1,1,1,1],"5":[14,1,1,1,1],"6":[14,2,1,1,1],"7":[6,78],"8":[84,6],"9":[1,77],"10":[2,0],"11":[2,2],"12":[2,12]},"meta":{"lastBranch":13,"lastFunction":1,"lastStatement":16,"seen":{"f:20:16:20:42":0,"s:21:13:21:Infinity":0,"b:21:13:21:20:21:20:21:Infinity":0,"s:23:18:23:Infinity":1,"b:23:25:23:41:23:41:23:57:23:57:23:71:23:71:23:73":1,"s:24:16:24:Infinity":2,"b:24:16:24:77:24:77:24:Infinity":2,"b:24:23:24:37:24:37:24:51:24:51:24:63:24:63:24:65":3,"s:25:14:25:Infinity":3,"b:25:21:25:35:25:35:25:47:25:47:25:59:25:59:25:76:25:76:25:78":4,"s:26:14:26:Infinity":4,"b:26:21:26:33:26:33:26:45:26:45:26:58:26:58:26:75:26:75:26:77":5,"s:27:18:27:Infinity":5,"b:27:25:27:41:27:41:27:57:27:57:27:71:27:71:27:85:27:85:27:87":6,"s:29:28:29:Infinity":6,"s:30:2:39:Infinity":7,"s:31:16:31:Infinity":8,"b:32:4:38:Infinity:34:11:38:Infinity":7,"s:32:4:38:Infinity":9,"b:32:8:32:35:32:35:32:47":8,"s:33:6:33:Infinity":10,"b:34:11:38:Infinity:undefined:undefined:undefined:undefined":9,"s:34:11:38:Infinity":11,"s:35:6:37:Infinity":12,"b:36:8:36:Infinity:undefined:undefined:undefined:undefined":10,"s:36:8:36:Infinity":13,"b:36:12:36:40:36:40:36:53":11,"s:36:53:36:Infinity":14,"s:41:2:49:Infinity":15,"b:43:16:43:28:43:28:43:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/article-block.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/article-block.ts","statementMap":{"0":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"2":{"start":{"line":34,"column":16},"end":{"line":34,"column":null}},"3":{"start":{"line":37,"column":4},"end":{"line":41,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":48,"column":null}},"5":{"start":{"line":50,"column":31},"end":{"line":50,"column":null}},"6":{"start":{"line":52,"column":2},"end":{"line":59,"column":null}}},"fnMap":{"0":{"name":"parseCalendarArticle","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":37}},"loc":{"start":{"line":32,"column":88},"end":{"line":60,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":37,"column":4},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},{"start":{"line":41,"column":4},"end":{"line":41,"column":null}}],"line":37},"2":{"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}},{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},{"start":{"line":48,"column":4},"end":{"line":48,"column":null}}],"line":44}},"s":{"0":11,"1":11,"2":1,"3":10,"4":11,"5":11,"6":11},"f":{"0":11},"b":{"0":[1,10],"1":[10,1,1,0,0],"2":[11,1,1,1,0]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":7,"seen":{"f:32:16:32:37":0,"s:33:18:33:Infinity":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":1,"s:34:16:34:Infinity":2,"s:37:4:41:Infinity":3,"b:37:4:37:Infinity:38:4:38:Infinity:39:4:39:Infinity:40:4:40:Infinity:41:4:41:Infinity":1,"s:44:4:48:Infinity":4,"b:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity:47:4:47:Infinity:48:4:48:Infinity":2,"s:50:31:50:Infinity":5,"s:52:2:59:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/orchestrator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/orchestrator.ts","statementMap":{"0":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"1":{"start":{"line":30,"column":34},"end":{"line":30,"column":57}},"2":{"start":{"line":46,"column":17},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"7":{"start":{"line":51,"column":18},"end":{"line":51,"column":null}},"8":{"start":{"line":52,"column":20},"end":{"line":52,"column":null}},"9":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"10":{"start":{"line":57,"column":2},"end":{"line":91,"column":null}},"11":{"start":{"line":57,"column":21},"end":{"line":57,"column":24}},"12":{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},"13":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"14":{"start":{"line":60,"column":6},"end":{"line":60,"column":null}},"15":{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},"16":{"start":{"line":64,"column":4},"end":{"line":90,"column":null}},"17":{"start":{"line":65,"column":6},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":72,"column":6},"end":{"line":81,"column":null}},"22":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"23":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"24":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"25":{"start":{"line":86,"column":6},"end":{"line":88,"column":null}},"26":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"27":{"start":{"line":89,"column":66},"end":{"line":89,"column":null}},"28":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"29":{"start":{"line":95,"column":2},"end":{"line":113,"column":null}},"30":{"start":{"line":96,"column":19},"end":{"line":96,"column":null}},"31":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"32":{"start":{"line":99,"column":4},"end":{"line":109,"column":null}},"33":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"34":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"35":{"start":{"line":115,"column":2},"end":{"line":126,"column":null}}},"fnMap":{"0":{"name":"defaultSleep","decl":{"start":{"line":29,"column":9},"end":{"line":29,"column":22}},"loc":{"start":{"line":29,"column":49},"end":{"line":31,"column":null}},"line":29},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":13},"end":{"line":30,"column":22}},"loc":{"start":{"line":30,"column":34},"end":{"line":30,"column":57}},"line":30},"2":{"name":"fetchCalendarWithFallback","decl":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"loc":{"start":{"line":45,"column":32},"end":{"line":127,"column":null}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"default-arg","locations":[{"start":{"line":44,"column":32},"end":{"line":44,"column":null}}],"line":44},"1":{"loc":{"start":{"line":46,"column":17},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":17},"end":{"line":46,"column":34}},{"start":{"line":46,"column":34},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":21},"end":{"line":47,"column":42}},{"start":{"line":47,"column":42},"end":{"line":47,"column":null}}],"line":47},"3":{"loc":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":18},"end":{"line":48,"column":36}},{"start":{"line":48,"column":36},"end":{"line":48,"column":null}}],"line":48},"4":{"loc":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":42}},{"start":{"line":49,"column":42},"end":{"line":49,"column":null}}],"line":49},"5":{"loc":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":18},"end":{"line":50,"column":36}},{"start":{"line":50,"column":36},"end":{"line":50,"column":null}}],"line":50},"6":{"loc":{"start":{"line":51,"column":18},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":18},"end":{"line":51,"column":36}},{"start":{"line":51,"column":36},"end":{"line":51,"column":null}}],"line":51},"7":{"loc":{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":58},"8":{"loc":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":41},"end":{"line":83,"column":55}},{"start":{"line":83,"column":55},"end":{"line":83,"column":null}}],"line":83},"9":{"loc":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":53},"end":{"line":85,"column":64}},{"start":{"line":85,"column":64},"end":{"line":85,"column":null}}],"line":85},"10":{"loc":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"11":{"loc":{"start":{"line":89,"column":10},"end":{"line":89,"column":66}},"type":"binary-expr","locations":[{"start":{"line":89,"column":10},"end":{"line":89,"column":45}},{"start":{"line":89,"column":45},"end":{"line":89,"column":66}}],"line":89},"12":{"loc":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":43},"end":{"line":111,"column":57}},{"start":{"line":111,"column":57},"end":{"line":111,"column":null}}],"line":111}},"s":{"0":0,"1":0,"2":9,"3":9,"4":9,"5":9,"6":9,"7":9,"8":9,"9":9,"10":9,"11":9,"12":12,"13":3,"14":3,"15":3,"16":12,"17":12,"18":12,"19":4,"20":4,"21":4,"22":8,"23":8,"24":8,"25":8,"26":8,"27":3,"28":5,"29":5,"30":5,"31":4,"32":4,"33":1,"34":1,"35":1},"f":{"0":0,"1":0,"2":9},"b":{"0":[9],"1":[9,0],"2":[9,0],"3":[9,0],"4":[9,0],"5":[9,0],"6":[9,0],"7":[3,9],"8":[8,0],"9":[8,0],"10":[3,5],"11":[8,8],"12":[1,0]},"meta":{"lastBranch":13,"lastFunction":3,"lastStatement":36,"seen":{"f:29:9:29:22":0,"s:30:2:30:Infinity":0,"f:30:13:30:22":1,"s:30:34:30:57":1,"f:41:22:41:Infinity":2,"b:44:32:44:Infinity":0,"s:46:17:46:Infinity":2,"b:46:17:46:34:46:34:46:Infinity":1,"s:47:21:47:Infinity":3,"b:47:21:47:42:47:42:47:Infinity":2,"s:48:18:48:Infinity":4,"b:48:18:48:36:48:36:48:Infinity":3,"s:49:21:49:Infinity":5,"b:49:21:49:42:49:42:49:Infinity":4,"s:50:18:50:Infinity":6,"b:50:18:50:36:50:36:50:Infinity":5,"s:51:18:51:Infinity":7,"b:51:18:51:36:51:36:51:Infinity":6,"s:52:20:52:Infinity":8,"s:54:19:54:Infinity":9,"s:57:2:91:Infinity":10,"s:57:21:57:24":11,"b:58:4:62:Infinity:undefined:undefined:undefined:undefined":7,"s:58:4:62:Infinity":12,"s:59:20:59:Infinity":13,"s:60:6:60:Infinity":14,"s:61:6:61:Infinity":15,"s:64:4:90:Infinity":16,"s:65:6:67:Infinity":17,"s:68:18:68:Infinity":18,"s:69:21:69:Infinity":19,"s:70:6:70:Infinity":20,"s:72:6:81:Infinity":21,"s:83:18:83:Infinity":22,"b:83:41:83:55:83:55:83:Infinity":8,"s:84:6:84:Infinity":23,"s:85:19:85:Infinity":24,"b:85:53:85:64:85:64:85:Infinity":9,"s:86:6:88:Infinity":25,"b:89:6:89:Infinity:undefined:undefined:undefined:undefined":10,"s:89:6:89:Infinity":26,"b:89:10:89:45:89:45:89:66":11,"s:89:66:89:Infinity":27,"s:93:2:93:Infinity":28,"s:95:2:113:Infinity":29,"s:96:19:96:Infinity":30,"s:97:4:97:Infinity":31,"s:99:4:109:Infinity":32,"s:111:4:111:Infinity":33,"b:111:43:111:57:111:57:111:Infinity":12,"s:112:4:112:Infinity":34,"s:115:2:126:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/extractors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/extractors.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"1":{"start":{"line":22,"column":12},"end":{"line":22,"column":null}},"2":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"3":{"start":{"line":28,"column":13},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":12},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"6":{"start":{"line":35,"column":12},"end":{"line":35,"column":null}},"7":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"8":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"9":{"start":{"line":45,"column":13},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":12},"end":{"line":49,"column":null}},"11":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"12":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"13":{"start":{"line":62,"column":23},"end":{"line":62,"column":null}},"14":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"15":{"start":{"line":65,"column":28},"end":{"line":65,"column":null}},"16":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"17":{"start":{"line":67,"column":2},"end":{"line":72,"column":null}},"18":{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"22":{"start":{"line":79,"column":12},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"24":{"start":{"line":85,"column":2},"end":{"line":90,"column":null}},"25":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"26":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"27":{"start":{"line":106,"column":2},"end":{"line":110,"column":null}}},"fnMap":{"0":{"name":"escapeRegex","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":28}},"loc":{"start":{"line":16,"column":47},"end":{"line":18,"column":null}},"line":16},"1":{"name":"extractDatetime","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":32}},"loc":{"start":{"line":21,"column":61},"end":{"line":24,"column":null}},"line":21},"2":{"name":"extractDataAttr","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":32}},"loc":{"start":{"line":27,"column":76},"end":{"line":31,"column":null}},"line":27},"3":{"name":"hasCalendarItemClass","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":37}},"loc":{"start":{"line":34,"column":61},"end":{"line":37,"column":null}},"line":34},"4":{"name":"extractSpanText","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":32}},"loc":{"start":{"line":43,"column":75},"end":{"line":51,"column":null}},"line":43},"5":{"name":"extractHeadingAndLinks","decl":{"start":{"line":57,"column":16},"end":{"line":57,"column":39}},"loc":{"start":{"line":60,"column":2},"end":{"line":75,"column":null}},"line":60},"6":{"name":"extractFirstAnchorText","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":39}},"loc":{"start":{"line":78,"column":61},"end":{"line":81,"column":null}},"line":78},"7":{"name":"isRiksdagDocumentHref","decl":{"start":{"line":84,"column":16},"end":{"line":84,"column":38}},"loc":{"start":{"line":84,"column":61},"end":{"line":92,"column":null}},"line":84},"8":{"name":"stripTags","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":26}},"loc":{"start":{"line":95,"column":48},"end":{"line":97,"column":null}},"line":95},"9":{"name":"normalizeOrgCode","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":33}},"loc":{"start":{"line":100,"column":54},"end":{"line":102,"column":null}},"line":100},"10":{"name":"normalizeAkt","decl":{"start":{"line":105,"column":16},"end":{"line":105,"column":29}},"loc":{"start":{"line":105,"column":50},"end":{"line":111,"column":null}},"line":105}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":9},"end":{"line":23,"column":null}},"type":"cond-expr","locations":[{"start":{"line":23,"column":14},"end":{"line":23,"column":30}},{"start":{"line":23,"column":30},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":23,"column":14},"end":{"line":23,"column":30}},"type":"binary-expr","locations":[{"start":{"line":23,"column":14},"end":{"line":23,"column":22}},{"start":{"line":23,"column":22},"end":{"line":23,"column":30}}],"line":23},"2":{"loc":{"start":{"line":30,"column":9},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":29},"end":{"line":30,"column":43}},{"start":{"line":30,"column":43},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":30,"column":9},"end":{"line":30,"column":29}},"type":"binary-expr","locations":[{"start":{"line":30,"column":9},"end":{"line":30,"column":14}},{"start":{"line":30,"column":14},"end":{"line":30,"column":29}}],"line":30},"4":{"loc":{"start":{"line":36,"column":9},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":9},"end":{"line":36,"column":67}},{"start":{"line":36,"column":67},"end":{"line":36,"column":null}}],"line":36},"5":{"loc":{"start":{"line":36,"column":14},"end":{"line":36,"column":24}},"type":"binary-expr","locations":[{"start":{"line":36,"column":14},"end":{"line":36,"column":22}},{"start":{"line":36,"column":22},"end":{"line":36,"column":24}}],"line":36},"6":{"loc":{"start":{"line":50,"column":9},"end":{"line":50,"column":null}},"type":"cond-expr","locations":[{"start":{"line":50,"column":13},"end":{"line":50,"column":52}},{"start":{"line":50,"column":52},"end":{"line":50,"column":null}}],"line":50},"7":{"loc":{"start":{"line":50,"column":13},"end":{"line":50,"column":52}},"type":"binary-expr","locations":[{"start":{"line":50,"column":13},"end":{"line":50,"column":45}},{"start":{"line":50,"column":45},"end":{"line":50,"column":52}}],"line":50},"8":{"loc":{"start":{"line":50,"column":23},"end":{"line":50,"column":33}},"type":"binary-expr","locations":[{"start":{"line":50,"column":23},"end":{"line":50,"column":31}},{"start":{"line":50,"column":31},"end":{"line":50,"column":33}}],"line":50},"9":{"loc":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":34},"end":{"line":63,"column":59}},{"start":{"line":63,"column":59},"end":{"line":63,"column":null}}],"line":63},"10":{"loc":{"start":{"line":63,"column":34},"end":{"line":63,"column":59}},"type":"binary-expr","locations":[{"start":{"line":63,"column":34},"end":{"line":63,"column":53}},{"start":{"line":63,"column":53},"end":{"line":63,"column":59}}],"line":63},"11":{"loc":{"start":{"line":68,"column":18},"end":{"line":68,"column":28}},"type":"binary-expr","locations":[{"start":{"line":68,"column":18},"end":{"line":68,"column":26}},{"start":{"line":68,"column":26},"end":{"line":68,"column":28}}],"line":68},"12":{"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69},"13":{"loc":{"start":{"line":80,"column":9},"end":{"line":80,"column":null}},"type":"cond-expr","locations":[{"start":{"line":80,"column":14},"end":{"line":80,"column":28}},{"start":{"line":80,"column":28},"end":{"line":80,"column":null}}],"line":80},"14":{"loc":{"start":{"line":80,"column":14},"end":{"line":80,"column":28}},"type":"binary-expr","locations":[{"start":{"line":80,"column":14},"end":{"line":80,"column":22}},{"start":{"line":80,"column":22},"end":{"line":80,"column":28}}],"line":80},"15":{"loc":{"start":{"line":86,"column":4},"end":{"line":90,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{"line":90,"column":4},"end":{"line":90,"column":null}}],"line":86}},"s":{"0":35,"1":17,"2":17,"3":28,"4":28,"5":28,"6":12,"7":12,"8":7,"9":7,"10":7,"11":7,"12":12,"13":12,"14":12,"15":12,"16":12,"17":12,"18":5,"19":5,"20":5,"21":12,"22":2,"23":2,"24":7,"25":18,"26":14,"27":12},"f":{"0":35,"1":17,"2":28,"3":12,"4":7,"5":12,"6":2,"7":7,"8":18,"9":14,"10":12},"b":{"0":[13,4],"1":[13,0],"2":[19,9],"3":[28,19],"4":[12,0],"5":[12,0],"6":[6,1],"7":[6,0],"8":[6,0],"9":[10,2],"10":[10,0],"11":[5,0],"12":[5,0],"13":[2,0],"14":[2,0],"15":[7,1,1,1,1]},"meta":{"lastBranch":16,"lastFunction":11,"lastStatement":28,"seen":{"f:16:16:16:28":0,"s:17:2:17:Infinity":0,"f:21:16:21:32":1,"s:22:12:22:Infinity":1,"s:23:2:23:Infinity":2,"b:23:14:23:30:23:30:23:Infinity":0,"b:23:14:23:22:23:22:23:30":1,"f:27:16:27:32":2,"s:28:13:28:Infinity":3,"s:29:12:29:Infinity":4,"s:30:2:30:Infinity":5,"b:30:29:30:43:30:43:30:Infinity":2,"b:30:9:30:14:30:14:30:29":3,"f:34:16:34:37":3,"s:35:12:35:Infinity":6,"s:36:2:36:Infinity":7,"b:36:9:36:67:36:67:36:Infinity":4,"b:36:14:36:22:36:22:36:24":5,"f:43:16:43:32":4,"s:44:15:44:Infinity":8,"s:45:13:48:Infinity":9,"s:49:12:49:Infinity":10,"s:50:2:50:Infinity":11,"b:50:13:50:52:50:52:50:Infinity":6,"b:50:13:50:45:50:45:50:52":7,"b:50:23:50:31:50:31:50:33":8,"f:57:16:57:39":5,"s:61:20:61:Infinity":12,"s:62:23:62:Infinity":13,"s:63:18:63:Infinity":14,"b:63:34:63:59:63:59:63:Infinity":9,"b:63:34:63:53:63:53:63:59":10,"s:65:28:65:Infinity":15,"s:66:17:66:Infinity":16,"s:67:2:72:Infinity":17,"s:68:10:68:Infinity":18,"b:68:18:68:26:68:26:68:28":11,"b:69:4:71:Infinity:undefined:undefined:undefined:undefined":12,"s:69:4:71:Infinity":19,"s:70:6:70:Infinity":20,"s:74:2:74:Infinity":21,"f:78:16:78:39":6,"s:79:12:79:Infinity":22,"s:80:2:80:Infinity":23,"b:80:14:80:28:80:28:80:Infinity":13,"b:80:14:80:22:80:22:80:28":14,"f:84:16:84:38":7,"s:85:2:90:Infinity":24,"b:86:4:86:Infinity:87:4:87:Infinity:88:4:88:Infinity:89:4:89:Infinity:90:4:90:Infinity":15,"f:95:16:95:26":8,"s:96:2:96:Infinity":25,"f:100:16:100:33":9,"s:101:2:101:Infinity":26,"f:105:16:105:29":10,"s:106:2:110:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/list-item.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/list-item.ts","statementMap":{"0":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"2":{"start":{"line":34,"column":16},"end":{"line":34,"column":null}},"3":{"start":{"line":37,"column":4},"end":{"line":40,"column":null}},"4":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"5":{"start":{"line":48,"column":31},"end":{"line":48,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"parseCalendarListItem","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":38}},"loc":{"start":{"line":32,"column":89},"end":{"line":58,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":37,"column":4},"end":{"line":40,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{"line":40,"column":4},"end":{"line":40,"column":null}}],"line":37},"2":{"loc":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}}],"line":43}},"s":{"0":3,"1":3,"2":1,"3":2,"4":3,"5":3,"6":3},"f":{"0":3},"b":{"0":[1,2],"1":[2,2,0,0],"2":[3,2,0,0]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":7,"seen":{"f:32:16:32:38":0,"s:33:18:33:Infinity":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":1,"s:34:16:34:Infinity":2,"s:37:4:40:Infinity":3,"b:37:4:37:Infinity:38:4:38:Infinity:39:4:39:Infinity:40:4:40:Infinity":1,"s:43:4:46:Infinity":4,"b:43:4:43:Infinity:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity":2,"s:48:31:48:Infinity":5,"s:50:2:57:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/parse.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/parse.ts","statementMap":{"0":{"start":{"line":28,"column":34},"end":{"line":28,"column":null}},"1":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":37,"column":null}},"3":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"5":{"start":{"line":33,"column":38},"end":{"line":33,"column":null}},"6":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"7":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"8":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"9":{"start":{"line":36,"column":15},"end":{"line":36,"column":null}},"10":{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},"11":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"12":{"start":{"line":41,"column":4},"end":{"line":46,"column":null}},"13":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"14":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"15":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"16":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"17":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"18":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"19":{"start":{"line":52,"column":36},"end":{"line":52,"column":null}},"20":{"start":{"line":64,"column":14},"end":{"line":66,"column":null}},"21":{"start":{"line":68,"column":21},"end":{"line":68,"column":null}},"22":{"start":{"line":69,"column":14},"end":{"line":69,"column":null}},"23":{"start":{"line":69,"column":31},"end":{"line":69,"column":51}},"24":{"start":{"line":72,"column":2},"end":{"line":94,"column":null}},"25":{"start":{"line":73,"column":21},"end":{"line":80,"column":null}},"26":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"27":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"28":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"29":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"30":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"31":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"32":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}}},"fnMap":{"0":{"name":"parseRiksdagKalendariumHtml","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":44}},"loc":{"start":{"line":27,"column":75},"end":{"line":50,"column":null}},"line":27},"1":{"name":"fetchWebCalendar","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":null}},"loc":{"start":{"line":63,"column":28},"end":{"line":97,"column":null}},"line":63},"2":{"name":"(anonymous_2)","decl":{"start":{"line":69,"column":14},"end":{"line":69,"column":31}},"loc":{"start":{"line":69,"column":31},"end":{"line":69,"column":51}},"line":69}},"branchMap":{"0":{"loc":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":18},"end":{"line":32,"column":37}},{"start":{"line":32,"column":37},"end":{"line":32,"column":null}}],"line":32},"1":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":17},"end":{"line":34,"column":36}},{"start":{"line":34,"column":36},"end":{"line":34,"column":null}}],"line":34},"3":{"loc":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"4":{"loc":{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":39},"5":{"loc":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":20},"end":{"line":42,"column":34}},{"start":{"line":42,"column":34},"end":{"line":42,"column":null}}],"line":42},"6":{"loc":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":19},"end":{"line":43,"column":33}},{"start":{"line":43,"column":33},"end":{"line":43,"column":null}}],"line":43},"7":{"loc":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"8":{"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"9":{"loc":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":90,"column":39},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":null}}],"line":90}},"s":{"0":11,"1":11,"2":11,"3":9,"4":9,"5":1,"6":8,"7":9,"8":9,"9":8,"10":11,"11":4,"12":4,"13":1,"14":1,"15":1,"16":1,"17":1,"18":11,"19":9,"20":8,"21":8,"22":8,"23":0,"24":8,"25":8,"26":6,"27":1,"28":5,"29":3,"30":3,"31":8,"32":5},"f":{"0":11,"1":8,"2":0},"b":{"0":[9,0],"1":[1,8],"2":[8,0],"3":[8,1],"4":[4,7],"5":[1,0],"6":[1,0],"7":[1,0],"8":[1,5],"9":[3,0]},"meta":{"lastBranch":10,"lastFunction":3,"lastStatement":33,"seen":{"f:27:16:27:44":0,"s:28:34:28:Infinity":0,"s:30:20:30:Infinity":1,"s:31:2:37:Infinity":2,"s:32:18:32:Infinity":3,"b:32:18:32:37:32:37:32:Infinity":0,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":1,"s:33:4:33:Infinity":4,"s:33:38:33:Infinity":5,"s:34:17:34:Infinity":6,"b:34:17:34:36:34:36:34:Infinity":2,"s:35:18:35:Infinity":7,"b:36:4:36:Infinity:undefined:undefined:undefined:undefined":3,"s:36:4:36:Infinity":8,"s:36:15:36:Infinity":9,"b:39:2:47:Infinity:undefined:undefined:undefined:undefined":4,"s:39:2:47:Infinity":10,"s:40:17:40:Infinity":11,"s:41:4:46:Infinity":12,"s:42:20:42:Infinity":13,"b:42:20:42:34:42:34:42:Infinity":5,"s:43:19:43:Infinity":14,"b:43:19:43:33:43:33:43:Infinity":6,"s:44:20:44:Infinity":15,"b:45:6:45:Infinity:undefined:undefined:undefined:undefined":7,"s:45:6:45:Infinity":16,"s:45:17:45:Infinity":17,"s:49:2:49:Infinity":18,"s:52:36:52:Infinity":19,"f:59:22:59:Infinity":1,"s:64:14:66:Infinity":20,"s:68:21:68:Infinity":21,"s:69:14:69:Infinity":22,"f:69:14:69:31":2,"s:69:31:69:51":23,"s:72:2:94:Infinity":24,"s:73:21:80:Infinity":25,"b:82:4:86:Infinity:undefined:undefined:undefined:undefined":8,"s:82:4:86:Infinity":26,"s:83:6:85:Infinity":27,"s:88:4:88:Infinity":28,"s:90:16:90:Infinity":29,"b:90:39:90:53:90:53:90:Infinity":9,"s:91:4:91:Infinity":30,"s:93:4:93:Infinity":31,"s:96:2:96:Infinity":32}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-article-types-doc.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-article-types-doc.ts","statementMap":{"0":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":17},"end":{"line":24,"column":null}},"3":{"start":{"line":26,"column":23},"end":{"line":26,"column":null}},"4":{"start":{"line":27,"column":21},"end":{"line":27,"column":null}},"5":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"6":{"start":{"line":34,"column":41},"end":{"line":34,"column":null}},"7":{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},"8":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"9":{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"11":{"start":{"line":42,"column":2},"end":{"line":55,"column":null}},"12":{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},"13":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"14":{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},"15":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"16":{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},"17":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},"19":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"20":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"21":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"22":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"23":{"start":{"line":66,"column":15},"end":{"line":69,"column":null}},"24":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"25":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"26":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"27":{"start":{"line":79,"column":19},"end":{"line":79,"column":null}},"28":{"start":{"line":80,"column":17},"end":{"line":80,"column":null}},"29":{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},"30":{"start":{"line":83,"column":4},"end":{"line":85,"column":null}},"31":{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},"32":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"33":{"start":{"line":91,"column":17},"end":{"line":91,"column":null}},"34":{"start":{"line":92,"column":16},"end":{"line":92,"column":null}},"35":{"start":{"line":94,"column":18},"end":{"line":94,"column":null}},"36":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"37":{"start":{"line":106,"column":19},"end":{"line":106,"column":null}},"38":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"39":{"start":{"line":108,"column":14},"end":{"line":108,"column":null}},"40":{"start":{"line":109,"column":18},"end":{"line":109,"column":null}},"41":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"42":{"start":{"line":114,"column":15},"end":{"line":114,"column":null}},"43":{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},"44":{"start":{"line":116,"column":2},"end":{"line":122,"column":null}},"45":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"46":{"start":{"line":118,"column":4},"end":{"line":118,"column":null}},"47":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"48":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"loadAndValidateRegistry","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":40}},"loc":{"start":{"line":32,"column":84},"end":{"line":57,"column":null}},"line":32},"1":{"name":"renderTable","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":28}},"loc":{"start":{"line":62,"column":72},"end":{"line":72,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":66,"column":21},"end":{"line":66,"column":26}},"loc":{"start":{"line":66,"column":32},"end":{"line":69,"column":3}},"line":66},"3":{"name":"replaceBetweenSentinels","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":40}},"loc":{"start":{"line":78,"column":76},"end":{"line":97,"column":null}},"line":78},"4":{"name":"generate","decl":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"loc":{"start":{"line":105,"column":8},"end":{"line":111,"column":null}},"line":105}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":36},"1":{"loc":{"start":{"line":36,"column":6},"end":{"line":36,"column":78}},"type":"binary-expr","locations":[{"start":{"line":36,"column":6},"end":{"line":36,"column":27}},{"start":{"line":36,"column":27},"end":{"line":36,"column":46}},{"start":{"line":36,"column":46},"end":{"line":36,"column":78}}],"line":36},"2":{"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":39},"3":{"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":43},"4":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":82}},"type":"binary-expr","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":17}},{"start":{"line":43,"column":17},"end":{"line":43,"column":30}},{"start":{"line":43,"column":30},"end":{"line":43,"column":55}},{"start":{"line":43,"column":55},"end":{"line":43,"column":82}}],"line":43},"5":{"loc":{"start":{"line":44,"column":82},"end":{"line":44,"column":102}},"type":"binary-expr","locations":[{"start":{"line":44,"column":82},"end":{"line":44,"column":90}},{"start":{"line":44,"column":90},"end":{"line":44,"column":102}}],"line":44},"6":{"loc":{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"7":{"loc":{"start":{"line":46,"column":8},"end":{"line":46,"column":78}},"type":"binary-expr","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":38}},{"start":{"line":46,"column":38},"end":{"line":46,"column":78}}],"line":46},"8":{"loc":{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":49},"9":{"loc":{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":52},"10":{"loc":{"start":{"line":52,"column":8},"end":{"line":52,"column":46}},"type":"binary-expr","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":27}},{"start":{"line":52,"column":27},"end":{"line":52,"column":46}}],"line":52},"11":{"loc":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":34},"end":{"line":67,"column":54}},{"start":{"line":67,"column":54},"end":{"line":67,"column":null}}],"line":67},"12":{"loc":{"start":{"line":67,"column":59},"end":{"line":67,"column":83}},"type":"binary-expr","locations":[{"start":{"line":67,"column":59},"end":{"line":67,"column":79}},{"start":{"line":67,"column":79},"end":{"line":67,"column":83}}],"line":67},"13":{"loc":{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"14":{"loc":{"start":{"line":82,"column":6},"end":{"line":82,"column":40}},"type":"binary-expr","locations":[{"start":{"line":82,"column":6},"end":{"line":82,"column":25}},{"start":{"line":82,"column":25},"end":{"line":82,"column":40}}],"line":82},"15":{"loc":{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":87},"16":{"loc":{"start":{"line":103,"column":2},"end":{"line":103,"column":null}},"type":"default-arg","locations":[{"start":{"line":103,"column":25},"end":{"line":103,"column":null}}],"line":103},"17":{"loc":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"type":"default-arg","locations":[{"start":{"line":104,"column":20},"end":{"line":104,"column":null}}],"line":104},"18":{"loc":{"start":{"line":114,"column":15},"end":{"line":114,"column":null}},"type":"binary-expr","locations":[{"start":{"line":114,"column":15},"end":{"line":114,"column":34}},{"start":{"line":114,"column":34},"end":{"line":114,"column":null}}],"line":114},"19":{"loc":{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":115}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":11,"6":11,"7":11,"8":1,"9":10,"10":1,"11":9,"12":69,"13":1,"14":68,"15":1,"16":67,"17":1,"18":66,"19":1,"20":5,"21":4,"22":4,"23":4,"24":52,"25":52,"26":4,"27":6,"28":6,"29":6,"30":1,"31":5,"32":1,"33":4,"34":4,"35":4,"36":4,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":0,"45":0,"46":0,"47":0,"48":0},"f":{"0":11,"1":4,"2":52,"3":6,"4":1},"b":{"0":[1,10],"1":[11,10,10],"2":[1,9],"3":[1,68],"4":[69,69,69,68],"5":[1,0],"6":[1,67],"7":[68,67],"8":[1,66],"9":[1,65],"10":[66,61],"11":[4,48],"12":[48,0],"13":[1,5],"14":[6,5],"15":[1,4],"16":[1],"17":[1],"18":[1,1],"19":[0,1]},"meta":{"lastBranch":20,"lastFunction":5,"lastStatement":49,"seen":{"s:22:19:22:Infinity":0,"s:23:18:23:Infinity":1,"s:24:17:24:Infinity":2,"s:26:23:26:Infinity":3,"s:27:21:27:Infinity":4,"f:32:16:32:40":0,"s:33:14:33:Infinity":5,"s:34:41:34:Infinity":6,"b:36:2:38:Infinity:undefined:undefined:undefined:undefined":0,"s:36:2:38:Infinity":7,"b:36:6:36:27:36:27:36:46:36:46:36:78":1,"s:37:4:37:Infinity":8,"b:39:2:41:Infinity:undefined:undefined:undefined:undefined":2,"s:39:2:41:Infinity":9,"s:40:4:40:Infinity":10,"s:42:2:55:Infinity":11,"b:43:4:45:Infinity:undefined:undefined:undefined:undefined":3,"s:43:4:45:Infinity":12,"b:43:8:43:17:43:17:43:30:43:30:43:55:43:55:43:82":4,"s:44:6:44:Infinity":13,"b:44:82:44:90:44:90:44:102":5,"b:46:4:48:Infinity:undefined:undefined:undefined:undefined":6,"s:46:4:48:Infinity":14,"b:46:8:46:38:46:38:46:78":7,"s:47:6:47:Infinity":15,"b:49:4:51:Infinity:undefined:undefined:undefined:undefined":8,"s:49:4:51:Infinity":16,"s:50:6:50:Infinity":17,"b:52:4:54:Infinity:undefined:undefined:undefined:undefined":9,"s:52:4:54:Infinity":18,"b:52:8:52:27:52:27:52:46":10,"s:53:6:53:Infinity":19,"s:56:2:56:Infinity":20,"f:62:16:62:28":1,"s:63:17:63:Infinity":21,"s:64:20:64:Infinity":22,"s:66:15:69:Infinity":23,"f:66:21:66:26":2,"s:67:17:67:Infinity":24,"b:67:34:67:54:67:54:67:Infinity":11,"b:67:59:67:79:67:79:67:83":12,"s:68:4:68:Infinity":25,"s:71:2:71:Infinity":26,"f:78:16:78:40":3,"s:79:19:79:Infinity":27,"s:80:17:80:Infinity":28,"b:82:2:86:Infinity:undefined:undefined:undefined:undefined":13,"s:82:2:86:Infinity":29,"b:82:6:82:25:82:25:82:40":14,"s:83:4:85:Infinity":30,"b:87:2:89:Infinity:undefined:undefined:undefined:undefined":15,"s:87:2:89:Infinity":31,"s:88:4:88:Infinity":32,"s:91:17:91:Infinity":33,"s:92:16:92:Infinity":34,"s:94:18:94:Infinity":35,"s:96:2:96:Infinity":36,"f:102:16:102:Infinity":4,"b:103:25:103:Infinity":16,"b:104:20:104:Infinity":17,"s:106:19:106:Infinity":37,"s:107:16:107:Infinity":38,"s:108:14:108:Infinity":39,"s:109:18:109:Infinity":40,"s:110:2:110:Infinity":41,"s:114:15:114:Infinity":42,"b:114:15:114:34:114:34:114:Infinity":18,"b:115:0:123:Infinity:undefined:undefined:undefined:undefined":19,"s:115:0:123:Infinity":43,"s:116:2:122:Infinity":44,"s:117:4:117:Infinity":45,"s:118:4:118:Infinity":46,"s:120:4:120:Infinity":47,"s:121:4:121:Infinity":48}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-statskontoret.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-statskontoret.ts","statementMap":{"0":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"1":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"2":{"start":{"line":53,"column":28},"end":{"line":53,"column":null}},"3":{"start":{"line":56,"column":40},"end":{"line":61,"column":null}},"4":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"5":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"6":{"start":{"line":109,"column":2},"end":{"line":114,"column":null}},"7":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"8":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"9":{"start":{"line":113,"column":4},"end":{"line":113,"column":null}},"10":{"start":{"line":118,"column":14},"end":{"line":118,"column":null}},"11":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"12":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"13":{"start":{"line":124,"column":14},"end":{"line":124,"column":null}},"14":{"start":{"line":125,"column":2},"end":{"line":125,"column":null}},"15":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"16":{"start":{"line":157,"column":17},"end":{"line":157,"column":null}},"17":{"start":{"line":158,"column":19},"end":{"line":158,"column":null}},"18":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"19":{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},"20":{"start":{"line":162,"column":23},"end":{"line":162,"column":null}},"21":{"start":{"line":163,"column":4},"end":{"line":172,"column":null}},"22":{"start":{"line":175,"column":17},"end":{"line":175,"column":null}},"23":{"start":{"line":179,"column":2},"end":{"line":203,"column":null}},"24":{"start":{"line":180,"column":4},"end":{"line":180,"column":null}},"25":{"start":{"line":181,"column":4},"end":{"line":181,"column":null}},"26":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"27":{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},"28":{"start":{"line":185,"column":25},"end":{"line":185,"column":null}},"29":{"start":{"line":186,"column":6},"end":{"line":195,"column":null}},"30":{"start":{"line":197,"column":19},"end":{"line":197,"column":null}},"31":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"32":{"start":{"line":205,"column":2},"end":{"line":214,"column":null}},"33":{"start":{"line":229,"column":78},"end":{"line":229,"column":null}},"34":{"start":{"line":230,"column":19},"end":{"line":230,"column":null}},"35":{"start":{"line":231,"column":17},"end":{"line":231,"column":null}},"36":{"start":{"line":232,"column":2},"end":{"line":232,"column":null}},"37":{"start":{"line":240,"column":2},"end":{"line":240,"column":null}},"38":{"start":{"line":240,"column":42},"end":{"line":240,"column":47}}},"fnMap":{"0":{"name":"cacheDir","decl":{"start":{"line":100,"column":9},"end":{"line":100,"column":18}},"loc":{"start":{"line":100,"column":80},"end":{"line":102,"column":null}},"line":100},"1":{"name":"cacheFilePath","decl":{"start":{"line":104,"column":9},"end":{"line":104,"column":23}},"loc":{"start":{"line":104,"column":85},"end":{"line":106,"column":null}},"line":104},"2":{"name":"readCacheEntry","decl":{"start":{"line":108,"column":9},"end":{"line":108,"column":24}},"loc":{"start":{"line":108,"column":66},"end":{"line":115,"column":null}},"line":108},"3":{"name":"writeCacheEntry","decl":{"start":{"line":117,"column":9},"end":{"line":117,"column":25}},"loc":{"start":{"line":117,"column":68},"end":{"line":121,"column":null}},"line":117},"4":{"name":"isCacheFresh","decl":{"start":{"line":123,"column":9},"end":{"line":123,"column":22}},"loc":{"start":{"line":123,"column":65},"end":{"line":126,"column":null}},"line":123},"5":{"name":"fetchStatskontoretCached","decl":{"start":{"line":147,"column":22},"end":{"line":147,"column":null}},"loc":{"start":{"line":150,"column":39},"end":{"line":215,"column":null}},"line":150},"6":{"name":"isStatskontoretCacheFresh","decl":{"start":{"line":225,"column":16},"end":{"line":225,"column":null}},"loc":{"start":{"line":228,"column":11},"end":{"line":233,"column":null}},"line":228},"7":{"name":"statskontoretSourceKeys","decl":{"start":{"line":239,"column":16},"end":{"line":239,"column":77}},"loc":{"start":{"line":239,"column":77},"end":{"line":241,"column":null}},"line":239},"8":{"name":"(anonymous_8)","decl":{"start":{"line":240,"column":31},"end":{"line":240,"column":36}},"loc":{"start":{"line":240,"column":42},"end":{"line":240,"column":47}},"line":240}},"branchMap":{"0":{"loc":{"start":{"line":149,"column":2},"end":{"line":149,"column":null}},"type":"default-arg","locations":[{"start":{"line":149,"column":45},"end":{"line":149,"column":null}}],"line":149},"1":{"loc":{"start":{"line":152,"column":4},"end":{"line":152,"column":null}},"type":"default-arg","locations":[{"start":{"line":152,"column":17},"end":{"line":152,"column":null}}],"line":152},"2":{"loc":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"type":"default-arg","locations":[{"start":{"line":153,"column":16},"end":{"line":153,"column":null}}],"line":153},"3":{"loc":{"start":{"line":154,"column":4},"end":{"line":154,"column":null}},"type":"default-arg","locations":[{"start":{"line":154,"column":19},"end":{"line":154,"column":null}}],"line":154},"4":{"loc":{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},{"start":{},"end":{}}],"line":161},"5":{"loc":{"start":{"line":161,"column":6},"end":{"line":161,"column":74}},"type":"binary-expr","locations":[{"start":{"line":161,"column":6},"end":{"line":161,"column":30}},{"start":{"line":161,"column":30},"end":{"line":161,"column":74}}],"line":161},"6":{"loc":{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":184},"7":{"loc":{"start":{"line":197,"column":19},"end":{"line":197,"column":null}},"type":"cond-expr","locations":[{"start":{"line":197,"column":44},"end":{"line":197,"column":60}},{"start":{"line":197,"column":60},"end":{"line":197,"column":null}}],"line":197},"8":{"loc":{"start":{"line":227,"column":2},"end":{"line":227,"column":null}},"type":"default-arg","locations":[{"start":{"line":227,"column":79},"end":{"line":227,"column":null}}],"line":227},"9":{"loc":{"start":{"line":229,"column":10},"end":{"line":229,"column":37}},"type":"default-arg","locations":[{"start":{"line":229,"column":23},"end":{"line":229,"column":37}}],"line":229},"10":{"loc":{"start":{"line":229,"column":37},"end":{"line":229,"column":78}},"type":"default-arg","locations":[{"start":{"line":229,"column":49},"end":{"line":229,"column":78}}],"line":229},"11":{"loc":{"start":{"line":232,"column":9},"end":{"line":232,"column":null}},"type":"binary-expr","locations":[{"start":{"line":232,"column":9},"end":{"line":232,"column":33}},{"start":{"line":232,"column":33},"end":{"line":232,"column":null}}],"line":232}},"s":{"0":1,"1":1,"2":1,"3":1,"4":6,"5":6,"6":6,"7":6,"8":6,"9":2,"10":0,"11":0,"12":0,"13":4,"14":4,"15":3,"16":3,"17":3,"18":3,"19":3,"20":1,"21":1,"22":2,"23":2,"24":2,"25":0,"26":0,"27":2,"28":1,"29":1,"30":1,"31":2,"32":0,"33":3,"34":3,"35":3,"36":3,"37":1,"38":4},"f":{"0":6,"1":6,"2":6,"3":0,"4":4,"5":3,"6":3,"7":1,"8":4},"b":{"0":[3],"1":[3],"2":[3],"3":[3],"4":[1,2],"5":[3,2],"6":[1,1],"7":[1,0],"8":[3],"9":[3],"10":[3],"11":[3,2]},"meta":{"lastBranch":12,"lastFunction":9,"lastStatement":39,"seen":{"s:49:19:49:Infinity":0,"s:50:18:50:Infinity":1,"s:53:28:53:Infinity":2,"s:56:40:61:Infinity":3,"f:100:9:100:18":0,"s:101:2:101:Infinity":4,"f:104:9:104:23":1,"s:105:2:105:Infinity":5,"f:108:9:108:24":2,"s:109:2:114:Infinity":6,"s:110:16:110:Infinity":7,"s:111:4:111:Infinity":8,"s:113:4:113:Infinity":9,"f:117:9:117:25":3,"s:118:14:118:Infinity":10,"s:119:2:119:Infinity":11,"s:120:2:120:Infinity":12,"f:123:9:123:22":4,"s:124:14:124:Infinity":13,"s:125:2:125:Infinity":14,"f:147:22:147:Infinity":5,"b:149:45:149:Infinity":0,"s:155:6:155:Infinity":15,"b:152:17:152:Infinity":1,"b:153:16:153:Infinity":2,"b:154:19:154:Infinity":3,"s:157:17:157:Infinity":16,"s:158:19:158:Infinity":17,"s:160:17:160:Infinity":18,"b:161:2:173:Infinity:undefined:undefined:undefined:undefined":4,"s:161:2:173:Infinity":19,"b:161:6:161:30:161:30:161:74":5,"s:162:23:162:Infinity":20,"s:163:4:172:Infinity":21,"s:175:17:175:Infinity":22,"s:179:2:203:Infinity":23,"s:180:4:180:Infinity":24,"s:181:4:181:Infinity":25,"s:182:4:182:Infinity":26,"b:184:4:196:Infinity:undefined:undefined:undefined:undefined":6,"s:184:4:196:Infinity":27,"s:185:25:185:Infinity":28,"s:186:6:195:Infinity":29,"s:197:19:197:Infinity":30,"b:197:44:197:60:197:60:197:Infinity":7,"s:198:4:202:Infinity":31,"s:205:2:214:Infinity":32,"f:225:16:225:Infinity":6,"b:227:79:227:Infinity":8,"s:229:78:229:Infinity":33,"b:229:23:229:37":9,"b:229:49:229:78":10,"s:230:19:230:Infinity":34,"s:231:17:231:Infinity":35,"s:232:2:232:Infinity":36,"b:232:9:232:33:232:33:232:Infinity":11,"f:239:16:239:77":7,"s:240:2:240:Infinity":37,"f:240:31:240:36":8,"s:240:42:240:47":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/language-flags.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/language-flags.ts","statementMap":{"0":{"start":{"line":11,"column":54},"end":{"line":15,"column":null}},"1":{"start":{"line":18,"column":65},"end":{"line":22,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":6,"1":6},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:11:54:15:Infinity":0,"s:18:65:22:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/article-merge.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/article-merge.ts","statementMap":{"0":{"start":{"line":23,"column":52},"end":{"line":23,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":35,"column":null}},"2":{"start":{"line":26,"column":4},"end":{"line":34,"column":null}},"3":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},"5":{"start":{"line":29,"column":8},"end":{"line":29,"column":null}},"6":{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},"7":{"start":{"line":32,"column":8},"end":{"line":32,"column":null}},"8":{"start":{"line":37,"column":52},"end":{"line":37,"column":null}},"9":{"start":{"line":39,"column":2},"end":{"line":46,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"11":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"12":{"start":{"line":42,"column":33},"end":{"line":42,"column":null}},"13":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"14":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"buildSlugToLanguagesMap","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":40}},"loc":{"start":{"line":22,"column":121},"end":{"line":49,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":33},"end":{"line":25,"column":42}},"loc":{"start":{"line":25,"column":63},"end":{"line":35,"column":3}},"line":25},"2":{"name":"(anonymous_2)","decl":{"start":{"line":26,"column":13},"end":{"line":26,"column":22}},"loc":{"start":{"line":26,"column":34},"end":{"line":34,"column":5}},"line":26},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":33},"end":{"line":39,"column":42}},"loc":{"start":{"line":39,"column":63},"end":{"line":46,"column":3}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":40,"column":13},"end":{"line":40,"column":22}},"loc":{"start":{"line":40,"column":34},"end":{"line":45,"column":5}},"line":40}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":31},"2":{"loc":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":41},"3":{"loc":{"start":{"line":43,"column":40},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":40},"end":{"line":43,"column":69}},{"start":{"line":43,"column":69},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":2,"1":2,"2":28,"3":12170,"4":12170,"5":1048,"6":12170,"7":12170,"8":2,"9":2,"10":28,"11":12170,"12":12170,"13":12170,"14":2},"f":{"0":2,"1":28,"2":12170,"3":28,"4":12170},"b":{"0":[1048,11122],"1":[12170,0],"2":[12170,0],"3":[12170,0]},"meta":{"lastBranch":4,"lastFunction":5,"lastStatement":15,"seen":{"f:22:16:22:40":0,"s:23:52:23:Infinity":0,"s:25:2:35:Infinity":1,"f:25:33:25:42":1,"s:26:4:34:Infinity":2,"f:26:13:26:22":2,"s:27:31:27:Infinity":3,"b:28:6:30:Infinity:undefined:undefined:undefined:undefined":0,"s:28:6:30:Infinity":4,"s:29:8:29:Infinity":5,"b:31:6:33:Infinity:undefined:undefined:undefined:undefined":1,"s:31:6:33:Infinity":6,"s:32:8:32:Infinity":7,"s:37:52:37:Infinity":8,"s:39:2:46:Infinity":9,"f:39:33:39:42":3,"s:40:4:45:Infinity":10,"f:40:13:40:22":4,"b:41:6:44:Infinity:undefined:undefined:undefined:undefined":2,"s:41:6:44:Infinity":11,"s:42:33:42:Infinity":12,"s:43:8:43:Infinity":13,"b:43:40:43:69:43:69:43:Infinity":3,"s:48:2:48:Infinity":14}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/languages.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/languages.ts","statementMap":{"0":{"start":{"line":19,"column":63},"end":{"line":300,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":8},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:19:63:300:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/frontmatter.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/frontmatter.ts","statementMap":{"0":{"start":{"line":31,"column":2},"end":{"line":39,"column":null}},"1":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"3":{"start":{"line":33,"column":22},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":21},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"6":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"9":{"start":{"line":67,"column":21},"end":{"line":69,"column":null}},"10":{"start":{"line":68,"column":10},"end":{"line":68,"column":32}},"11":{"start":{"line":69,"column":19},"end":{"line":69,"column":31}},"12":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"13":{"start":{"line":70,"column":31},"end":{"line":70,"column":null}},"14":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"15":{"start":{"line":71,"column":28},"end":{"line":71,"column":47}},"16":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"17":{"start":{"line":81,"column":29},"end":{"line":81,"column":null}},"18":{"start":{"line":82,"column":52},"end":{"line":82,"column":null}},"19":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"20":{"start":{"line":83,"column":24},"end":{"line":83,"column":null}},"21":{"start":{"line":85,"column":29},"end":{"line":85,"column":null}},"22":{"start":{"line":86,"column":52},"end":{"line":86,"column":null}},"23":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"24":{"start":{"line":87,"column":24},"end":{"line":87,"column":null}},"25":{"start":{"line":89,"column":32},"end":{"line":89,"column":null}},"26":{"start":{"line":90,"column":55},"end":{"line":90,"column":null}},"27":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"28":{"start":{"line":91,"column":27},"end":{"line":91,"column":null}},"29":{"start":{"line":93,"column":32},"end":{"line":93,"column":null}},"30":{"start":{"line":94,"column":55},"end":{"line":94,"column":null}},"31":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"32":{"start":{"line":95,"column":27},"end":{"line":95,"column":null}},"33":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}},"34":{"start":{"line":104,"column":41},"end":{"line":104,"column":null}},"35":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"36":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"37":{"start":{"line":112,"column":16},"end":{"line":112,"column":null}},"38":{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},"39":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"40":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"41":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"42":{"start":{"line":122,"column":26},"end":{"line":122,"column":null}},"43":{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},"44":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"45":{"start":{"line":127,"column":2},"end":{"line":127,"column":null}},"46":{"start":{"line":134,"column":2},"end":{"line":149,"column":null}},"47":{"start":{"line":135,"column":49},"end":{"line":135,"column":null}},"48":{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},"49":{"start":{"line":136,"column":22},"end":{"line":136,"column":null}},"50":{"start":{"line":138,"column":31},"end":{"line":138,"column":null}},"51":{"start":{"line":139,"column":49},"end":{"line":139,"column":null}},"52":{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},"53":{"start":{"line":142,"column":30},"end":{"line":142,"column":null}},"54":{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},"55":{"start":{"line":146,"column":4},"end":{"line":146,"column":null}},"56":{"start":{"line":148,"column":4},"end":{"line":148,"column":null}},"57":{"start":{"line":156,"column":41},"end":{"line":156,"column":null}},"58":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"59":{"start":{"line":164,"column":2},"end":{"line":210,"column":null}},"60":{"start":{"line":165,"column":28},"end":{"line":165,"column":null}},"61":{"start":{"line":166,"column":29},"end":{"line":166,"column":null}},"62":{"start":{"line":168,"column":47},"end":{"line":168,"column":null}},"63":{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},"64":{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},"65":{"start":{"line":171,"column":6},"end":{"line":171,"column":null}},"66":{"start":{"line":174,"column":25},"end":{"line":174,"column":null}},"67":{"start":{"line":177,"column":6},"end":{"line":179,"column":null}},"68":{"start":{"line":180,"column":24},"end":{"line":184,"column":null}},"69":{"start":{"line":185,"column":33},"end":{"line":185,"column":null}},"70":{"start":{"line":186,"column":19},"end":{"line":186,"column":null}},"71":{"start":{"line":187,"column":24},"end":{"line":187,"column":null}},"72":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"73":{"start":{"line":189,"column":42},"end":{"line":204,"column":null}},"74":{"start":{"line":206,"column":4},"end":{"line":206,"column":null}},"75":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"76":{"start":{"line":209,"column":4},"end":{"line":209,"column":null}}},"fnMap":{"0":{"name":"extractDescriptionFromJSONLD","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":45}},"loc":{"start":{"line":30,"column":74},"end":{"line":40,"column":null}},"line":30},"1":{"name":"stripBrandSuffix","decl":{"start":{"line":49,"column":16},"end":{"line":49,"column":33}},"loc":{"start":{"line":49,"column":56},"end":{"line":51,"column":null}},"line":49},"2":{"name":"chooseBestDescription","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":null}},"loc":{"start":{"line":66,"column":10},"end":{"line":73,"column":null}},"line":66},"3":{"name":"(anonymous_3)","decl":{"start":{"line":68,"column":5},"end":{"line":68,"column":10}},"loc":{"start":{"line":68,"column":10},"end":{"line":68,"column":32}},"line":68},"4":{"name":"(anonymous_4)","decl":{"start":{"line":69,"column":5},"end":{"line":69,"column":13}},"loc":{"start":{"line":69,"column":19},"end":{"line":69,"column":31}},"line":69},"5":{"name":"(anonymous_5)","decl":{"start":{"line":71,"column":13},"end":{"line":71,"column":19}},"loc":{"start":{"line":71,"column":28},"end":{"line":71,"column":47}},"line":71},"6":{"name":"extractMetaContent","decl":{"start":{"line":80,"column":16},"end":{"line":80,"column":35}},"loc":{"start":{"line":80,"column":82},"end":{"line":98,"column":null}},"line":80},"7":{"name":"extractTitle","decl":{"start":{"line":103,"column":16},"end":{"line":103,"column":29}},"loc":{"start":{"line":103,"column":58},"end":{"line":106,"column":null}},"line":103},"8":{"name":"normalizeDateString","decl":{"start":{"line":111,"column":16},"end":{"line":111,"column":36}},"loc":{"start":{"line":111,"column":68},"end":{"line":128,"column":null}},"line":111},"9":{"name":"extractDateFromJSONLD","decl":{"start":{"line":133,"column":16},"end":{"line":133,"column":38}},"loc":{"start":{"line":133,"column":67},"end":{"line":150,"column":null}},"line":133},"10":{"name":"extractFromFilename","decl":{"start":{"line":155,"column":16},"end":{"line":155,"column":36}},"loc":{"start":{"line":155,"column":62},"end":{"line":158,"column":null}},"line":155},"11":{"name":"parseArticleMetadata","decl":{"start":{"line":163,"column":16},"end":{"line":163,"column":37}},"loc":{"start":{"line":163,"column":83},"end":{"line":211,"column":null}},"line":163}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"1":{"loc":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":60},"end":{"line":35,"column":90}},{"start":{"line":35,"column":90},"end":{"line":35,"column":null}}],"line":35},"2":{"loc":{"start":{"line":36,"column":11},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":29},"end":{"line":36,"column":36}},{"start":{"line":36,"column":36},"end":{"line":36,"column":null}}],"line":36},"3":{"loc":{"start":{"line":68,"column":17},"end":{"line":68,"column":24}},"type":"binary-expr","locations":[{"start":{"line":68,"column":17},"end":{"line":68,"column":22}},{"start":{"line":68,"column":22},"end":{"line":68,"column":24}}],"line":68},"4":{"loc":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":70},"5":{"loc":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},{"start":{},"end":{}}],"line":83},"6":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"7":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"8":{"loc":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"9":{"loc":{"start":{"line":105,"column":9},"end":{"line":105,"column":null}},"type":"cond-expr","locations":[{"start":{"line":105,"column":17},"end":{"line":105,"column":70}},{"start":{"line":105,"column":70},"end":{"line":105,"column":null}}],"line":105},"10":{"loc":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},{"start":{},"end":{}}],"line":112},"11":{"loc":{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":114},"12":{"loc":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":118},"13":{"loc":{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":123},"14":{"loc":{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":136},"15":{"loc":{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},{"start":{},"end":{}}],"line":141},"16":{"loc":{"start":{"line":157,"column":9},"end":{"line":157,"column":null}},"type":"cond-expr","locations":[{"start":{"line":157,"column":17},"end":{"line":157,"column":29}},{"start":{"line":157,"column":29},"end":{"line":157,"column":null}}],"line":157},"17":{"loc":{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":169},"18":{"loc":{"start":{"line":177,"column":6},"end":{"line":179,"column":null}},"type":"binary-expr","locations":[{"start":{"line":177,"column":6},"end":{"line":177,"column":null}},{"start":{"line":178,"column":6},"end":{"line":178,"column":null}},{"start":{"line":179,"column":6},"end":{"line":179,"column":null}}],"line":177},"19":{"loc":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"type":"cond-expr","locations":[{"start":{"line":188,"column":35},"end":{"line":188,"column":76}},{"start":{"line":188,"column":76},"end":{"line":188,"column":null}}],"line":188},"20":{"loc":{"start":{"line":195,"column":8},"end":{"line":198,"column":null}},"type":"binary-expr","locations":[{"start":{"line":195,"column":8},"end":{"line":195,"column":null}},{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},{"start":{"line":197,"column":8},"end":{"line":197,"column":null}},{"start":{"line":198,"column":8},"end":{"line":198,"column":null}}],"line":195},"21":{"loc":{"start":{"line":203,"column":10},"end":{"line":203,"column":null}},"type":"cond-expr","locations":[{"start":{"line":203,"column":21},"end":{"line":203,"column":36}},{"start":{"line":203,"column":36},"end":{"line":203,"column":null}}],"line":203}},"s":{"0":30454,"1":30454,"2":30454,"3":43,"4":30411,"5":30411,"6":30454,"7":115,"8":30454,"9":30454,"10":91362,"11":91362,"12":30454,"13":14,"14":30440,"15":60913,"16":30440,"17":152524,"18":152524,"19":152524,"20":151441,"21":1083,"22":1083,"23":1083,"24":0,"25":1083,"26":1083,"27":1083,"28":0,"29":1083,"30":1083,"31":1083,"32":0,"33":1083,"34":0,"35":0,"36":30454,"37":0,"38":30454,"39":254,"40":30200,"41":30200,"42":0,"43":0,"44":0,"45":0,"46":244,"47":244,"48":244,"49":14,"50":230,"51":230,"52":230,"53":230,"54":230,"55":0,"56":0,"57":14,"58":14,"59":30465,"60":30465,"61":30465,"62":30465,"63":30465,"64":11,"65":11,"66":30454,"67":30454,"68":30465,"69":30465,"70":30465,"71":30465,"72":30465,"73":30465,"74":30465,"75":0,"76":0},"f":{"0":30454,"1":30454,"2":30454,"3":91362,"4":91362,"5":60913,"6":152524,"7":0,"8":30454,"9":244,"10":14,"11":30465},"b":{"0":[43,30411],"1":[30036,260],"2":[30036,260],"3":[91362,510],"4":[14,30440],"5":[151441,1083],"6":[0,1083],"7":[0,1083],"8":[0,1083],"9":[0,0],"10":[0,30454],"11":[254,30200],"12":[30200,0],"13":[0,0],"14":[14,230],"15":[230,0],"16":[14,0],"17":[11,30454],"18":[30454,0,0],"19":[29961,493],"20":[30465,254,244,14],"21":[29961,493]},"meta":{"lastBranch":22,"lastFunction":12,"lastStatement":77,"seen":{"f:30:16:30:45":0,"s:31:2:39:Infinity":0,"s:32:24:32:Infinity":1,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":0,"s:33:4:33:Infinity":2,"s:33:22:33:Infinity":3,"s:34:21:34:Infinity":4,"s:35:17:35:Infinity":5,"b:35:60:35:90:35:90:35:Infinity":1,"s:36:4:36:Infinity":6,"b:36:29:36:36:36:36:36:Infinity":2,"s:38:4:38:Infinity":7,"f:49:16:49:33":1,"s:50:2:50:Infinity":8,"f:62:16:62:Infinity":2,"s:67:21:69:Infinity":9,"f:68:5:68:10":3,"s:68:10:68:32":10,"b:68:17:68:22:68:22:68:24":3,"f:69:5:69:13":4,"s:69:19:69:31":11,"b:70:2:70:Infinity:undefined:undefined:undefined:undefined":4,"s:70:2:70:Infinity":12,"s:70:31:70:Infinity":13,"s:71:2:71:Infinity":14,"f:71:13:71:19":5,"s:71:28:71:47":15,"s:72:2:72:Infinity":16,"f:80:16:80:35":6,"s:81:29:81:Infinity":17,"s:82:52:82:Infinity":18,"b:83:2:83:Infinity:undefined:undefined:undefined:undefined":5,"s:83:2:83:Infinity":19,"s:83:24:83:Infinity":20,"s:85:29:85:Infinity":21,"s:86:52:86:Infinity":22,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":6,"s:87:2:87:Infinity":23,"s:87:24:87:Infinity":24,"s:89:32:89:Infinity":25,"s:90:55:90:Infinity":26,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":7,"s:91:2:91:Infinity":27,"s:91:27:91:Infinity":28,"s:93:32:93:Infinity":29,"s:94:55:94:Infinity":30,"b:95:2:95:Infinity:undefined:undefined:undefined:undefined":8,"s:95:2:95:Infinity":31,"s:95:27:95:Infinity":32,"s:97:2:97:Infinity":33,"f:103:16:103:29":7,"s:104:41:104:Infinity":34,"s:105:2:105:Infinity":35,"b:105:17:105:70:105:70:105:Infinity":9,"f:111:16:111:36":8,"b:112:2:112:Infinity:undefined:undefined:undefined:undefined":10,"s:112:2:112:Infinity":36,"s:112:16:112:Infinity":37,"b:114:2:116:Infinity:undefined:undefined:undefined:undefined":11,"s:114:2:116:Infinity":38,"s:115:4:115:Infinity":39,"b:118:2:120:Infinity:undefined:undefined:undefined:undefined":12,"s:118:2:120:Infinity":40,"s:119:4:119:Infinity":41,"s:122:26:122:Infinity":42,"b:123:2:125:Infinity:undefined:undefined:undefined:undefined":13,"s:123:2:125:Infinity":43,"s:124:4:124:Infinity":44,"s:127:2:127:Infinity":45,"f:133:16:133:38":9,"s:134:2:149:Infinity":46,"s:135:49:135:Infinity":47,"b:136:4:136:Infinity:undefined:undefined:undefined:undefined":14,"s:136:4:136:Infinity":48,"s:136:22:136:Infinity":49,"s:138:31:138:Infinity":50,"s:139:49:139:Infinity":51,"b:141:4:144:Infinity:undefined:undefined:undefined:undefined":15,"s:141:4:144:Infinity":52,"s:142:30:142:Infinity":53,"s:143:6:143:Infinity":54,"s:146:4:146:Infinity":55,"s:148:4:148:Infinity":56,"f:155:16:155:36":10,"s:156:41:156:Infinity":57,"s:157:2:157:Infinity":58,"b:157:17:157:29:157:29:157:Infinity":16,"f:163:16:163:37":11,"s:164:2:210:Infinity":59,"s:165:28:165:Infinity":60,"s:166:29:166:Infinity":61,"s:168:47:168:Infinity":62,"b:169:4:172:Infinity:undefined:undefined:undefined:undefined":17,"s:169:4:172:Infinity":63,"s:170:6:170:Infinity":64,"s:171:6:171:Infinity":65,"s:174:25:174:Infinity":66,"s:177:6:179:Infinity":67,"b:177:6:177:Infinity:178:6:178:Infinity:179:6:179:Infinity":18,"s:180:24:184:Infinity":68,"s:185:33:185:Infinity":69,"s:186:19:186:Infinity":70,"s:187:24:187:Infinity":71,"s:188:21:188:Infinity":72,"b:188:35:188:76:188:76:188:Infinity":19,"s:189:42:204:Infinity":73,"b:195:8:195:Infinity:196:8:196:Infinity:197:8:197:Infinity:198:8:198:Infinity":20,"b:203:21:203:36:203:36:203:Infinity":21,"s:206:4:206:Infinity":74,"s:208:4:208:Infinity":75,"s:209:4:209:Infinity":76}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/i18n.ts","statementMap":{"0":{"start":{"line":18,"column":23},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":28},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":26},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":2},"end":{"line":21,"column":null}},"4":{"start":{"line":32,"column":50},"end":{"line":32,"column":null}},"5":{"start":{"line":33,"column":24},"end":{"line":39,"column":null}},"6":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"7":{"start":{"line":35,"column":29},"end":{"line":35,"column":null}},"8":{"start":{"line":36,"column":32},"end":{"line":36,"column":null}},"9":{"start":{"line":37,"column":26},"end":{"line":37,"column":null}},"10":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"11":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"12":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"13":{"start":{"line":47,"column":43},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"15":{"start":{"line":50,"column":32},"end":{"line":50,"column":null}},"16":{"start":{"line":51,"column":25},"end":{"line":51,"column":null}},"17":{"start":{"line":51,"column":49},"end":{"line":51,"column":83}},"18":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"generateLanguageBadge","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":38}},"loc":{"start":{"line":17,"column":84},"end":{"line":22,"column":null}},"line":17},"1":{"name":"generateLanguageSwitcherNav","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":44}},"loc":{"start":{"line":31,"column":73},"end":{"line":41,"column":null}},"line":31},"2":{"name":"(anonymous_2)","decl":{"start":{"line":33,"column":36},"end":{"line":33,"column":41}},"loc":{"start":{"line":33,"column":58},"end":{"line":39,"column":3}},"line":33},"3":{"name":"generateAvailableLanguages","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":43}},"loc":{"start":{"line":46,"column":93},"end":{"line":54,"column":null}},"line":46},"4":{"name":"(anonymous_4)","decl":{"start":{"line":51,"column":35},"end":{"line":51,"column":40}},"loc":{"start":{"line":51,"column":49},"end":{"line":51,"column":83}},"line":51}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":52},"end":{"line":17,"column":84}},"type":"default-arg","locations":[{"start":{"line":17,"column":69},"end":{"line":17,"column":84}}],"line":17},"1":{"loc":{"start":{"line":18,"column":23},"end":{"line":18,"column":null}},"type":"binary-expr","locations":[{"start":{"line":18,"column":23},"end":{"line":18,"column":47}},{"start":{"line":18,"column":47},"end":{"line":18,"column":null}}],"line":18},"2":{"loc":{"start":{"line":20,"column":26},"end":{"line":20,"column":null}},"type":"cond-expr","locations":[{"start":{"line":20,"column":34},"end":{"line":20,"column":49}},{"start":{"line":20,"column":49},"end":{"line":20,"column":null}}],"line":20},"3":{"loc":{"start":{"line":21,"column":64},"end":{"line":21,"column":129}},"type":"binary-expr","locations":[{"start":{"line":21,"column":64},"end":{"line":21,"column":124}},{"start":{"line":21,"column":124},"end":{"line":21,"column":129}}],"line":21},"4":{"loc":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":25},"end":{"line":34,"column":49}},{"start":{"line":34,"column":49},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":29},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":45},"end":{"line":35,"column":60}},{"start":{"line":35,"column":60},"end":{"line":35,"column":null}}],"line":35},"6":{"loc":{"start":{"line":36,"column":32},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":55},"end":{"line":36,"column":67}},{"start":{"line":36,"column":67},"end":{"line":36,"column":null}}],"line":36},"7":{"loc":{"start":{"line":37,"column":26},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":42},"end":{"line":37,"column":49}},{"start":{"line":37,"column":49},"end":{"line":37,"column":null}}],"line":37},"8":{"loc":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"9":{"loc":{"start":{"line":47,"column":6},"end":{"line":47,"column":43}},"type":"binary-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":20}},{"start":{"line":47,"column":20},"end":{"line":47,"column":43}}],"line":47},"10":{"loc":{"start":{"line":50,"column":32},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":32},"end":{"line":50,"column":74}},{"start":{"line":50,"column":74},"end":{"line":50,"column":null}}],"line":50}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0},"f":{"0":0,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0]},"meta":{"lastBranch":11,"lastFunction":5,"lastStatement":19,"seen":{"f:17:16:17:38":0,"b:17:69:17:84":0,"s:18:23:18:Infinity":0,"b:18:23:18:47:18:47:18:Infinity":1,"s:19:28:19:Infinity":1,"s:20:26:20:Infinity":2,"b:20:34:20:49:20:49:20:Infinity":2,"s:21:2:21:Infinity":3,"b:21:64:21:124:21:124:21:129":3,"f:31:16:31:44":1,"s:32:50:32:Infinity":4,"s:33:24:39:Infinity":5,"f:33:36:33:41":2,"s:34:25:34:Infinity":6,"b:34:25:34:49:34:49:34:Infinity":4,"s:35:29:35:Infinity":7,"b:35:45:35:60:35:60:35:Infinity":5,"s:36:32:36:Infinity":8,"b:36:55:36:67:36:67:36:Infinity":6,"s:37:26:37:Infinity":9,"b:37:42:37:49:37:49:37:Infinity":7,"s:38:4:38:Infinity":10,"s:40:2:40:Infinity":11,"f:46:16:46:43":3,"b:47:2:47:Infinity:undefined:undefined:undefined:undefined":8,"s:47:2:47:Infinity":12,"b:47:6:47:20:47:20:47:43":9,"s:47:43:47:Infinity":13,"s:49:25:49:Infinity":14,"s:50:32:50:Infinity":15,"b:50:32:50:74:50:74:50:Infinity":10,"s:51:25:51:Infinity":16,"f:51:35:51:40":4,"s:51:49:51:83":17,"s:53:2:53:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/article-grid.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/article-grid.ts","statementMap":{"0":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"skeletonCard","decl":{"start":{"line":13,"column":9},"end":{"line":13,"column":32}},"loc":{"start":{"line":13,"column":32},"end":{"line":22,"column":null}},"line":13},"1":{"name":"renderArticleGrid","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":34}},"loc":{"start":{"line":25,"column":64},"end":{"line":44,"column":null}},"line":25}},"branchMap":{},"s":{"0":99,"1":33},"f":{"0":99,"1":33},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":2,"seen":{"f:13:9:13:32":0,"s:14:2:14:Infinity":0,"f:25:16:25:34":1,"s:26:2:42:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/path-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/path-utils.ts","statementMap":{"0":{"start":{"line":17,"column":19},"end":{"line":17,"column":null}},"1":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"2":{"start":{"line":21,"column":32},"end":{"line":21,"column":null}},"3":{"start":{"line":28,"column":27},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":32,"column":6},"end":{"line":32,"column":null}},"8":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"9":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"10":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"11":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":47,"column":30},"end":{"line":47,"column":null}},"13":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"14":{"start":{"line":51,"column":64},"end":{"line":53,"column":null}},"15":{"start":{"line":52,"column":41},"end":{"line":52,"column":51}},"16":{"start":{"line":55,"column":2},"end":{"line":65,"column":null}},"17":{"start":{"line":56,"column":49},"end":{"line":56,"column":null}},"18":{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},"19":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"20":{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},"21":{"start":{"line":62,"column":8},"end":{"line":62,"column":null}},"22":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"23":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"24":{"start":{"line":68,"column":41},"end":{"line":68,"column":96}},"25":{"start":{"line":71,"column":31},"end":{"line":73,"column":null}},"26":{"start":{"line":72,"column":25},"end":{"line":72,"column":39}},"27":{"start":{"line":73,"column":26},"end":{"line":73,"column":63}},"28":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"29":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}}},"fnMap":{"0":{"name":"collectArticleFiles","decl":{"start":{"line":27,"column":9},"end":{"line":27,"column":29}},"loc":{"start":{"line":27,"column":52},"end":{"line":38,"column":null}},"line":27},"1":{"name":"scanNewsArticles","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":74}},"loc":{"start":{"line":44,"column":74},"end":{"line":77,"column":null}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":52,"column":27},"end":{"line":52,"column":32}},"loc":{"start":{"line":52,"column":41},"end":{"line":52,"column":51}},"line":52},"3":{"name":"(anonymous_3)","decl":{"start":{"line":55,"column":12},"end":{"line":55,"column":21}},"loc":{"start":{"line":55,"column":34},"end":{"line":65,"column":3}},"line":55},"4":{"name":"(anonymous_4)","decl":{"start":{"line":67,"column":30},"end":{"line":67,"column":39}},"loc":{"start":{"line":67,"column":48},"end":{"line":69,"column":3}},"line":67},"5":{"name":"(anonymous_5)","decl":{"start":{"line":68,"column":26},"end":{"line":68,"column":32}},"loc":{"start":{"line":68,"column":41},"end":{"line":68,"column":96}},"line":68},"6":{"name":"(anonymous_6)","decl":{"start":{"line":72,"column":5},"end":{"line":72,"column":13}},"loc":{"start":{"line":72,"column":25},"end":{"line":72,"column":39}},"line":72},"7":{"name":"(anonymous_7)","decl":{"start":{"line":73,"column":5},"end":{"line":73,"column":10}},"loc":{"start":{"line":73,"column":26},"end":{"line":73,"column":63}},"line":73}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},{"start":{"line":33,"column":11},"end":{"line":35,"column":null}}],"line":31},"1":{"loc":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":33,"column":15},"end":{"line":33,"column":98}},"type":"binary-expr","locations":[{"start":{"line":33,"column":15},"end":{"line":33,"column":33}},{"start":{"line":33,"column":33},"end":{"line":33,"column":65}},{"start":{"line":33,"column":65},"end":{"line":33,"column":98}}],"line":33},"3":{"loc":{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":58},"4":{"loc":{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"5":{"loc":{"start":{"line":74,"column":44},"end":{"line":74,"column":106}},"type":"cond-expr","locations":[{"start":{"line":74,"column":68},"end":{"line":74,"column":92}},{"start":{"line":74,"column":92},"end":{"line":74,"column":106}}],"line":74}},"s":{"0":5,"1":5,"2":5,"3":40,"4":40,"5":40,"6":30731,"7":35,"8":30696,"9":30435,"10":40,"11":5,"12":5,"13":5,"14":5,"15":70,"16":5,"17":30435,"18":30435,"19":30425,"20":30425,"21":30425,"22":5,"23":70,"24":147430,"25":5,"26":70,"27":70,"28":5,"29":5},"f":{"0":40,"1":5,"2":70,"3":30435,"4":70,"5":147430,"6":70,"7":70},"b":{"0":[35,30696],"1":[30435,261],"2":[30696,30696,30561],"3":[30425,10],"4":[30425,0],"5":[5,0]},"meta":{"lastBranch":6,"lastFunction":8,"lastStatement":30,"seen":{"s:17:19:17:Infinity":0,"s:18:18:18:Infinity":1,"s:21:32:21:Infinity":2,"f:27:9:27:29":0,"s:28:27:28:Infinity":3,"s:29:18:29:Infinity":4,"s:30:2:36:Infinity":5,"b:31:4:35:Infinity:33:11:35:Infinity":0,"s:31:4:35:Infinity":6,"s:32:6:32:Infinity":7,"b:33:11:35:Infinity:undefined:undefined:undefined:undefined":1,"s:33:11:35:Infinity":8,"b:33:15:33:33:33:33:33:65:33:65:33:98":2,"s:34:6:34:Infinity":9,"s:37:2:37:Infinity":10,"f:44:16:44:74":1,"s:45:2:45:Infinity":11,"s:47:30:47:Infinity":12,"s:49:2:49:Infinity":13,"s:51:64:53:Infinity":14,"f:52:27:52:32":2,"s:52:41:52:51":15,"s:55:2:65:Infinity":16,"f:55:12:55:21":3,"s:56:49:56:Infinity":17,"b:58:4:64:Infinity:undefined:undefined:undefined:undefined":3,"s:58:4:64:Infinity":18,"s:59:6:59:Infinity":19,"b:61:6:63:Infinity:undefined:undefined:undefined:undefined":4,"s:61:6:63:Infinity":20,"s:62:8:62:Infinity":21,"s:67:2:69:Infinity":22,"f:67:30:67:39":4,"s:68:4:68:Infinity":23,"f:68:26:68:32":5,"s:68:41:68:96":24,"s:71:31:73:Infinity":25,"f:72:5:72:13":6,"s:72:25:72:39":26,"f:73:5:73:10":7,"s:73:26:73:63":27,"s:74:2:74:Infinity":28,"b:74:68:74:92:74:92:74:106":5,"s:76:2:76:Infinity":29}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/slug.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/slug.ts","statementMap":{"0":{"start":{"line":20,"column":19},"end":{"line":20,"column":null}},"1":{"start":{"line":23,"column":38},"end":{"line":23,"column":null}},"2":{"start":{"line":25,"column":75},"end":{"line":33,"column":null}},"3":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},"5":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":18},"end":{"line":46,"column":null}},"7":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"8":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"9":{"start":{"line":48,"column":52},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":42},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"13":{"start":{"line":50,"column":49},"end":{"line":50,"column":null}},"14":{"start":{"line":52,"column":18},"end":{"line":52,"column":null}},"15":{"start":{"line":53,"column":4},"end":{"line":61,"column":null}},"16":{"start":{"line":53,"column":17},"end":{"line":53,"column":35}},"17":{"start":{"line":54,"column":21},"end":{"line":54,"column":null}},"18":{"start":{"line":55,"column":26},"end":{"line":55,"column":null}},"19":{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},"20":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"21":{"start":{"line":57,"column":60},"end":{"line":57,"column":null}},"22":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"23":{"start":{"line":58,"column":50},"end":{"line":58,"column":null}},"24":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"25":{"start":{"line":59,"column":57},"end":{"line":59,"column":null}},"26":{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},"27":{"start":{"line":65,"column":22},"end":{"line":65,"column":null}},"28":{"start":{"line":66,"column":25},"end":{"line":66,"column":null}},"29":{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},"30":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"31":{"start":{"line":69,"column":20},"end":{"line":69,"column":null}},"32":{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},"33":{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},"34":{"start":{"line":71,"column":54},"end":{"line":71,"column":null}},"35":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"36":{"start":{"line":72,"column":44},"end":{"line":72,"column":null}},"37":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"38":{"start":{"line":73,"column":51},"end":{"line":73,"column":null}},"39":{"start":{"line":78,"column":31},"end":{"line":78,"column":null}},"40":{"start":{"line":80,"column":40},"end":{"line":95,"column":null}},"41":{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},"42":{"start":{"line":97,"column":110},"end":{"line":97,"column":149}},"43":{"start":{"line":98,"column":4},"end":{"line":98,"column":null}},"44":{"start":{"line":101,"column":37},"end":{"line":116,"column":null}},"45":{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},"46":{"start":{"line":120,"column":36},"end":{"line":120,"column":75}},"47":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"48":{"start":{"line":124,"column":37},"end":{"line":139,"column":null}},"49":{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},"50":{"start":{"line":141,"column":69},"end":{"line":141,"column":108}},"51":{"start":{"line":142,"column":4},"end":{"line":142,"column":null}},"52":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"53":{"start":{"line":153,"column":27},"end":{"line":153,"column":null}},"54":{"start":{"line":154,"column":21},"end":{"line":154,"column":null}},"55":{"start":{"line":157,"column":2},"end":{"line":166,"column":null}},"56":{"start":{"line":158,"column":24},"end":{"line":158,"column":null}},"57":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"58":{"start":{"line":159,"column":28},"end":{"line":159,"column":null}},"59":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"60":{"start":{"line":160,"column":214},"end":{"line":160,"column":null}},"61":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"62":{"start":{"line":161,"column":308},"end":{"line":161,"column":null}},"63":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"64":{"start":{"line":162,"column":373},"end":{"line":162,"column":null}},"65":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"66":{"start":{"line":163,"column":352},"end":{"line":163,"column":null}},"67":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"68":{"start":{"line":164,"column":374},"end":{"line":164,"column":null}},"69":{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},"70":{"start":{"line":165,"column":352},"end":{"line":165,"column":null}},"71":{"start":{"line":168,"column":23},"end":{"line":168,"column":null}},"72":{"start":{"line":169,"column":2},"end":{"line":171,"column":null}},"73":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"74":{"start":{"line":170,"column":36},"end":{"line":170,"column":null}},"75":{"start":{"line":173,"column":2},"end":{"line":173,"column":null}},"76":{"start":{"line":180,"column":25},"end":{"line":180,"column":null}},"77":{"start":{"line":181,"column":21},"end":{"line":181,"column":null}},"78":{"start":{"line":184,"column":2},"end":{"line":186,"column":null}},"79":{"start":{"line":185,"column":4},"end":{"line":185,"column":null}},"80":{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},"81":{"start":{"line":189,"column":4},"end":{"line":189,"column":null}},"82":{"start":{"line":190,"column":25},"end":{"line":190,"column":null}},"83":{"start":{"line":191,"column":4},"end":{"line":191,"column":null}},"84":{"start":{"line":194,"column":2},"end":{"line":194,"column":null}},"85":{"start":{"line":194,"column":42},"end":{"line":194,"column":63}}},"fnMap":{"0":{"name":"classifyArticleType","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":36}},"loc":{"start":{"line":42,"column":112},"end":{"line":146,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":97,"column":97},"end":{"line":97,"column":103}},"loc":{"start":{"line":97,"column":110},"end":{"line":97,"column":149}},"line":97},"2":{"name":"(anonymous_2)","decl":{"start":{"line":120,"column":23},"end":{"line":120,"column":29}},"loc":{"start":{"line":120,"column":36},"end":{"line":120,"column":75}},"line":120},"3":{"name":"(anonymous_3)","decl":{"start":{"line":141,"column":56},"end":{"line":141,"column":62}},"loc":{"start":{"line":141,"column":69},"end":{"line":141,"column":108}},"line":141},"4":{"name":"extractTopics","decl":{"start":{"line":152,"column":16},"end":{"line":152,"column":30}},"loc":{"start":{"line":152,"column":80},"end":{"line":174,"column":null}},"line":152},"5":{"name":"extractTags","decl":{"start":{"line":179,"column":16},"end":{"line":179,"column":28}},"loc":{"start":{"line":179,"column":105},"end":{"line":195,"column":null}},"line":179},"6":{"name":"(anonymous_6)","decl":{"start":{"line":194,"column":26},"end":{"line":194,"column":34}},"loc":{"start":{"line":194,"column":42},"end":{"line":194,"column":63}},"line":194}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"4":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"5":{"loc":{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57},"7":{"loc":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"8":{"loc":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"9":{"loc":{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":64},"10":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":50}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":22}},{"start":{"line":64,"column":22},"end":{"line":64,"column":50}}],"line":64},"11":{"loc":{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":67},"12":{"loc":{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":70},"13":{"loc":{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":71},"14":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"15":{"loc":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"16":{"loc":{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":97},"17":{"loc":{"start":{"line":97,"column":6},"end":{"line":97,"column":152}},"type":"binary-expr","locations":[{"start":{"line":97,"column":6},"end":{"line":97,"column":41}},{"start":{"line":97,"column":41},"end":{"line":97,"column":77}},{"start":{"line":97,"column":77},"end":{"line":97,"column":152}}],"line":97},"18":{"loc":{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},{"start":{},"end":{}}],"line":118},"19":{"loc":{"start":{"line":118,"column":6},"end":{"line":120,"column":78}},"type":"binary-expr","locations":[{"start":{"line":118,"column":6},"end":{"line":118,"column":48}},{"start":{"line":118,"column":48},"end":{"line":118,"column":85}},{"start":{"line":118,"column":85},"end":{"line":118,"column":null}},{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},{"start":{"line":120,"column":6},"end":{"line":120,"column":78}}],"line":118},"20":{"loc":{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":141},"21":{"loc":{"start":{"line":141,"column":6},"end":{"line":141,"column":111}},"type":"binary-expr","locations":[{"start":{"line":141,"column":6},"end":{"line":141,"column":39}},{"start":{"line":141,"column":39},"end":{"line":141,"column":111}}],"line":141},"22":{"loc":{"start":{"line":152,"column":47},"end":{"line":152,"column":80}},"type":"default-arg","locations":[{"start":{"line":152,"column":66},"end":{"line":152,"column":80}}],"line":152},"23":{"loc":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"type":"if","locations":[{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},{"start":{},"end":{}}],"line":159},"24":{"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":160},"25":{"loc":{"start":{"line":160,"column":8},"end":{"line":160,"column":214}},"type":"binary-expr","locations":[{"start":{"line":160,"column":8},"end":{"line":160,"column":38}},{"start":{"line":160,"column":38},"end":{"line":160,"column":65}},{"start":{"line":160,"column":65},"end":{"line":160,"column":96}},{"start":{"line":160,"column":96},"end":{"line":160,"column":118}},{"start":{"line":160,"column":118},"end":{"line":160,"column":140}},{"start":{"line":160,"column":140},"end":{"line":160,"column":162}},{"start":{"line":160,"column":162},"end":{"line":160,"column":190}},{"start":{"line":160,"column":190},"end":{"line":160,"column":214}}],"line":160},"26":{"loc":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"27":{"loc":{"start":{"line":161,"column":8},"end":{"line":161,"column":308}},"type":"binary-expr","locations":[{"start":{"line":161,"column":8},"end":{"line":161,"column":38}},{"start":{"line":161,"column":38},"end":{"line":161,"column":66}},{"start":{"line":161,"column":66},"end":{"line":161,"column":97}},{"start":{"line":161,"column":97},"end":{"line":161,"column":125}},{"start":{"line":161,"column":125},"end":{"line":161,"column":154}},{"start":{"line":161,"column":154},"end":{"line":161,"column":186}},{"start":{"line":161,"column":186},"end":{"line":161,"column":214}},{"start":{"line":161,"column":214},"end":{"line":161,"column":236}},{"start":{"line":161,"column":236},"end":{"line":161,"column":258}},{"start":{"line":161,"column":258},"end":{"line":161,"column":285}},{"start":{"line":161,"column":285},"end":{"line":161,"column":308}}],"line":161},"28":{"loc":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},{"start":{},"end":{}}],"line":162},"29":{"loc":{"start":{"line":162,"column":8},"end":{"line":162,"column":373}},"type":"binary-expr","locations":[{"start":{"line":162,"column":8},"end":{"line":162,"column":35}},{"start":{"line":162,"column":35},"end":{"line":162,"column":62}},{"start":{"line":162,"column":62},"end":{"line":162,"column":89}},{"start":{"line":162,"column":89},"end":{"line":162,"column":116}},{"start":{"line":162,"column":116},"end":{"line":162,"column":145}},{"start":{"line":162,"column":145},"end":{"line":162,"column":177}},{"start":{"line":162,"column":177},"end":{"line":162,"column":204}},{"start":{"line":162,"column":204},"end":{"line":162,"column":231}},{"start":{"line":162,"column":231},"end":{"line":162,"column":259}},{"start":{"line":162,"column":259},"end":{"line":162,"column":285}},{"start":{"line":162,"column":285},"end":{"line":162,"column":309}},{"start":{"line":162,"column":309},"end":{"line":162,"column":331}},{"start":{"line":162,"column":331},"end":{"line":162,"column":353}},{"start":{"line":162,"column":353},"end":{"line":162,"column":373}}],"line":162},"30":{"loc":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"31":{"loc":{"start":{"line":163,"column":8},"end":{"line":163,"column":352}},"type":"binary-expr","locations":[{"start":{"line":163,"column":8},"end":{"line":163,"column":39}},{"start":{"line":163,"column":39},"end":{"line":163,"column":64}},{"start":{"line":163,"column":64},"end":{"line":163,"column":89}},{"start":{"line":163,"column":89},"end":{"line":163,"column":118}},{"start":{"line":163,"column":118},"end":{"line":163,"column":144}},{"start":{"line":163,"column":144},"end":{"line":163,"column":177}},{"start":{"line":163,"column":177},"end":{"line":163,"column":211}},{"start":{"line":163,"column":211},"end":{"line":163,"column":237}},{"start":{"line":163,"column":237},"end":{"line":163,"column":263}},{"start":{"line":163,"column":263},"end":{"line":163,"column":288}},{"start":{"line":163,"column":288},"end":{"line":163,"column":310}},{"start":{"line":163,"column":310},"end":{"line":163,"column":332}},{"start":{"line":163,"column":332},"end":{"line":163,"column":352}}],"line":163},"32":{"loc":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":164},"33":{"loc":{"start":{"line":164,"column":8},"end":{"line":164,"column":374}},"type":"binary-expr","locations":[{"start":{"line":164,"column":8},"end":{"line":164,"column":37}},{"start":{"line":164,"column":37},"end":{"line":164,"column":64}},{"start":{"line":164,"column":64},"end":{"line":164,"column":90}},{"start":{"line":164,"column":90},"end":{"line":164,"column":116}},{"start":{"line":164,"column":116},"end":{"line":164,"column":145}},{"start":{"line":164,"column":145},"end":{"line":164,"column":174}},{"start":{"line":164,"column":174},"end":{"line":164,"column":204}},{"start":{"line":164,"column":204},"end":{"line":164,"column":230}},{"start":{"line":164,"column":230},"end":{"line":164,"column":259}},{"start":{"line":164,"column":259},"end":{"line":164,"column":283}},{"start":{"line":164,"column":283},"end":{"line":164,"column":307}},{"start":{"line":164,"column":307},"end":{"line":164,"column":330}},{"start":{"line":164,"column":330},"end":{"line":164,"column":353}},{"start":{"line":164,"column":353},"end":{"line":164,"column":374}}],"line":164},"34":{"loc":{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":165},"35":{"loc":{"start":{"line":165,"column":8},"end":{"line":165,"column":352}},"type":"binary-expr","locations":[{"start":{"line":165,"column":8},"end":{"line":165,"column":39}},{"start":{"line":165,"column":39},"end":{"line":165,"column":71}},{"start":{"line":165,"column":71},"end":{"line":165,"column":101}},{"start":{"line":165,"column":101},"end":{"line":165,"column":133}},{"start":{"line":165,"column":133},"end":{"line":165,"column":165}},{"start":{"line":165,"column":165},"end":{"line":165,"column":196}},{"start":{"line":165,"column":196},"end":{"line":165,"column":227}},{"start":{"line":165,"column":227},"end":{"line":165,"column":256}},{"start":{"line":165,"column":256},"end":{"line":165,"column":285}},{"start":{"line":165,"column":285},"end":{"line":165,"column":310}},{"start":{"line":165,"column":310},"end":{"line":165,"column":332}},{"start":{"line":165,"column":332},"end":{"line":165,"column":352}}],"line":165},"36":{"loc":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"type":"if","locations":[{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},{"start":{},"end":{}}],"line":170},"37":{"loc":{"start":{"line":179,"column":45},"end":{"line":179,"column":68}},"type":"default-arg","locations":[{"start":{"line":179,"column":64},"end":{"line":179,"column":68}}],"line":179},"38":{"loc":{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":188}},"s":{"0":5,"1":5,"2":5,"3":49242,"4":49242,"5":49172,"6":49172,"7":49172,"8":29679,"9":4947,"10":24732,"11":15442,"12":9290,"13":9290,"14":19493,"15":19493,"16":19493,"17":23178,"18":23178,"19":23178,"20":3975,"21":3965,"22":10,"23":10,"24":0,"25":0,"26":15588,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":15588,"40":15588,"41":15588,"42":60731,"43":15546,"44":42,"45":42,"46":1745,"47":5,"48":37,"49":37,"50":1242,"51":4,"52":33,"53":30454,"54":30454,"55":30454,"56":17996,"57":17996,"58":101,"59":17996,"60":1054,"61":17996,"62":2298,"63":17996,"64":256,"65":17996,"66":27,"67":17996,"68":2907,"69":17996,"70":15,"71":30454,"72":30454,"73":213178,"74":79746,"75":30454,"76":30454,"77":30454,"78":30454,"79":17996,"80":30454,"81":18788,"82":18788,"83":18788,"84":30454,"85":86586},"f":{"0":49242,"1":60731,"2":1745,"3":1242,"4":30454,"5":30454,"6":86586},"b":{"0":[49172,70],"1":[29679,19493],"2":[4947,24732],"3":[15442,9290],"4":[9290,0],"5":[3975,19203],"6":[3965,10],"7":[10,0],"8":[0,0],"9":[0,15588],"10":[15588,11092],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[15546,42],"17":[15588,15578,15578],"18":[5,37],"19":[42,42,42,42,42],"20":[4,33],"21":[37,37],"22":[30454],"23":[101,17895],"24":[1054,16942],"25":[17996,17459,16944,16944,16943,16943,16943,16942],"26":[2298,15698],"27":[17996,17170,16735,16620,16620,16489,16359,16359,16109,15944,15818],"28":[256,17740],"29":[17996,17906,17761,17746,17741,17741,17740,17740,17740,17740,17740,17740,17740,17740],"30":[27,17969],"31":[17996,17980,17970,17970,17970,17970,17970,17970,17970,17969,17969,17969,17969],"32":[2907,15089],"33":[17996,16471,16426,16266,16261,16131,15970,15810,15805,15650,15650,15520,15374,15224],"34":[15,17981],"35":[17996,17991,17981,17981,17981,17981,17981,17981,17981,17981,17981,17981],"36":[79746,133432],"37":[30454],"38":[18788,11666]},"meta":{"lastBranch":39,"lastFunction":7,"lastStatement":86,"seen":{"s:20:19:20:Infinity":0,"s:23:38:23:Infinity":1,"s:25:75:33:Infinity":2,"f:42:16:42:36":0,"s:43:20:43:Infinity":3,"b:44:2:62:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:62:Infinity":4,"s:45:17:45:Infinity":5,"s:46:18:46:Infinity":6,"b:47:4:51:Infinity:undefined:undefined:undefined:undefined":1,"s:47:4:51:Infinity":7,"b:48:6:48:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:48:Infinity":8,"s:48:52:48:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":3,"s:49:6:49:Infinity":10,"s:49:42:49:Infinity":11,"b:50:6:50:Infinity:undefined:undefined:undefined:undefined":4,"s:50:6:50:Infinity":12,"s:50:49:50:Infinity":13,"s:52:18:52:Infinity":14,"s:53:4:61:Infinity":15,"s:53:17:53:35":16,"s:54:21:54:Infinity":17,"s:55:26:55:Infinity":18,"b:56:6:60:Infinity:undefined:undefined:undefined:undefined":5,"s:56:6:60:Infinity":19,"b:57:8:57:Infinity:undefined:undefined:undefined:undefined":6,"s:57:8:57:Infinity":20,"s:57:60:57:Infinity":21,"b:58:8:58:Infinity:undefined:undefined:undefined:undefined":7,"s:58:8:58:Infinity":22,"s:58:50:58:Infinity":23,"b:59:8:59:Infinity:undefined:undefined:undefined:undefined":8,"s:59:8:59:Infinity":24,"s:59:57:59:Infinity":25,"b:64:2:76:Infinity:undefined:undefined:undefined:undefined":9,"s:64:2:76:Infinity":26,"b:64:6:64:22:64:22:64:50":10,"s:65:22:65:Infinity":27,"s:66:25:66:Infinity":28,"b:67:4:75:Infinity:undefined:undefined:undefined:undefined":11,"s:67:4:75:Infinity":29,"s:68:22:68:Infinity":30,"s:69:20:69:Infinity":31,"b:70:6:74:Infinity:undefined:undefined:undefined:undefined":12,"s:70:6:74:Infinity":32,"b:71:8:71:Infinity:undefined:undefined:undefined:undefined":13,"s:71:8:71:Infinity":33,"s:71:54:71:Infinity":34,"b:72:8:72:Infinity:undefined:undefined:undefined:undefined":14,"s:72:8:72:Infinity":35,"s:72:44:72:Infinity":36,"b:73:8:73:Infinity:undefined:undefined:undefined:undefined":15,"s:73:8:73:Infinity":37,"s:73:51:73:Infinity":38,"s:78:31:78:Infinity":39,"s:80:40:95:Infinity":40,"b:97:2:99:Infinity:undefined:undefined:undefined:undefined":16,"s:97:2:99:Infinity":41,"b:97:6:97:41:97:41:97:77:97:77:97:152":17,"f:97:97:97:103":1,"s:97:110:97:149":42,"s:98:4:98:Infinity":43,"s:101:37:116:Infinity":44,"b:118:2:122:Infinity:undefined:undefined:undefined:undefined":18,"s:118:2:122:Infinity":45,"b:118:6:118:48:118:48:118:85:118:85:118:Infinity:119:6:119:Infinity:120:6:120:78":19,"f:120:23:120:29":2,"s:120:36:120:75":46,"s:121:4:121:Infinity":47,"s:124:37:139:Infinity":48,"b:141:2:143:Infinity:undefined:undefined:undefined:undefined":20,"s:141:2:143:Infinity":49,"b:141:6:141:39:141:39:141:111":21,"f:141:56:141:62":3,"s:141:69:141:108":50,"s:142:4:142:Infinity":51,"s:145:2:145:Infinity":52,"f:152:16:152:30":4,"b:152:66:152:80":22,"s:153:27:153:Infinity":53,"s:154:21:154:Infinity":54,"s:157:2:166:Infinity":55,"s:158:24:158:Infinity":56,"b:159:4:159:Infinity:undefined:undefined:undefined:undefined":23,"s:159:4:159:Infinity":57,"s:159:28:159:Infinity":58,"b:160:4:160:Infinity:undefined:undefined:undefined:undefined":24,"s:160:4:160:Infinity":59,"b:160:8:160:38:160:38:160:65:160:65:160:96:160:96:160:118:160:118:160:140:160:140:160:162:160:162:160:190:160:190:160:214":25,"s:160:214:160:Infinity":60,"b:161:4:161:Infinity:undefined:undefined:undefined:undefined":26,"s:161:4:161:Infinity":61,"b:161:8:161:38:161:38:161:66:161:66:161:97:161:97:161:125:161:125:161:154:161:154:161:186:161:186:161:214:161:214:161:236:161:236:161:258:161:258:161:285:161:285:161:308":27,"s:161:308:161:Infinity":62,"b:162:4:162:Infinity:undefined:undefined:undefined:undefined":28,"s:162:4:162:Infinity":63,"b:162:8:162:35:162:35:162:62:162:62:162:89:162:89:162:116:162:116:162:145:162:145:162:177:162:177:162:204:162:204:162:231:162:231:162:259:162:259:162:285:162:285:162:309:162:309:162:331:162:331:162:353:162:353:162:373":29,"s:162:373:162:Infinity":64,"b:163:4:163:Infinity:undefined:undefined:undefined:undefined":30,"s:163:4:163:Infinity":65,"b:163:8:163:39:163:39:163:64:163:64:163:89:163:89:163:118:163:118:163:144:163:144:163:177:163:177:163:211:163:211:163:237:163:237:163:263:163:263:163:288:163:288:163:310:163:310:163:332:163:332:163:352":31,"s:163:352:163:Infinity":66,"b:164:4:164:Infinity:undefined:undefined:undefined:undefined":32,"s:164:4:164:Infinity":67,"b:164:8:164:37:164:37:164:64:164:64:164:90:164:90:164:116:164:116:164:145:164:145:164:174:164:174:164:204:164:204:164:230:164:230:164:259:164:259:164:283:164:283:164:307:164:307:164:330:164:330:164:353:164:353:164:374":33,"s:164:374:164:Infinity":68,"b:165:4:165:Infinity:undefined:undefined:undefined:undefined":34,"s:165:4:165:Infinity":69,"b:165:8:165:39:165:39:165:71:165:71:165:101:165:101:165:133:165:133:165:165:165:165:165:196:165:196:165:227:165:227:165:256:165:256:165:285:165:285:165:310:165:310:165:332:165:332:165:352":35,"s:165:352:165:Infinity":70,"s:168:23:168:Infinity":71,"s:169:2:171:Infinity":72,"b:170:4:170:Infinity:undefined:undefined:undefined:undefined":36,"s:170:4:170:Infinity":73,"s:170:36:170:Infinity":74,"s:173:2:173:Infinity":75,"f:179:16:179:28":5,"b:179:64:179:68":37,"s:180:25:180:Infinity":76,"s:181:21:181:Infinity":77,"s:184:2:186:Infinity":78,"s:185:4:185:Infinity":79,"b:188:2:192:Infinity:undefined:undefined:undefined:undefined":38,"s:188:2:192:Infinity":80,"s:189:4:189:Infinity":81,"s:190:25:190:Infinity":82,"s:191:4:191:Infinity":83,"s:194:2:194:Infinity":84,"f:194:26:194:34":6,"s:194:42:194:63":85}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-prelude.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-prelude.ts","statementMap":{"0":{"start":{"line":30,"column":26},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":21},"end":{"line":36,"column":null}},"2":{"start":{"line":38,"column":23},"end":{"line":38,"column":null}},"3":{"start":{"line":39,"column":26},"end":{"line":39,"column":null}},"4":{"start":{"line":41,"column":2},"end":{"line":61,"column":null}}},"fnMap":{"0":{"name":"buildPrelude","decl":{"start":{"line":29,"column":16},"end":{"line":29,"column":29}},"loc":{"start":{"line":29,"column":90},"end":{"line":62,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":37},"end":{"line":39,"column":89}},"type":"binary-expr","locations":[{"start":{"line":39,"column":37},"end":{"line":39,"column":75}},{"start":{"line":39,"column":75},"end":{"line":39,"column":89}}],"line":39}},"s":{"0":33,"1":33,"2":33,"3":33,"4":33},"f":{"0":33},"b":{"0":[33,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":5,"seen":{"f:29:16:29:29":0,"s:30:26:30:Infinity":0,"s:31:21:36:Infinity":1,"s:38:23:38:Infinity":2,"s:39:26:39:Infinity":3,"b:39:37:39:75:39:75:39:89":0,"s:41:2:61:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/filtering.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/filtering.ts","statementMap":{"0":{"start":{"line":12,"column":25},"end":{"line":12,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:12:25:12:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/helpers.ts","statementMap":{"0":{"start":{"line":13,"column":32},"end":{"line":13,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:13:32:13:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/index.ts","statementMap":{"0":{"start":{"line":24,"column":35},"end":{"line":24,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:24:35:24:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/rendering.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/rendering.ts","statementMap":{"0":{"start":{"line":12,"column":25},"end":{"line":12,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:12:25:12:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/search.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/search.ts","statementMap":{"0":{"start":{"line":14,"column":22},"end":{"line":14,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:14:22:14:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/sorting.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/sorting.ts","statementMap":{"0":{"start":{"line":15,"column":23},"end":{"line":15,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:15:23:15:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script.ts","statementMap":{"0":{"start":{"line":23,"column":18},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}}},"fnMap":{"0":{"name":"renderClientScript","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":35}},"loc":{"start":{"line":22,"column":69},"end":{"line":32,"column":null}},"line":22}},"branchMap":{},"s":{"0":33,"1":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":2,"seen":{"f:22:16:22:35":0,"s:23:18:28:Infinity":0,"s:29:2:31:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/constants.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/constants.ts","statementMap":{"0":{"start":{"line":10,"column":36},"end":{"line":10,"column":null}},"1":{"start":{"line":13,"column":24},"end":{"line":13,"column":null}},"2":{"start":{"line":17,"column":8},"end":{"line":17,"column":null}},"3":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}}},"fnMap":{"0":{"name":"appVersionMarker","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":43}},"loc":{"start":{"line":16,"column":43},"end":{"line":19,"column":null}},"line":16}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":19},"end":{"line":17,"column":74}},"type":"binary-expr","locations":[{"start":{"line":17,"column":19},"end":{"line":17,"column":54}},{"start":{"line":17,"column":54},"end":{"line":17,"column":74}}],"line":17}},"s":{"0":6,"1":6,"2":33,"3":33},"f":{"0":33},"b":{"0":[33,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":4,"seen":{"s:10:36:10:Infinity":0,"s:13:24:13:Infinity":1,"f:16:16:16:43":0,"s:17:8:17:Infinity":2,"b:17:19:17:54:17:54:17:74":0,"s:18:2:18:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/filters.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/filters.ts","statementMap":{"0":{"start":{"line":14,"column":26},"end":{"line":14,"column":null}},"1":{"start":{"line":15,"column":2},"end":{"line":64,"column":null}}},"fnMap":{"0":{"name":"renderFilterBar","decl":{"start":{"line":13,"column":16},"end":{"line":13,"column":32}},"loc":{"start":{"line":13,"column":89},"end":{"line":69,"column":null}},"line":13}},"branchMap":{},"s":{"0":33,"1":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":2,"seen":{"f:13:16:13:32":0,"s:14:26:14:Infinity":0,"s:15:2:64:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hero.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hero.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"renderHero","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"loc":{"start":{"line":20,"column":10},"end":{"line":40,"column":null}},"line":20}},"branchMap":{},"s":{"0":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:15:16:15:Infinity":0,"s:21:2:36:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hreflang.ts","statementMap":{"0":{"start":{"line":16,"column":25},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":2},"end":{"line":22,"column":null}},"2":{"start":{"line":19,"column":21},"end":{"line":19,"column":null}},"3":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"4":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"5":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"6":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}}},"fnMap":{"0":{"name":"generateHreflangTags","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":47}},"loc":{"start":{"line":15,"column":47},"end":{"line":27,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":21},"end":{"line":19,"column":null}},"type":"cond-expr","locations":[{"start":{"line":19,"column":40},"end":{"line":19,"column":55}},{"start":{"line":19,"column":55},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":19,"column":64},"end":{"line":19,"column":98}},"type":"cond-expr","locations":[{"start":{"line":19,"column":83},"end":{"line":19,"column":90}},{"start":{"line":19,"column":90},"end":{"line":19,"column":98}}],"line":19}},"s":{"0":4,"1":4,"2":56,"3":56,"4":56,"5":4,"6":4},"f":{"0":4},"b":{"0":[4,52],"1":[4,48]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":7,"seen":{"f:15:16:15:47":0,"s:16:25:16:Infinity":0,"s:18:2:22:Infinity":1,"s:19:21:19:Infinity":2,"b:19:40:19:55:19:55:19:Infinity":0,"b:19:83:19:90:19:90:19:98":1,"s:20:22:20:Infinity":3,"s:21:4:21:Infinity":4,"s:24:2:24:Infinity":5,"s:26:2:26:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/language-notice.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/language-notice.ts","statementMap":{"0":{"start":{"line":12,"column":73},"end":{"line":25,"column":null}},"1":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"3":{"start":{"line":34,"column":12},"end":{"line":34,"column":null}},"4":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"5":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}}},"fnMap":{"0":{"name":"generateLanguageNotice","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":39}},"loc":{"start":{"line":32,"column":64},"end":{"line":43,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":40,"column":51},"end":{"line":40,"column":77}},"type":"cond-expr","locations":[{"start":{"line":40,"column":59},"end":{"line":40,"column":74}},{"start":{"line":40,"column":74},"end":{"line":40,"column":77}}],"line":40}},"s":{"0":6,"1":19,"2":19,"3":2,"4":17,"5":17},"f":{"0":19},"b":{"0":[2,17],"1":[4,13]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":6,"seen":{"s:12:73:25:Infinity":0,"f:32:16:32:39":0,"s:33:14:33:Infinity":1,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":2,"s:34:12:34:Infinity":3,"s:36:16:36:Infinity":4,"s:38:2:40:Infinity":5,"b:40:59:40:74:40:74:40:77":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/i18n.ts","statementMap":{"0":{"start":{"line":16,"column":70},"end":{"line":31,"column":null}},"1":{"start":{"line":34,"column":120},"end":{"line":49,"column":null}},"2":{"start":{"line":52,"column":136},"end":{"line":67,"column":null}},"3":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"4":{"start":{"line":76,"column":14},"end":{"line":76,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":81,"column":null}},"6":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"7":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"8":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"9":{"start":{"line":96,"column":13},"end":{"line":96,"column":null}},"10":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}}},"fnMap":{"0":{"name":"localizeClearFilters","decl":{"start":{"line":70,"column":16},"end":{"line":70,"column":37}},"loc":{"start":{"line":70,"column":62},"end":{"line":72,"column":null}},"line":70},"1":{"name":"buildRecencyLabels","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":35}},"loc":{"start":{"line":75,"column":76},"end":{"line":82,"column":null}},"line":75},"2":{"name":"heroMetricLabels","decl":{"start":{"line":85,"column":16},"end":{"line":85,"column":33}},"loc":{"start":{"line":85,"column":126},"end":{"line":87,"column":null}},"line":85},"3":{"name":"toChromeLang","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":29}},"loc":{"start":{"line":90,"column":56},"end":{"line":92,"column":null}},"line":90},"4":{"name":"toBcp47","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":24}},"loc":{"start":{"line":95,"column":76},"end":{"line":98,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":71,"column":9},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":9},"end":{"line":71,"column":42}},{"start":{"line":71,"column":42},"end":{"line":71,"column":null}}],"line":71},"1":{"loc":{"start":{"line":76,"column":14},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":14},"end":{"line":76,"column":41}},{"start":{"line":76,"column":41},"end":{"line":76,"column":null}}],"line":76},"2":{"loc":{"start":{"line":86,"column":9},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":9},"end":{"line":86,"column":40}},{"start":{"line":86,"column":40},"end":{"line":86,"column":null}}],"line":86},"3":{"loc":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"4":{"loc":{"start":{"line":97,"column":9},"end":{"line":97,"column":null}},"type":"cond-expr","locations":[{"start":{"line":97,"column":25},"end":{"line":97,"column":32}},{"start":{"line":97,"column":32},"end":{"line":97,"column":null}}],"line":97}},"s":{"0":7,"1":7,"2":7,"3":34,"4":34,"5":34,"6":34,"7":495,"8":369,"9":2,"10":367},"f":{"0":34,"1":34,"2":34,"3":495,"4":369},"b":{"0":[34,1],"1":[34,1],"2":[34,1],"3":[2,367],"4":[21,346]},"meta":{"lastBranch":5,"lastFunction":5,"lastStatement":11,"seen":{"s:16:70:31:Infinity":0,"s:34:120:49:Infinity":1,"s:52:136:67:Infinity":2,"f:70:16:70:37":0,"s:71:2:71:Infinity":3,"b:71:9:71:42:71:42:71:Infinity":0,"f:75:16:75:35":1,"s:76:14:76:Infinity":4,"b:76:14:76:41:76:41:76:Infinity":1,"s:77:2:81:Infinity":5,"f:85:16:85:33":2,"s:86:2:86:Infinity":6,"b:86:9:86:40:86:40:86:Infinity":2,"f:90:16:90:29":3,"s:91:2:91:Infinity":7,"f:95:16:95:24":4,"b:96:2:96:Infinity:undefined:undefined:undefined:undefined":3,"s:96:2:96:Infinity":8,"s:96:13:96:Infinity":9,"s:97:2:97:Infinity":10,"b:97:25:97:32:97:32:97:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/index.ts","statementMap":{"0":{"start":{"line":33,"column":39},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":22},"end":{"line":34,"column":null}},"2":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"3":{"start":{"line":38,"column":24},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"5":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":43},"end":{"line":44,"column":null}},"7":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":60,"column":null}},"9":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"10":{"start":{"line":65,"column":29},"end":{"line":65,"column":null}},"11":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"12":{"start":{"line":66,"column":29},"end":{"line":66,"column":35}},"13":{"start":{"line":66,"column":52},"end":{"line":66,"column":70}},"14":{"start":{"line":71,"column":49},"end":{"line":71,"column":null}},"15":{"start":{"line":72,"column":2},"end":{"line":74,"column":null}},"16":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"17":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"18":{"start":{"line":81,"column":19},"end":{"line":81,"column":null}},"19":{"start":{"line":96,"column":32},"end":{"line":96,"column":null}},"20":{"start":{"line":97,"column":19},"end":{"line":97,"column":null}},"21":{"start":{"line":98,"column":16},"end":{"line":98,"column":null}},"22":{"start":{"line":99,"column":30},"end":{"line":99,"column":null}},"23":{"start":{"line":101,"column":26},"end":{"line":101,"column":null}},"24":{"start":{"line":102,"column":22},"end":{"line":102,"column":null}},"25":{"start":{"line":103,"column":21},"end":{"line":103,"column":null}},"26":{"start":{"line":104,"column":23},"end":{"line":104,"column":null}},"27":{"start":{"line":106,"column":21},"end":{"line":106,"column":null}},"28":{"start":{"line":107,"column":19},"end":{"line":107,"column":null}},"29":{"start":{"line":108,"column":17},"end":{"line":108,"column":null}},"30":{"start":{"line":110,"column":17},"end":{"line":131,"column":null}},"31":{"start":{"line":133,"column":15},"end":{"line":133,"column":null}},"32":{"start":{"line":134,"column":18},"end":{"line":134,"column":null}},"33":{"start":{"line":135,"column":15},"end":{"line":135,"column":null}},"34":{"start":{"line":136,"column":17},"end":{"line":136,"column":null}},"35":{"start":{"line":137,"column":22},"end":{"line":137,"column":null}},"36":{"start":{"line":138,"column":21},"end":{"line":138,"column":null}},"37":{"start":{"line":139,"column":14},"end":{"line":139,"column":null}},"38":{"start":{"line":144,"column":15},"end":{"line":164,"column":null}},"39":{"start":{"line":166,"column":2},"end":{"line":169,"column":null}}},"fnMap":{"0":{"name":"indexFilename","decl":{"start":{"line":37,"column":9},"end":{"line":37,"column":23}},"loc":{"start":{"line":37,"column":48},"end":{"line":40,"column":null}},"line":37},"1":{"name":"buildExcerpt","decl":{"start":{"line":43,"column":9},"end":{"line":43,"column":22}},"loc":{"start":{"line":43,"column":51},"end":{"line":46,"column":null}},"line":43},"2":{"name":"toDisplayData","decl":{"start":{"line":49,"column":9},"end":{"line":49,"column":23}},"loc":{"start":{"line":49,"column":67},"end":{"line":61,"column":null}},"line":49},"3":{"name":"pickLatestDate","decl":{"start":{"line":64,"column":9},"end":{"line":64,"column":24}},"loc":{"start":{"line":64,"column":74},"end":{"line":67,"column":null}},"line":64},"4":{"name":"(anonymous_4)","decl":{"start":{"line":66,"column":18},"end":{"line":66,"column":23}},"loc":{"start":{"line":66,"column":29},"end":{"line":66,"column":35}},"line":66},"5":{"name":"(anonymous_5)","decl":{"start":{"line":66,"column":37},"end":{"line":66,"column":43}},"loc":{"start":{"line":66,"column":52},"end":{"line":66,"column":70}},"line":66},"6":{"name":"buildHreflangAlternates","decl":{"start":{"line":70,"column":9},"end":{"line":70,"column":70}},"loc":{"start":{"line":70,"column":70},"end":{"line":76,"column":null}},"line":70},"7":{"name":"generateIndexHTML","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"loc":{"start":{"line":95,"column":10},"end":{"line":170,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":38},"1":{"loc":{"start":{"line":39,"column":18},"end":{"line":39,"column":52}},"type":"cond-expr","locations":[{"start":{"line":39,"column":37},"end":{"line":39,"column":44}},{"start":{"line":39,"column":44},"end":{"line":39,"column":52}}],"line":39},"2":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"3":{"loc":{"start":{"line":56,"column":24},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":24},"end":{"line":56,"column":48}},{"start":{"line":56,"column":48},"end":{"line":56,"column":null}}],"line":56},"4":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"5":{"loc":{"start":{"line":119,"column":13},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":32},"end":{"line":119,"column":45}},{"start":{"line":119,"column":45},"end":{"line":119,"column":null}}],"line":119},"6":{"loc":{"start":{"line":121,"column":50},"end":{"line":121,"column":110}},"type":"cond-expr","locations":[{"start":{"line":121,"column":69},"end":{"line":121,"column":84}},{"start":{"line":121,"column":84},"end":{"line":121,"column":110}}],"line":121},"7":{"loc":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":24},"end":{"line":145,"column":58}},{"start":{"line":145,"column":58},"end":{"line":145,"column":null}}],"line":145}},"s":{"0":6,"1":6,"2":495,"3":39,"4":456,"5":12245,"6":11953,"7":292,"8":12245,"9":33,"10":0,"11":33,"12":12245,"13":12212,"14":33,"15":33,"16":462,"17":33,"18":6,"19":33,"20":33,"21":33,"22":33,"23":33,"24":33,"25":33,"26":33,"27":33,"28":33,"29":33,"30":33,"31":33,"32":33,"33":33,"34":33,"35":33,"36":33,"37":33,"38":33,"39":33},"f":{"0":495,"1":12245,"2":12245,"3":33,"4":12245,"5":12212,"6":33,"7":33},"b":{"0":[39,456],"1":[35,421],"2":[11953,292],"3":[12245,75],"4":[0,33],"5":[6,27],"6":[6,27],"7":[0,33]},"meta":{"lastBranch":8,"lastFunction":8,"lastStatement":40,"seen":{"s:33:39:33:Infinity":0,"s:34:22:34:Infinity":1,"f:37:9:37:23":0,"b:38:2:38:Infinity:undefined:undefined:undefined:undefined":0,"s:38:2:38:Infinity":2,"s:38:24:38:Infinity":3,"s:39:2:39:Infinity":4,"b:39:37:39:44:39:44:39:52":1,"f:43:9:43:22":1,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":2,"s:44:2:44:Infinity":5,"s:44:43:44:Infinity":6,"s:45:2:45:Infinity":7,"f:49:9:49:23":2,"s:50:2:60:Infinity":8,"b:56:24:56:48:56:48:56:Infinity":3,"f:64:9:64:24":3,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":4,"s:65:2:65:Infinity":9,"s:65:29:65:Infinity":10,"s:66:2:66:Infinity":11,"f:66:18:66:23":4,"s:66:29:66:35":12,"f:66:37:66:43":5,"s:66:52:66:70":13,"f:70:9:70:70":6,"s:71:49:71:Infinity":14,"s:72:2:74:Infinity":15,"s:73:4:73:Infinity":16,"s:75:2:75:Infinity":17,"s:81:19:81:Infinity":18,"f:91:16:91:Infinity":7,"s:96:32:96:Infinity":19,"s:97:19:97:Infinity":20,"s:98:16:98:Infinity":21,"s:99:30:99:Infinity":22,"s:101:26:101:Infinity":23,"s:102:22:102:Infinity":24,"s:103:21:103:Infinity":25,"s:104:23:104:Infinity":26,"s:106:21:106:Infinity":27,"s:107:19:107:Infinity":28,"s:108:17:108:Infinity":29,"s:110:17:131:Infinity":30,"b:119:32:119:45:119:45:119:Infinity":5,"b:121:69:121:84:121:84:121:110":6,"s:133:15:133:Infinity":31,"s:134:18:134:Infinity":32,"s:135:15:135:Infinity":33,"s:136:17:136:Infinity":34,"s:137:22:137:Infinity":35,"s:138:21:138:Infinity":36,"s:139:14:139:Infinity":37,"s:144:15:164:Infinity":38,"b:145:24:145:58:145:58:145:Infinity":7,"s:166:2:169:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/page-sections.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/page-sections.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":31,"column":16},"end":{"line":34,"column":null}},"2":{"start":{"line":31,"column":36},"end":{"line":34,"column":18}},"3":{"start":{"line":35,"column":2},"end":{"line":38,"column":null}}},"fnMap":{"0":{"name":"renderAiNewsroomSection","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":40}},"loc":{"start":{"line":20,"column":70},"end":{"line":27,"column":null}},"line":20},"1":{"name":"renderFaqSection","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":33}},"loc":{"start":{"line":30,"column":93},"end":{"line":41,"column":null}},"line":30},"2":{"name":"(anonymous_2)","decl":{"start":{"line":31,"column":25},"end":{"line":31,"column":30}},"loc":{"start":{"line":31,"column":36},"end":{"line":34,"column":18}},"line":31}},"branchMap":{},"s":{"0":33,"1":33,"2":165,"3":33},"f":{"0":33,"1":33,"2":165},"b":{},"meta":{"lastBranch":0,"lastFunction":3,"lastStatement":4,"seen":{"f:20:16:20:40":0,"s:21:2:24:Infinity":0,"f:30:16:30:33":1,"s:31:16:34:Infinity":1,"f:31:25:31:30":2,"s:31:36:34:18":2,"s:35:2:38:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/rtl.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/rtl.ts","statementMap":{"0":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"1":{"start":{"line":13,"column":14},"end":{"line":13,"column":null}},"2":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":47,"column":null}}},"fnMap":{"0":{"name":"generateRTLStyles","decl":{"start":{"line":12,"column":16},"end":{"line":12,"column":34}},"loc":{"start":{"line":12,"column":70},"end":{"line":32,"column":null}},"line":12},"1":{"name":"newsPageExtraRtlStyle","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":38}},"loc":{"start":{"line":39,"column":62},"end":{"line":48,"column":null}},"line":39}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"type":"if","locations":[{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},{"start":{},"end":{}}],"line":13},"1":{"loc":{"start":{"line":40,"column":9},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":17},"end":{"line":47,"column":null}},{"start":{"line":47,"column":4},"end":{"line":47,"column":null}}],"line":40}},"s":{"0":4,"1":2,"2":2,"3":33},"f":{"0":4,"1":33},"b":{"0":[2,2],"1":[4,29]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":4,"seen":{"f:12:16:12:34":0,"b:13:2:13:Infinity:undefined:undefined:undefined:undefined":0,"s:13:2:13:Infinity":0,"s:13:14:13:Infinity":1,"s:15:2:15:Infinity":2,"f:39:16:39:38":1,"s:40:2:47:Infinity":3,"b:40:17:47:Infinity:47:4:47:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/seo-fallback.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/seo-fallback.ts","statementMap":{"0":{"start":{"line":20,"column":27},"end":{"line":20,"column":null}},"1":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":16},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":16},"end":{"line":31,"column":161}},"4":{"start":{"line":33,"column":19},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}}},"fnMap":{"0":{"name":"renderSeoFallback","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":null}},"loc":{"start":{"line":27,"column":10},"end":{"line":42,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":31,"column":5},"end":{"line":31,"column":10}},"loc":{"start":{"line":31,"column":16},"end":{"line":31,"column":161}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":19},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},{"start":{"line":35,"column":6},"end":{"line":35,"column":null}}],"line":33},"1":{"loc":{"start":{"line":34,"column":36},"end":{"line":34,"column":74}},"type":"cond-expr","locations":[{"start":{"line":34,"column":55},"end":{"line":34,"column":60}},{"start":{"line":34,"column":60},"end":{"line":34,"column":74}}],"line":34}},"s":{"0":6,"1":33,"2":33,"3":5675,"4":33,"5":33},"f":{"0":33,"1":5675},"b":{"0":[28,5],"1":[2,26]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":6,"seen":{"s:20:27:20:Infinity":0,"f:23:16:23:Infinity":0,"s:28:22:28:Infinity":1,"s:29:16:32:Infinity":2,"f:31:5:31:10":1,"s:31:16:31:161":3,"s:33:19:35:Infinity":4,"b:34:6:34:Infinity:35:6:35:Infinity":0,"b:34:55:34:60:34:60:34:74":1,"s:36:2:40:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/horizon-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/horizon-context.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"2":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"3":{"start":{"line":100,"column":42},"end":{"line":100,"column":null}},"4":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"5":{"start":{"line":106,"column":14},"end":{"line":106,"column":null}},"6":{"start":{"line":107,"column":15},"end":{"line":107,"column":null}},"7":{"start":{"line":108,"column":14},"end":{"line":108,"column":null}},"8":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"9":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"10":{"start":{"line":117,"column":14},"end":{"line":117,"column":null}},"11":{"start":{"line":118,"column":16},"end":{"line":118,"column":null}},"12":{"start":{"line":118,"column":38},"end":{"line":118,"column":49}},"13":{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},"14":{"start":{"line":120,"column":4},"end":{"line":122,"column":null}},"15":{"start":{"line":121,"column":67},"end":{"line":121,"column":71}},"16":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"17":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"18":{"start":{"line":133,"column":15},"end":{"line":133,"column":null}},"19":{"start":{"line":134,"column":16},"end":{"line":134,"column":null}},"20":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"21":{"start":{"line":143,"column":14},"end":{"line":143,"column":null}},"22":{"start":{"line":144,"column":15},"end":{"line":144,"column":null}},"23":{"start":{"line":145,"column":20},"end":{"line":145,"column":null}},"24":{"start":{"line":146,"column":18},"end":{"line":146,"column":null}},"25":{"start":{"line":147,"column":2},"end":{"line":147,"column":null}},"26":{"start":{"line":160,"column":12},"end":{"line":160,"column":null}},"27":{"start":{"line":161,"column":15},"end":{"line":161,"column":null}},"28":{"start":{"line":162,"column":16},"end":{"line":162,"column":null}},"29":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"30":{"start":{"line":163,"column":19},"end":{"line":163,"column":null}},"31":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"32":{"start":{"line":164,"column":18},"end":{"line":164,"column":null}},"33":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"34":{"start":{"line":176,"column":12},"end":{"line":176,"column":null}},"35":{"start":{"line":177,"column":12},"end":{"line":177,"column":null}},"36":{"start":{"line":178,"column":14},"end":{"line":178,"column":null}},"37":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"38":{"start":{"line":179,"column":65},"end":{"line":179,"column":null}},"39":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"40":{"start":{"line":180,"column":42},"end":{"line":180,"column":null}},"41":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"42":{"start":{"line":181,"column":73},"end":{"line":181,"column":null}},"43":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"44":{"start":{"line":199,"column":22},"end":{"line":199,"column":null}},"45":{"start":{"line":200,"column":14},"end":{"line":200,"column":null}},"46":{"start":{"line":201,"column":2},"end":{"line":208,"column":null}},"47":{"start":{"line":215,"column":37},"end":{"line":223,"column":null}},"48":{"start":{"line":236,"column":13},"end":{"line":236,"column":null}},"49":{"start":{"line":237,"column":6},"end":{"line":243,"column":null}},"50":{"start":{"line":238,"column":2},"end":{"line":242,"column":null}},"51":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"52":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"53":{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},"54":{"start":{"line":245,"column":32},"end":{"line":245,"column":null}},"55":{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},"56":{"start":{"line":247,"column":4},"end":{"line":247,"column":null}},"57":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"58":{"start":{"line":250,"column":14},"end":{"line":250,"column":null}},"59":{"start":{"line":251,"column":2},"end":{"line":251,"column":null}}},"fnMap":{"0":{"name":"loadRegistry","decl":{"start":{"line":105,"column":16},"end":{"line":105,"column":53}},"loc":{"start":{"line":105,"column":53},"end":{"line":111,"column":null}},"line":105},"1":{"name":"getArticleType","decl":{"start":{"line":116,"column":16},"end":{"line":116,"column":31}},"loc":{"start":{"line":116,"column":61},"end":{"line":125,"column":null}},"line":116},"2":{"name":"(anonymous_2)","decl":{"start":{"line":118,"column":26},"end":{"line":118,"column":32}},"loc":{"start":{"line":118,"column":38},"end":{"line":118,"column":49}},"line":118},"3":{"name":"(anonymous_3)","decl":{"start":{"line":121,"column":56},"end":{"line":121,"column":61}},"loc":{"start":{"line":121,"column":67},"end":{"line":121,"column":71}},"line":121},"4":{"name":"daysToElection","decl":{"start":{"line":131,"column":16},"end":{"line":131,"column":31}},"loc":{"start":{"line":131,"column":60},"end":{"line":136,"column":null}},"line":131},"5":{"name":"activeCycleAnchor","decl":{"start":{"line":142,"column":16},"end":{"line":142,"column":34}},"loc":{"start":{"line":142,"column":75},"end":{"line":148,"column":null}},"line":142},"6":{"name":"weoVintage","decl":{"start":{"line":159,"column":16},"end":{"line":159,"column":27}},"loc":{"start":{"line":159,"column":56},"end":{"line":166,"column":null}},"line":159},"7":{"name":"sessionPhase","decl":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"loc":{"start":{"line":175,"column":57},"end":{"line":183,"column":null}},"line":175},"8":{"name":"horizonContext","decl":{"start":{"line":198,"column":16},"end":{"line":198,"column":31}},"loc":{"start":{"line":198,"column":84},"end":{"line":209,"column":null}},"line":198},"9":{"name":"(anonymous_9)","decl":{"start":{"line":237,"column":6},"end":{"line":237,"column":22}},"loc":{"start":{"line":237,"column":22},"end":{"line":243,"column":1}},"line":237}},"branchMap":{"0":{"loc":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":106},"1":{"loc":{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":119},"2":{"loc":{"start":{"line":147,"column":9},"end":{"line":147,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":47},"end":{"line":147,"column":56}},{"start":{"line":147,"column":56},"end":{"line":147,"column":null}}],"line":147},"3":{"loc":{"start":{"line":147,"column":9},"end":{"line":147,"column":47}},"type":"binary-expr","locations":[{"start":{"line":147,"column":9},"end":{"line":147,"column":30}},{"start":{"line":147,"column":30},"end":{"line":147,"column":47}}],"line":147},"4":{"loc":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"5":{"loc":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":164},"6":{"loc":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":179},"7":{"loc":{"start":{"line":179,"column":6},"end":{"line":179,"column":65}},"type":"binary-expr","locations":[{"start":{"line":179,"column":6},"end":{"line":179,"column":17}},{"start":{"line":179,"column":17},"end":{"line":179,"column":29}},{"start":{"line":179,"column":29},"end":{"line":179,"column":42}},{"start":{"line":179,"column":42},"end":{"line":179,"column":54}},{"start":{"line":179,"column":54},"end":{"line":179,"column":65}}],"line":179},"8":{"loc":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},{"start":{},"end":{}}],"line":180},"9":{"loc":{"start":{"line":180,"column":7},"end":{"line":180,"column":42}},"type":"binary-expr","locations":[{"start":{"line":180,"column":7},"end":{"line":180,"column":19}},{"start":{"line":180,"column":19},"end":{"line":180,"column":33}},{"start":{"line":180,"column":33},"end":{"line":180,"column":42}}],"line":180},"10":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"11":{"loc":{"start":{"line":181,"column":6},"end":{"line":181,"column":73}},"type":"binary-expr","locations":[{"start":{"line":181,"column":6},"end":{"line":181,"column":17}},{"start":{"line":181,"column":17},"end":{"line":181,"column":28}},{"start":{"line":181,"column":28},"end":{"line":181,"column":39}},{"start":{"line":181,"column":39},"end":{"line":181,"column":51}},{"start":{"line":181,"column":51},"end":{"line":181,"column":62}},{"start":{"line":181,"column":62},"end":{"line":181,"column":73}}],"line":181},"12":{"loc":{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},"type":"if","locations":[{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},{"start":{},"end":{}}],"line":244},"13":{"loc":{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},"type":"if","locations":[{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},{"start":{},"end":{}}],"line":246},"14":{"loc":{"start":{"line":246,"column":6},"end":{"line":246,"column":31}},"type":"binary-expr","locations":[{"start":{"line":246,"column":6},"end":{"line":246,"column":17}},{"start":{"line":246,"column":17},"end":{"line":246,"column":31}}],"line":246}},"s":{"0":1,"1":1,"2":1,"3":1,"4":21,"5":20,"6":1,"7":1,"8":1,"9":1,"10":6,"11":6,"12":63,"13":6,"14":1,"15":13,"16":5,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"23":6,"24":6,"25":6,"26":10,"27":10,"28":10,"29":10,"30":2,"31":8,"32":8,"33":2,"34":12,"35":12,"36":12,"37":12,"38":3,"39":9,"40":2,"41":7,"42":3,"43":4,"44":3,"45":3,"46":3,"47":1,"48":1,"49":1,"50":1,"51":1,"52":0,"53":1,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0},"f":{"0":21,"1":6,"2":63,"3":13,"4":6,"5":6,"6":10,"7":12,"8":3,"9":1},"b":{"0":[20,1],"1":[1,5],"2":[2,4],"3":[6,2],"4":[2,8],"5":[6,2],"6":[3,9],"7":[12,11,11,10,2],"8":[2,7],"9":[9,1,8],"10":[3,4],"11":[7,7,6,6,4,0],"12":[0,1],"13":[0,0],"14":[0,0]},"meta":{"lastBranch":15,"lastFunction":10,"lastStatement":60,"seen":{"s:38:19:38:Infinity":0,"s:39:18:39:Infinity":1,"s:40:17:40:Infinity":2,"s:100:42:100:Infinity":3,"f:105:16:105:53":0,"b:106:2:106:Infinity:undefined:undefined:undefined:undefined":0,"s:106:2:106:Infinity":4,"s:106:14:106:Infinity":5,"s:107:15:107:Infinity":6,"s:108:14:108:Infinity":7,"s:109:2:109:Infinity":8,"s:110:2:110:Infinity":9,"f:116:16:116:31":1,"s:117:14:117:Infinity":10,"s:118:16:118:Infinity":11,"f:118:26:118:32":2,"s:118:38:118:49":12,"b:119:2:123:Infinity:undefined:undefined:undefined:undefined":1,"s:119:2:123:Infinity":13,"s:120:4:122:Infinity":14,"f:121:56:121:61":3,"s:121:67:121:71":15,"s:124:2:124:Infinity":16,"f:131:16:131:31":4,"s:132:14:132:Infinity":17,"s:133:15:133:Infinity":18,"s:134:16:134:Infinity":19,"s:135:2:135:Infinity":20,"f:142:16:142:34":5,"s:143:14:143:Infinity":21,"s:144:15:144:Infinity":22,"s:145:20:145:Infinity":23,"s:146:18:146:Infinity":24,"s:147:2:147:Infinity":25,"b:147:47:147:56:147:56:147:Infinity":2,"b:147:9:147:30:147:30:147:47":3,"f:159:16:159:27":6,"s:160:12:160:Infinity":26,"s:161:15:161:Infinity":27,"s:162:16:162:Infinity":28,"b:163:2:163:Infinity:undefined:undefined:undefined:undefined":4,"s:163:2:163:Infinity":29,"s:163:19:163:Infinity":30,"b:164:2:164:Infinity:undefined:undefined:undefined:undefined":5,"s:164:2:164:Infinity":31,"s:164:18:164:Infinity":32,"s:165:2:165:Infinity":33,"f:173:16:173:Infinity":7,"s:176:12:176:Infinity":34,"s:177:12:177:Infinity":35,"s:178:14:178:Infinity":36,"b:179:2:179:Infinity:undefined:undefined:undefined:undefined":6,"s:179:2:179:Infinity":37,"b:179:6:179:17:179:17:179:29:179:29:179:42:179:42:179:54:179:54:179:65":7,"s:179:65:179:Infinity":38,"b:180:2:180:Infinity:undefined:undefined:undefined:undefined":8,"s:180:2:180:Infinity":39,"b:180:7:180:19:180:19:180:33:180:33:180:42":9,"s:180:42:180:Infinity":40,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":10,"s:181:2:181:Infinity":41,"b:181:6:181:17:181:17:181:28:181:28:181:39:181:39:181:51:181:51:181:62:181:62:181:73":11,"s:181:73:181:Infinity":42,"s:182:2:182:Infinity":43,"f:198:16:198:31":8,"s:199:22:199:Infinity":44,"s:200:14:200:Infinity":45,"s:201:2:208:Infinity":46,"s:215:37:223:Infinity":47,"s:236:13:236:Infinity":48,"s:237:6:243:Infinity":49,"f:237:6:237:22":9,"s:238:2:242:Infinity":50,"s:239:4:239:Infinity":51,"s:241:4:241:Infinity":52,"b:244:0:252:Infinity:undefined:undefined:undefined:undefined":12,"s:244:0:252:Infinity":53,"s:245:32:245:Infinity":54,"b:246:2:249:Infinity:undefined:undefined:undefined:undefined":13,"s:246:2:249:Infinity":55,"b:246:6:246:17:246:17:246:31":14,"s:247:4:247:Infinity":56,"s:248:4:248:Infinity":57,"s:250:14:250:Infinity":58,"s:251:2:251:Infinity":59}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/schema-ld.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/schema-ld.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":60,"column":null}},"1":{"start":{"line":24,"column":75},"end":{"line":59,"column":6}},"2":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}},"3":{"start":{"line":77,"column":2},"end":{"line":83,"column":null}},"4":{"start":{"line":88,"column":2},"end":{"line":106,"column":null}},"5":{"start":{"line":115,"column":2},"end":{"line":120,"column":null}}},"fnMap":{"0":{"name":"buildItemListLd","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":null}},"loc":{"start":{"line":17,"column":11},"end":{"line":61,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":24,"column":50},"end":{"line":24,"column":55}},"loc":{"start":{"line":24,"column":75},"end":{"line":59,"column":6}},"line":24},"2":{"name":"buildBreadcrumbLd","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":34}},"loc":{"start":{"line":64,"column":83},"end":{"line":73,"column":null}},"line":64},"3":{"name":"buildOrganizationLd","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":47}},"loc":{"start":{"line":76,"column":47},"end":{"line":84,"column":null}},"line":76},"4":{"name":"buildWebsiteLd","decl":{"start":{"line":87,"column":16},"end":{"line":87,"column":31}},"loc":{"start":{"line":87,"column":80},"end":{"line":107,"column":null}},"line":87},"5":{"name":"buildAllJsonLd","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"loc":{"start":{"line":114,"column":13},"end":{"line":121,"column":null}},"line":114}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":21},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":12},"end":{"line":36,"column":null}},{"start":{"line":37,"column":12},"end":{"line":37,"column":null}}],"line":35},"1":{"loc":{"start":{"line":38,"column":28},"end":{"line":38,"column":55}},"type":"binary-expr","locations":[{"start":{"line":38,"column":28},"end":{"line":38,"column":44}},{"start":{"line":38,"column":44},"end":{"line":38,"column":55}}],"line":38},"2":{"loc":{"start":{"line":51,"column":12},"end":{"line":51,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":31},"end":{"line":51,"column":64}},{"start":{"line":51,"column":64},"end":{"line":51,"column":null}}],"line":51},"3":{"loc":{"start":{"line":94,"column":17},"end":{"line":94,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":17},"end":{"line":94,"column":43}},{"start":{"line":94,"column":43},"end":{"line":94,"column":null}}],"line":94}},"s":{"0":33,"1":330,"2":33,"3":33,"4":33,"5":33},"f":{"0":33,"1":330,"2":33,"3":33,"4":33,"5":33},"b":{"0":[192,138],"1":[330,0],"2":[280,50],"3":[33,0]},"meta":{"lastBranch":4,"lastFunction":6,"lastStatement":6,"seen":{"f:14:16:14:Infinity":0,"s:18:2:60:Infinity":0,"f:24:50:24:55":1,"s:24:75:59:6":1,"b:36:12:36:Infinity:37:12:37:Infinity":0,"b:38:28:38:44:38:44:38:55":1,"b:51:31:51:64:51:64:51:Infinity":2,"f:64:16:64:34":2,"s:65:2:72:Infinity":2,"f:76:16:76:47":3,"s:77:2:83:Infinity":3,"f:87:16:87:31":4,"s:88:2:106:Infinity":4,"b:94:17:94:43:94:43:94:Infinity":3,"f:110:16:110:Infinity":5,"s:115:2:120:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/html-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/html-utils.ts","statementMap":{"0":{"start":{"line":10,"column":58},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":28},"end":{"line":18,"column":null}},"2":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":28,"column":13},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":2},"end":{"line":32,"column":null}},"5":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"6":{"start":{"line":36,"column":59},"end":{"line":50,"column":null}},"7":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"8":{"start":{"line":63,"column":13},"end":{"line":63,"column":null}},"9":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"10":{"start":{"line":67,"column":2},"end":{"line":74,"column":null}},"11":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"12":{"start":{"line":69,"column":4},"end":{"line":73,"column":null}},"13":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"14":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"15":{"start":{"line":76,"column":2},"end":{"line":83,"column":null}},"16":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"17":{"start":{"line":78,"column":4},"end":{"line":82,"column":null}},"18":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"19":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"20":{"start":{"line":85,"column":2},"end":{"line":88,"column":null}},"21":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"22":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}}},"fnMap":{"0":{"name":"escapeHtml","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":27}},"loc":{"start":{"line":27,"column":77},"end":{"line":33,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"loc":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"line":31},"2":{"name":"decodeHtmlEntities","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":35}},"loc":{"start":{"line":62,"column":76},"end":{"line":91,"column":null}},"line":62},"3":{"name":"(anonymous_3)","decl":{"start":{"line":67,"column":26},"end":{"line":67,"column":40}},"loc":{"start":{"line":67,"column":81},"end":{"line":74,"column":3}},"line":67},"4":{"name":"(anonymous_4)","decl":{"start":{"line":76,"column":26},"end":{"line":76,"column":50}},"loc":{"start":{"line":76,"column":90},"end":{"line":83,"column":3}},"line":76},"5":{"name":"(anonymous_5)","decl":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"loc":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"line":87}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":27},"end":{"line":31,"column":49}},{"start":{"line":31,"column":49},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"3":{"loc":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"type":"binary-expr","locations":[{"start":{"line":87,"column":27},"end":{"line":87,"column":50}},{"start":{"line":87,"column":50},"end":{"line":87,"column":null}}],"line":87}},"s":{"0":66,"1":66,"2":24741,"3":3,"4":24738,"5":826,"6":66,"7":121864,"8":17,"9":121847,"10":121847,"11":5887,"12":5887,"13":5887,"14":0,"15":121847,"16":7,"17":7,"18":7,"19":0,"20":121847,"21":1925,"22":121847},"f":{"0":24741,"1":826,"2":121864,"3":5887,"4":7,"5":1925},"b":{"0":[3,24738],"1":[826,0],"2":[17,121847],"3":[1925,0]},"meta":{"lastBranch":4,"lastFunction":6,"lastStatement":23,"seen":{"s:10:58:16:Infinity":0,"s:18:28:18:Infinity":1,"f:27:16:27:27":0,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:28:Infinity":2,"s:28:13:28:Infinity":3,"s:29:2:32:Infinity":4,"f:30:4:30:Infinity":1,"s:31:27:31:Infinity":5,"b:31:27:31:49:31:49:31:Infinity":1,"s:36:59:50:Infinity":6,"f:62:16:62:35":2,"b:63:2:63:Infinity:undefined:undefined:undefined:undefined":2,"s:63:2:63:Infinity":7,"s:63:13:63:Infinity":8,"s:65:15:65:Infinity":9,"s:67:2:74:Infinity":10,"f:67:26:67:40":3,"s:68:22:68:Infinity":11,"s:69:4:73:Infinity":12,"s:70:6:70:Infinity":13,"s:72:6:72:Infinity":14,"s:76:2:83:Infinity":15,"f:76:26:76:50":4,"s:77:22:77:Infinity":16,"s:78:4:82:Infinity":17,"s:79:6:79:Infinity":18,"s:81:6:81:Infinity":19,"s:85:2:88:Infinity":20,"f:86:4:86:Infinity":5,"s:87:27:87:Infinity":21,"b:87:27:87:50:87:50:87:Infinity":3,"s:90:2:90:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-codes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-codes.ts","statementMap":{"0":{"start":{"line":36,"column":29},"end":{"line":46,"column":null}},"1":{"start":{"line":56,"column":66},"end":{"line":74,"column":null}},"2":{"start":{"line":81,"column":66},"end":{"line":83,"column":null}},"3":{"start":{"line":82,"column":76},"end":{"line":82,"column":88}},"4":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"5":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"6":{"start":{"line":101,"column":16},"end":{"line":101,"column":null}},"7":{"start":{"line":102,"column":15},"end":{"line":102,"column":null}},"8":{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},"9":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"10":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"11":{"start":{"line":115,"column":2},"end":{"line":115,"column":null}},"12":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"13":{"start":{"line":128,"column":66},"end":{"line":148,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":82,"column":54},"end":{"line":82,"column":59}},"loc":{"start":{"line":82,"column":76},"end":{"line":82,"column":88}},"line":82},"1":{"name":"toDatamapperCode","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":33}},"loc":{"start":{"line":90,"column":55},"end":{"line":93,"column":null}},"line":90},"2":{"name":"toImfAreaCode","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":30}},"loc":{"start":{"line":100,"column":52},"end":{"line":111,"column":null}},"line":100},"3":{"name":"isKnownIso3","decl":{"start":{"line":114,"column":16},"end":{"line":114,"column":28}},"loc":{"start":{"line":114,"column":51},"end":{"line":116,"column":null}},"line":114},"4":{"name":"listKnownIso3Codes","decl":{"start":{"line":123,"column":16},"end":{"line":123,"column":56}},"loc":{"start":{"line":123,"column":56},"end":{"line":125,"column":null}},"line":123}},"branchMap":{"0":{"loc":{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},{"start":{},"end":{}}],"line":103}},"s":{"0":20,"1":20,"2":20,"3":340,"4":38,"5":38,"6":6,"7":6,"8":6,"9":3,"10":3,"11":4,"12":3,"13":20},"f":{"0":340,"1":38,"2":6,"3":4,"4":3},"b":{"0":[3,3]},"meta":{"lastBranch":1,"lastFunction":5,"lastStatement":14,"seen":{"s:36:29:46:Infinity":0,"s:56:66:74:Infinity":1,"s:81:66:83:Infinity":2,"f:82:54:82:59":0,"s:82:76:82:88":3,"f:90:16:90:33":1,"s:91:16:91:Infinity":4,"s:92:2:92:Infinity":5,"f:100:16:100:30":2,"s:101:16:101:Infinity":6,"s:102:15:102:Infinity":7,"b:103:2:109:Infinity:undefined:undefined:undefined:undefined":0,"s:103:2:109:Infinity":8,"s:104:4:108:Infinity":9,"s:110:2:110:Infinity":10,"f:114:16:114:28":3,"s:115:2:115:Infinity":11,"f:123:16:123:56":4,"s:124:2:124:Infinity":12,"s:128:66:148:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-context.ts","statementMap":{"0":{"start":{"line":83,"column":62},"end":{"line":321,"column":null}},"1":{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},"2":{"start":{"line":331,"column":34},"end":{"line":331,"column":null}},"3":{"start":{"line":332,"column":18},"end":{"line":332,"column":null}},"4":{"start":{"line":332,"column":43},"end":{"line":332,"column":58}},"5":{"start":{"line":333,"column":2},"end":{"line":337,"column":null}},"6":{"start":{"line":334,"column":4},"end":{"line":336,"column":null}},"7":{"start":{"line":335,"column":6},"end":{"line":335,"column":null}},"8":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"9":{"start":{"line":344,"column":16},"end":{"line":344,"column":null}},"10":{"start":{"line":345,"column":2},"end":{"line":347,"column":null}},"11":{"start":{"line":346,"column":4},"end":{"line":346,"column":null}},"12":{"start":{"line":346,"column":37},"end":{"line":346,"column":62}},"13":{"start":{"line":351,"column":32},"end":{"line":357,"column":null}},"14":{"start":{"line":361,"column":2},"end":{"line":361,"column":null}},"15":{"start":{"line":369,"column":2},"end":{"line":369,"column":null}},"16":{"start":{"line":388,"column":18},"end":{"line":388,"column":null}},"17":{"start":{"line":389,"column":18},"end":{"line":389,"column":null}},"18":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"19":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"20":{"start":{"line":403,"column":14},"end":{"line":403,"column":null}},"21":{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},"22":{"start":{"line":404,"column":47},"end":{"line":404,"column":null}},"23":{"start":{"line":405,"column":13},"end":{"line":405,"column":null}},"24":{"start":{"line":406,"column":13},"end":{"line":406,"column":null}},"25":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"26":{"start":{"line":416,"column":2},"end":{"line":416,"column":null}},"27":{"start":{"line":416,"column":45},"end":{"line":416,"column":57}},"28":{"start":{"line":435,"column":17},"end":{"line":435,"column":null}},"29":{"start":{"line":436,"column":2},"end":{"line":443,"column":null}},"30":{"start":{"line":437,"column":21},"end":{"line":437,"column":null}},"31":{"start":{"line":438,"column":4},"end":{"line":442,"column":null}},"32":{"start":{"line":439,"column":18},"end":{"line":439,"column":null}},"33":{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},"34":{"start":{"line":440,"column":28},"end":{"line":440,"column":null}},"35":{"start":{"line":441,"column":6},"end":{"line":441,"column":null}},"36":{"start":{"line":444,"column":14},"end":{"line":444,"column":null}},"37":{"start":{"line":445,"column":2},"end":{"line":447,"column":null}},"38":{"start":{"line":446,"column":4},"end":{"line":446,"column":null}},"39":{"start":{"line":448,"column":2},"end":{"line":448,"column":null}},"40":{"start":{"line":457,"column":2},"end":{"line":459,"column":null}},"41":{"start":{"line":458,"column":32},"end":{"line":458,"column":74}}},"fnMap":{"0":{"name":"findImfIndicatorsForDomains","decl":{"start":{"line":328,"column":16},"end":{"line":328,"column":null}},"loc":{"start":{"line":330,"column":34},"end":{"line":338,"column":null}},"line":330},"1":{"name":"(anonymous_1)","decl":{"start":{"line":332,"column":32},"end":{"line":332,"column":37}},"loc":{"start":{"line":332,"column":43},"end":{"line":332,"column":58}},"line":332},"2":{"name":"(anonymous_2)","decl":{"start":{"line":333,"column":24},"end":{"line":333,"column":32}},"loc":{"start":{"line":334,"column":4},"end":{"line":336,"column":null}},"line":334},"3":{"name":"(anonymous_3)","decl":{"start":{"line":334,"column":26},"end":{"line":334,"column":32}},"loc":{"start":{"line":335,"column":6},"end":{"line":335,"column":null}},"line":335},"4":{"name":"(anonymous_4)","decl":{"start":{"line":335,"column":14},"end":{"line":335,"column":20}},"loc":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"line":335},"5":{"name":"findImfIndicatorsForCommittee","decl":{"start":{"line":341,"column":16},"end":{"line":341,"column":null}},"loc":{"start":{"line":343,"column":34},"end":{"line":348,"column":null}},"line":343},"6":{"name":"(anonymous_6)","decl":{"start":{"line":345,"column":24},"end":{"line":345,"column":32}},"loc":{"start":{"line":346,"column":4},"end":{"line":346,"column":null}},"line":346},"7":{"name":"(anonymous_7)","decl":{"start":{"line":346,"column":25},"end":{"line":346,"column":31}},"loc":{"start":{"line":346,"column":37},"end":{"line":346,"column":62}},"line":346},"8":{"name":"imfCountryNameEn","decl":{"start":{"line":360,"column":16},"end":{"line":360,"column":33}},"loc":{"start":{"line":360,"column":55},"end":{"line":362,"column":null}},"line":360},"9":{"name":"imfCitation","decl":{"start":{"line":368,"column":16},"end":{"line":368,"column":28}},"loc":{"start":{"line":368,"column":80},"end":{"line":370,"column":null}},"line":368},"10":{"name":"findImfIndicatorByCode","decl":{"start":{"line":384,"column":16},"end":{"line":384,"column":null}},"loc":{"start":{"line":387,"column":35},"end":{"line":393,"column":null}},"line":387},"11":{"name":"(anonymous_11)","decl":{"start":{"line":390,"column":24},"end":{"line":390,"column":null}},"loc":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"line":391},"12":{"name":"findImfIndicatorByCitation","decl":{"start":{"line":400,"column":16},"end":{"line":400,"column":null}},"loc":{"start":{"line":402,"column":35},"end":{"line":408,"column":null}},"line":402},"13":{"name":"getImfDatabasesInUse","decl":{"start":{"line":415,"column":16},"end":{"line":415,"column":65}},"loc":{"start":{"line":415,"column":65},"end":{"line":417,"column":null}},"line":415},"14":{"name":"(anonymous_14)","decl":{"start":{"line":416,"column":32},"end":{"line":416,"column":37}},"loc":{"start":{"line":416,"column":45},"end":{"line":416,"column":57}},"line":416},"15":{"name":"getImfCommitteeMatrix","decl":{"start":{"line":434,"column":16},"end":{"line":434,"column":80}},"loc":{"start":{"line":434,"column":80},"end":{"line":449,"column":null}},"line":434},"16":{"name":"listImfCitations","decl":{"start":{"line":456,"column":16},"end":{"line":456,"column":54}},"loc":{"start":{"line":456,"column":54},"end":{"line":460,"column":null}},"line":456},"17":{"name":"(anonymous_17)","decl":{"start":{"line":458,"column":19},"end":{"line":458,"column":24}},"loc":{"start":{"line":458,"column":32},"end":{"line":458,"column":74}},"line":458}},"branchMap":{"0":{"loc":{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},"type":"if","locations":[{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},{"start":{},"end":{}}],"line":331},"1":{"loc":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"type":"binary-expr","locations":[{"start":{"line":335,"column":26},"end":{"line":335,"column":60}},{"start":{"line":335,"column":60},"end":{"line":335,"column":90}}],"line":335},"2":{"loc":{"start":{"line":361,"column":9},"end":{"line":361,"column":null}},"type":"binary-expr","locations":[{"start":{"line":361,"column":9},"end":{"line":361,"column":49}},{"start":{"line":361,"column":49},"end":{"line":361,"column":null}}],"line":361},"3":{"loc":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"type":"binary-expr","locations":[{"start":{"line":391,"column":13},"end":{"line":391,"column":41}},{"start":{"line":391,"column":41},"end":{"line":391,"column":null}}],"line":391},"4":{"loc":{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},"type":"if","locations":[{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},{"start":{},"end":{}}],"line":404},"5":{"loc":{"start":{"line":404,"column":6},"end":{"line":404,"column":47}},"type":"binary-expr","locations":[{"start":{"line":404,"column":6},"end":{"line":404,"column":18}},{"start":{"line":404,"column":18},"end":{"line":404,"column":47}}],"line":404},"6":{"loc":{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},"type":"if","locations":[{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},{"start":{},"end":{}}],"line":440}},"s":{"0":1,"1":5,"2":1,"3":4,"4":4,"5":4,"6":80,"7":161,"8":161,"9":4,"10":4,"11":80,"12":134,"13":1,"14":3,"15":163,"16":32,"17":32,"18":32,"19":314,"20":26,"21":26,"22":4,"23":22,"24":22,"25":22,"26":2,"27":40,"28":5,"29":5,"30":100,"31":100,"32":200,"33":200,"34":50,"35":200,"36":5,"37":5,"38":50,"39":5,"40":2,"41":40},"f":{"0":5,"1":4,"2":80,"3":161,"4":161,"5":4,"6":80,"7":134,"8":3,"9":163,"10":32,"11":314,"12":26,"13":2,"14":40,"15":5,"16":2,"17":40},"b":{"0":[1,4],"1":[161,151],"2":[3,1],"3":[314,109],"4":[4,22],"5":[26,23],"6":[50,150]},"meta":{"lastBranch":7,"lastFunction":18,"lastStatement":42,"seen":{"s:83:62:321:Infinity":0,"f:328:16:328:Infinity":0,"b:331:2:331:Infinity:undefined:undefined:undefined:undefined":0,"s:331:2:331:Infinity":1,"s:331:34:331:Infinity":2,"s:332:18:332:Infinity":3,"f:332:32:332:37":1,"s:332:43:332:58":4,"s:333:2:337:Infinity":5,"f:333:24:333:32":2,"s:334:4:336:Infinity":6,"f:334:26:334:32":3,"s:335:6:335:Infinity":7,"f:335:14:335:20":4,"s:335:26:335:90":8,"b:335:26:335:60:335:60:335:90":1,"f:341:16:341:Infinity":5,"s:344:16:344:Infinity":9,"s:345:2:347:Infinity":10,"f:345:24:345:32":6,"s:346:4:346:Infinity":11,"f:346:25:346:31":7,"s:346:37:346:62":12,"s:351:32:357:Infinity":13,"f:360:16:360:33":8,"s:361:2:361:Infinity":14,"b:361:9:361:49:361:49:361:Infinity":2,"f:368:16:368:28":9,"s:369:2:369:Infinity":15,"f:384:16:384:Infinity":10,"s:388:18:388:Infinity":16,"s:389:18:389:Infinity":17,"s:390:2:392:Infinity":18,"f:390:24:390:Infinity":11,"s:391:13:391:Infinity":19,"b:391:13:391:41:391:41:391:Infinity":3,"f:400:16:400:Infinity":12,"s:403:14:403:Infinity":20,"b:404:2:404:Infinity:undefined:undefined:undefined:undefined":4,"s:404:2:404:Infinity":21,"b:404:6:404:18:404:18:404:47":5,"s:404:47:404:Infinity":22,"s:405:13:405:Infinity":23,"s:406:13:406:Infinity":24,"s:407:2:407:Infinity":25,"f:415:16:415:65":13,"s:416:2:416:Infinity":26,"f:416:32:416:37":14,"s:416:45:416:57":27,"f:434:16:434:80":15,"s:435:17:435:Infinity":28,"s:436:2:443:Infinity":29,"s:437:21:437:Infinity":30,"s:438:4:442:Infinity":31,"s:439:18:439:Infinity":32,"b:440:6:440:Infinity:undefined:undefined:undefined:undefined":6,"s:440:6:440:Infinity":33,"s:440:28:440:Infinity":34,"s:441:6:441:Infinity":35,"s:444:14:444:Infinity":36,"s:445:2:447:Infinity":37,"s:446:4:446:Infinity":38,"s:448:2:448:Infinity":39,"f:456:16:456:54":16,"s:457:2:459:Infinity":40,"f:458:19:458:24":17,"s:458:32:458:74":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/client.ts","statementMap":{"0":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"1":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"2":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"3":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"4":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"5":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"6":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"7":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"8":{"start":{"line":95,"column":4},"end":{"line":101,"column":null}},"9":{"start":{"line":110,"column":4},"end":{"line":116,"column":null}},"10":{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},"11":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"12":{"start":{"line":133,"column":16},"end":{"line":133,"column":null}},"13":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"14":{"start":{"line":135,"column":6},"end":{"line":145,"column":null}},"15":{"start":{"line":136,"column":23},"end":{"line":136,"column":null}},"16":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"17":{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},"18":{"start":{"line":140,"column":10},"end":{"line":140,"column":null}},"19":{"start":{"line":141,"column":10},"end":{"line":141,"column":null}},"20":{"start":{"line":142,"column":10},"end":{"line":142,"column":null}},"21":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"22":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"23":{"start":{"line":159,"column":19},"end":{"line":159,"column":null}},"24":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"25":{"start":{"line":160,"column":29},"end":{"line":160,"column":null}},"26":{"start":{"line":161,"column":20},"end":{"line":161,"column":null}},"27":{"start":{"line":161,"column":41},"end":{"line":161,"column":54}},"28":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"29":{"start":{"line":174,"column":16},"end":{"line":174,"column":null}},"30":{"start":{"line":175,"column":4},"end":{"line":182,"column":null}},"31":{"start":{"line":176,"column":6},"end":{"line":181,"column":null}},"32":{"start":{"line":177,"column":23},"end":{"line":177,"column":null}},"33":{"start":{"line":178,"column":8},"end":{"line":178,"column":null}},"34":{"start":{"line":180,"column":8},"end":{"line":180,"column":null}},"35":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"36":{"start":{"line":192,"column":4},"end":{"line":198,"column":null}},"37":{"start":{"line":202,"column":41},"end":{"line":202,"column":null}},"38":{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},"39":{"start":{"line":207,"column":4},"end":{"line":207,"column":null}},"40":{"start":{"line":209,"column":2},"end":{"line":209,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":72,"column":2},"end":{"line":72,"column":14}},"loc":{"start":{"line":72,"column":44},"end":{"line":81,"column":null}},"line":72},"1":{"name":"(anonymous_1)","decl":{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},"loc":{"start":{"line":94,"column":29},"end":{"line":102,"column":null}},"line":94},"2":{"name":"(anonymous_2)","decl":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"loc":{"start":{"line":109,"column":85},"end":{"line":117,"column":null}},"line":109},"3":{"name":"(anonymous_3)","decl":{"start":{"line":124,"column":8},"end":{"line":124,"column":null}},"loc":{"start":{"line":128,"column":51},"end":{"line":148,"column":null}},"line":128},"4":{"name":"(anonymous_4)","decl":{"start":{"line":155,"column":8},"end":{"line":155,"column":null}},"loc":{"start":{"line":158,"column":34},"end":{"line":163,"column":null}},"line":158},"5":{"name":"(anonymous_5)","decl":{"start":{"line":161,"column":27},"end":{"line":161,"column":35}},"loc":{"start":{"line":161,"column":41},"end":{"line":161,"column":54}},"line":161},"6":{"name":"(anonymous_6)","decl":{"start":{"line":170,"column":8},"end":{"line":170,"column":null}},"loc":{"start":{"line":173,"column":47},"end":{"line":184,"column":null}},"line":173},"7":{"name":"(anonymous_7)","decl":{"start":{"line":191,"column":8},"end":{"line":191,"column":18}},"loc":{"start":{"line":191,"column":59},"end":{"line":199,"column":null}},"line":191},"8":{"name":"getDefaultImfClient","decl":{"start":{"line":205,"column":16},"end":{"line":205,"column":49}},"loc":{"start":{"line":205,"column":49},"end":{"line":210,"column":null}},"line":205}},"branchMap":{"0":{"loc":{"start":{"line":72,"column":14},"end":{"line":72,"column":44}},"type":"default-arg","locations":[{"start":{"line":72,"column":40},"end":{"line":72,"column":44}}],"line":72},"1":{"loc":{"start":{"line":73,"column":29},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":29},"end":{"line":73,"column":57}},{"start":{"line":73,"column":57},"end":{"line":73,"column":null}}],"line":73},"2":{"loc":{"start":{"line":74,"column":23},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":45}},{"start":{"line":74,"column":45},"end":{"line":74,"column":null}}],"line":74},"3":{"loc":{"start":{"line":75,"column":19},"end":{"line":75,"column":null}},"type":"binary-expr","locations":[{"start":{"line":75,"column":19},"end":{"line":75,"column":37}},{"start":{"line":75,"column":37},"end":{"line":75,"column":null}}],"line":75},"4":{"loc":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":22},"end":{"line":76,"column":43}},{"start":{"line":76,"column":43},"end":{"line":76,"column":null}}],"line":76},"5":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"type":"binary-expr","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":41}},{"start":{"line":77,"column":41},"end":{"line":77,"column":null}}],"line":77},"6":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"type":"binary-expr","locations":[{"start":{"line":78,"column":22},"end":{"line":78,"column":43}},{"start":{"line":78,"column":43},"end":{"line":78,"column":null}}],"line":78},"7":{"loc":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"type":"default-arg","locations":[{"start":{"line":93,"column":12},"end":{"line":93,"column":null}}],"line":93},"8":{"loc":{"start":{"line":127,"column":4},"end":{"line":127,"column":null}},"type":"default-arg","locations":[{"start":{"line":127,"column":12},"end":{"line":127,"column":null}}],"line":127},"9":{"loc":{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":129},"10":{"loc":{"start":{"line":129,"column":8},"end":{"line":129,"column":47}},"type":"binary-expr","locations":[{"start":{"line":129,"column":8},"end":{"line":129,"column":21}},{"start":{"line":129,"column":21},"end":{"line":129,"column":47}}],"line":129},"11":{"loc":{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":139},"12":{"loc":{"start":{"line":139,"column":12},"end":{"line":139,"column":96}},"type":"binary-expr","locations":[{"start":{"line":139,"column":12},"end":{"line":139,"column":45}},{"start":{"line":139,"column":45},"end":{"line":139,"column":78}},{"start":{"line":139,"column":78},"end":{"line":139,"column":96}}],"line":139},"13":{"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":160},"14":{"loc":{"start":{"line":162,"column":11},"end":{"line":162,"column":null}},"type":"binary-expr","locations":[{"start":{"line":162,"column":11},"end":{"line":162,"column":25}},{"start":{"line":162,"column":25},"end":{"line":162,"column":null}}],"line":162},"15":{"loc":{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":206}},"s":{"0":53,"1":53,"2":53,"3":53,"4":53,"5":53,"6":53,"7":53,"8":36,"9":1,"10":7,"11":1,"12":6,"13":6,"14":10,"15":10,"16":5,"17":5,"18":3,"19":3,"20":3,"21":2,"22":4,"23":6,"24":5,"25":3,"26":2,"27":5,"28":2,"29":1,"30":1,"31":3,"32":3,"33":2,"34":1,"35":1,"36":9,"37":19,"38":2,"39":1,"40":2},"f":{"0":53,"1":36,"2":1,"3":7,"4":6,"5":5,"6":1,"7":9,"8":2},"b":{"0":[53],"1":[53,52],"2":[53,52],"3":[53,12],"4":[53,6],"5":[53,52],"6":[53,20],"7":[36],"8":[7],"9":[1,6],"10":[7,6],"11":[3,2],"12":[5,4,3],"13":[3,2],"14":[2,1],"15":[1,1]},"meta":{"lastBranch":16,"lastFunction":9,"lastStatement":41,"seen":{"f:72:2:72:14":0,"b:72:40:72:44":0,"s:73:4:73:Infinity":0,"b:73:29:73:57:73:57:73:Infinity":1,"s:74:4:74:Infinity":1,"b:74:23:74:45:74:45:74:Infinity":2,"s:75:4:75:Infinity":2,"b:75:19:75:37:75:37:75:Infinity":3,"s:76:4:76:Infinity":3,"b:76:22:76:43:76:43:76:Infinity":4,"s:77:4:77:Infinity":4,"b:77:21:77:41:77:41:77:Infinity":5,"s:78:4:78:Infinity":5,"b:78:22:78:43:78:43:78:Infinity":6,"s:79:4:79:Infinity":6,"s:80:4:80:Infinity":7,"f:90:8:90:Infinity":1,"b:93:12:93:Infinity":7,"s:95:4:101:Infinity":8,"f:109:8:109:85":2,"s:110:4:116:Infinity":9,"f:124:8:124:Infinity":3,"b:127:12:127:Infinity":8,"b:129:4:131:Infinity:undefined:undefined:undefined:undefined":9,"s:129:4:131:Infinity":10,"b:129:8:129:21:129:21:129:47":10,"s:130:6:130:Infinity":11,"s:133:16:133:Infinity":12,"s:134:4:146:Infinity":13,"s:135:6:145:Infinity":14,"s:136:23:136:Infinity":15,"s:137:8:137:Infinity":16,"b:139:8:143:Infinity:undefined:undefined:undefined:undefined":11,"s:139:8:143:Infinity":17,"b:139:12:139:45:139:45:139:78:139:78:139:96":12,"s:140:10:140:Infinity":18,"s:141:10:141:Infinity":19,"s:142:10:142:Infinity":20,"s:144:8:144:Infinity":21,"s:147:4:147:Infinity":22,"f:155:8:155:Infinity":4,"s:159:19:159:Infinity":23,"b:160:4:160:Infinity:undefined:undefined:undefined:undefined":13,"s:160:4:160:Infinity":24,"s:160:29:160:Infinity":25,"s:161:20:161:Infinity":26,"f:161:27:161:35":5,"s:161:41:161:54":27,"s:162:4:162:Infinity":28,"b:162:11:162:25:162:25:162:Infinity":14,"f:170:8:170:Infinity":6,"s:174:16:174:Infinity":29,"s:175:4:182:Infinity":30,"s:176:6:181:Infinity":31,"s:177:23:177:Infinity":32,"s:178:8:178:Infinity":33,"s:180:8:180:Infinity":34,"s:183:4:183:Infinity":35,"f:191:8:191:18":7,"s:192:4:198:Infinity":36,"s:202:41:202:Infinity":37,"f:205:16:205:49":8,"b:206:2:208:Infinity:undefined:undefined:undefined:undefined":15,"s:206:2:208:Infinity":38,"s:207:4:207:Infinity":39,"s:209:2:209:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/auth.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/auth.ts","statementMap":{"0":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"1":{"start":{"line":43,"column":30},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}}},"fnMap":{"0":{"name":"resolveSdmxSubscriptionKey","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":43}},"loc":{"start":{"line":42,"column":70},"end":{"line":45,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":44,"column":9},"end":{"line":44,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":9},"end":{"line":44,"column":53}},{"start":{"line":44,"column":53},"end":{"line":44,"column":null}}],"line":44}},"s":{"0":53,"1":5,"2":48},"f":{"0":53},"b":{"0":[5,48],"1":[48,47]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":3,"seen":{"f:42:16:42:43":0,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":0,"s:43:30:43:Infinity":1,"s:44:2:44:Infinity":2,"b:44:9:44:53:44:53:44:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/defaults.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/defaults.ts","statementMap":{"0":{"start":{"line":14,"column":43},"end":{"line":14,"column":null}},"1":{"start":{"line":15,"column":37},"end":{"line":15,"column":null}},"2":{"start":{"line":16,"column":31},"end":{"line":16,"column":null}},"3":{"start":{"line":17,"column":35},"end":{"line":17,"column":null}},"4":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"5":{"start":{"line":27,"column":35},"end":{"line":27,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":20,"1":20,"2":20,"3":20,"4":20,"5":20},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":6,"seen":{"s:14:43:14:Infinity":0,"s:15:37:15:Infinity":1,"s:16:31:16:Infinity":2,"s:17:35:17:Infinity":3,"s:19:2:19:Infinity":4,"s:27:35:27:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/http-error.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/http-error.ts","statementMap":{"0":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":24},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":23},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":10},"end":{"line":38,"column":null}},"6":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"7":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"8":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"9":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":29,"column":2},"end":{"line":29,"column":14}},"loc":{"start":{"line":29,"column":84},"end":{"line":44,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":29,"column":55},"end":{"line":29,"column":84}},"type":"default-arg","locations":[{"start":{"line":29,"column":77},"end":{"line":29,"column":84}}],"line":29},"1":{"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":16},"end":{"line":30,"column":32}},{"start":{"line":30,"column":32},"end":{"line":30,"column":46}},{"start":{"line":30,"column":46},"end":{"line":30,"column":null}}],"line":30},"2":{"loc":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":26},"end":{"line":32,"column":53}},{"start":{"line":32,"column":53},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":32},"end":{"line":33,"column":59}},{"start":{"line":33,"column":59},"end":{"line":33,"column":null}}],"line":33},"4":{"loc":{"start":{"line":34,"column":23},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":23},"end":{"line":34,"column":72}},{"start":{"line":34,"column":72},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":10},"end":{"line":38,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":null}},{"start":{"line":38,"column":10},"end":{"line":38,"column":null}}],"line":35},"6":{"loc":{"start":{"line":35,"column":10},"end":{"line":36,"column":null}},"type":"binary-expr","locations":[{"start":{"line":36,"column":7},"end":{"line":36,"column":24}},{"start":{"line":36,"column":24},"end":{"line":36,"column":48}},{"start":{"line":36,"column":48},"end":{"line":36,"column":null}}],"line":35},"7":{"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":48}},{"start":{"line":42,"column":48},"end":{"line":42,"column":null}}],"line":42}},"s":{"0":17,"1":17,"2":17,"3":17,"4":17,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17},"f":{"0":17},"b":{"0":[17],"1":[17,17,3],"2":[17,16],"3":[17,6],"4":[17,12],"5":[4,13],"6":[17,15,6],"7":[17,14]},"meta":{"lastBranch":8,"lastFunction":1,"lastStatement":11,"seen":{"f:29:2:29:14":0,"b:29:77:29:84":0,"s:30:16:30:Infinity":0,"b:30:16:30:32:30:32:30:46:30:46:30:Infinity":1,"s:31:24:31:Infinity":1,"s:32:26:32:Infinity":2,"b:32:26:32:53:32:53:32:Infinity":2,"s:33:32:33:Infinity":3,"b:33:32:33:59:33:59:33:Infinity":3,"s:34:23:34:Infinity":4,"b:34:23:34:72:34:72:34:Infinity":4,"s:35:10:38:Infinity":5,"b:37:10:37:Infinity:38:10:38:Infinity":5,"b:36:7:36:24:36:24:36:48:36:48:36:Infinity":6,"s:39:4:39:Infinity":6,"s:40:4:40:Infinity":7,"s:41:4:41:Infinity":8,"s:42:4:42:Infinity":9,"b:42:21:42:48:42:48:42:Infinity":7,"s:43:4:43:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/weo-sdmx-only.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/weo-sdmx-only.ts","statementMap":{"0":{"start":{"line":23,"column":27},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":4},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":22,"column":2},"end":{"line":22,"column":14}},"loc":{"start":{"line":22,"column":45},"end":{"line":34,"column":null}},"line":22}},"branchMap":{},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4},"f":{"0":4},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":7,"seen":{"f:22:2:22:14":0,"s:23:27:23:Infinity":0,"s:24:21:24:Infinity":1,"s:25:4:29:Infinity":2,"s:30:4:30:Infinity":3,"s:31:4:31:Infinity":4,"s:32:4:32:Infinity":5,"s:33:4:33:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/cofog-codes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/cofog-codes.ts","statementMap":{"0":{"start":{"line":16,"column":29},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":28},"end":{"line":18,"column":null}},"2":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":39},"end":{"line":22,"column":null}},"4":{"start":{"line":28,"column":35},"end":{"line":33,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":15,"1":15,"2":15,"3":15,"4":15},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":5,"seen":{"s:16:29:16:Infinity":0,"s:18:28:18:Infinity":1,"s:20:31:20:Infinity":2,"s:22:39:22:Infinity":3,"s:28:35:33:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/fm.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/fm.ts","statementMap":{"0":{"start":{"line":16,"column":33},"end":{"line":21,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":17},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:16:33:21:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/parsers/datamapper-envelope.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/parsers/datamapper-envelope.ts","statementMap":{"0":{"start":{"line":84,"column":24},"end":{"line":84,"column":null}},"1":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"2":{"start":{"line":85,"column":22},"end":{"line":85,"column":null}},"3":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"4":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"5":{"start":{"line":87,"column":20},"end":{"line":87,"column":null}},"6":{"start":{"line":89,"column":22},"end":{"line":89,"column":null}},"7":{"start":{"line":90,"column":33},"end":{"line":90,"column":null}},"8":{"start":{"line":91,"column":2},"end":{"line":111,"column":null}},"9":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"10":{"start":{"line":92,"column":53},"end":{"line":92,"column":null}},"11":{"start":{"line":93,"column":20},"end":{"line":93,"column":null}},"12":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"13":{"start":{"line":94,"column":35},"end":{"line":94,"column":null}},"14":{"start":{"line":95,"column":20},"end":{"line":95,"column":null}},"15":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"16":{"start":{"line":96,"column":35},"end":{"line":96,"column":null}},"17":{"start":{"line":97,"column":25},"end":{"line":97,"column":null}},"18":{"start":{"line":98,"column":29},"end":{"line":109,"column":null}},"19":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"20":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"21":{"start":{"line":113,"column":24},"end":{"line":113,"column":81}},"22":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"23":{"start":{"line":124,"column":14},"end":{"line":124,"column":null}},"24":{"start":{"line":125,"column":21},"end":{"line":125,"column":null}},"25":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"26":{"start":{"line":126,"column":19},"end":{"line":126,"column":null}},"27":{"start":{"line":127,"column":2},"end":{"line":140,"column":null}},"28":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"29":{"start":{"line":128,"column":43},"end":{"line":128,"column":null}},"30":{"start":{"line":129,"column":20},"end":{"line":129,"column":null}},"31":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"32":{"start":{"line":130,"column":18},"end":{"line":130,"column":null}},"33":{"start":{"line":131,"column":4},"end":{"line":139,"column":null}},"34":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}}},"fnMap":{"0":{"name":"parseDatamapperValues","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":null}},"loc":{"start":{"line":83,"column":18},"end":{"line":115,"column":null}},"line":83},"1":{"name":"(anonymous_1)","decl":{"start":{"line":113,"column":9},"end":{"line":113,"column":15}},"loc":{"start":{"line":113,"column":24},"end":{"line":113,"column":81}},"line":113},"2":{"name":"parseDatamapperIndicators","decl":{"start":{"line":121,"column":16},"end":{"line":121,"column":null}},"loc":{"start":{"line":123,"column":43},"end":{"line":142,"column":null}},"line":123}},"branchMap":{"0":{"loc":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":85},"1":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"2":{"loc":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92},"3":{"loc":{"start":{"line":92,"column":8},"end":{"line":92,"column":53}},"type":"binary-expr","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":29}},{"start":{"line":92,"column":29},"end":{"line":92,"column":53}}],"line":92},"4":{"loc":{"start":{"line":93,"column":20},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":51},"end":{"line":93,"column":62}},{"start":{"line":93,"column":62},"end":{"line":93,"column":null}}],"line":93},"5":{"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":94},"6":{"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"7":{"loc":{"start":{"line":108,"column":10},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":25},"end":{"line":108,"column":61}},{"start":{"line":108,"column":61},"end":{"line":108,"column":null}}],"line":108},"8":{"loc":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},{"start":{},"end":{}}],"line":126},"9":{"loc":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":128},"10":{"loc":{"start":{"line":128,"column":8},"end":{"line":128,"column":43}},"type":"binary-expr","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":17}},{"start":{"line":128,"column":17},"end":{"line":128,"column":43}}],"line":128},"11":{"loc":{"start":{"line":129,"column":20},"end":{"line":129,"column":null}},"type":"cond-expr","locations":[{"start":{"line":129,"column":55},"end":{"line":129,"column":70}},{"start":{"line":129,"column":70},"end":{"line":129,"column":null}}],"line":129},"12":{"loc":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":130},"13":{"loc":{"start":{"line":133,"column":13},"end":{"line":133,"column":null}},"type":"cond-expr","locations":[{"start":{"line":133,"column":46},"end":{"line":133,"column":59}},{"start":{"line":133,"column":59},"end":{"line":133,"column":null}}],"line":133},"14":{"loc":{"start":{"line":134,"column":19},"end":{"line":134,"column":null}},"type":"cond-expr","locations":[{"start":{"line":134,"column":58},"end":{"line":134,"column":77}},{"start":{"line":134,"column":77},"end":{"line":134,"column":null}}],"line":134},"15":{"loc":{"start":{"line":135,"column":14},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":135,"column":48},"end":{"line":135,"column":62}},{"start":{"line":135,"column":62},"end":{"line":135,"column":null}}],"line":135},"16":{"loc":{"start":{"line":136,"column":12},"end":{"line":136,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":44},"end":{"line":136,"column":56}},{"start":{"line":136,"column":56},"end":{"line":136,"column":null}}],"line":136},"17":{"loc":{"start":{"line":138,"column":10},"end":{"line":138,"column":null}},"type":"cond-expr","locations":[{"start":{"line":138,"column":48},"end":{"line":138,"column":82}},{"start":{"line":138,"column":82},"end":{"line":138,"column":null}}],"line":138}},"s":{"0":34,"1":34,"2":10,"3":24,"4":24,"5":4,"6":20,"7":20,"8":20,"9":45,"10":2,"11":43,"12":45,"13":2,"14":41,"15":41,"16":1,"17":40,"18":40,"19":45,"20":20,"21":34,"22":20,"23":7,"24":7,"25":7,"26":3,"27":4,"28":9,"29":1,"30":8,"31":9,"32":1,"33":7,"34":4},"f":{"0":34,"1":34,"2":7},"b":{"0":[10,24],"1":[4,20],"2":[2,43],"3":[45,43],"4":[41,2],"5":[2,43],"6":[1,40],"7":[6,34],"8":[3,4],"9":[1,8],"10":[9,8],"11":[7,1],"12":[1,8],"13":[7,0],"14":[0,7],"15":[0,7],"16":[2,5],"17":[1,6]},"meta":{"lastBranch":18,"lastFunction":3,"lastStatement":35,"seen":{"f:78:16:78:Infinity":0,"s:84:24:84:Infinity":0,"b:85:2:85:Infinity:undefined:undefined:undefined:undefined":0,"s:85:2:85:Infinity":1,"s:85:22:85:Infinity":2,"s:86:22:86:Infinity":3,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":1,"s:87:2:87:Infinity":4,"s:87:20:87:Infinity":5,"s:89:22:89:Infinity":6,"s:90:33:90:Infinity":7,"s:91:2:111:Infinity":8,"b:92:4:92:Infinity:undefined:undefined:undefined:undefined":2,"s:92:4:92:Infinity":9,"b:92:8:92:29:92:29:92:53":3,"s:92:53:92:Infinity":10,"s:93:20:93:Infinity":11,"b:93:51:93:62:93:62:93:Infinity":4,"b:94:4:94:Infinity:undefined:undefined:undefined:undefined":5,"s:94:4:94:Infinity":12,"s:94:35:94:Infinity":13,"s:95:20:95:Infinity":14,"b:96:4:96:Infinity:undefined:undefined:undefined:undefined":6,"s:96:4:96:Infinity":15,"s:96:35:96:Infinity":16,"s:97:25:97:Infinity":17,"s:98:29:109:Infinity":18,"b:108:25:108:61:108:61:108:Infinity":7,"s:110:4:110:Infinity":19,"s:113:2:113:Infinity":20,"f:113:9:113:15":1,"s:113:24:113:81":21,"s:114:2:114:Infinity":22,"f:121:16:121:Infinity":2,"s:124:14:124:Infinity":23,"s:125:21:125:Infinity":24,"b:126:2:126:Infinity:undefined:undefined:undefined:undefined":8,"s:126:2:126:Infinity":25,"s:126:19:126:Infinity":26,"s:127:2:140:Infinity":27,"b:128:4:128:Infinity:undefined:undefined:undefined:undefined":9,"s:128:4:128:Infinity":28,"b:128:8:128:17:128:17:128:43":10,"s:128:43:128:Infinity":29,"s:129:20:129:Infinity":30,"b:129:55:129:70:129:70:129:Infinity":11,"b:130:4:130:Infinity:undefined:undefined:undefined:undefined":12,"s:130:4:130:Infinity":31,"s:130:18:130:Infinity":32,"s:131:4:139:Infinity":33,"b:133:46:133:59:133:59:133:Infinity":13,"b:134:58:134:77:134:77:134:Infinity":14,"b:135:48:135:62:135:62:135:Infinity":15,"b:136:44:136:56:136:56:136:Infinity":16,"b:138:48:138:82:138:82:138:Infinity":17,"s:141:2:141:Infinity":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/weo.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/weo.ts","statementMap":{"0":{"start":{"line":25,"column":34},"end":{"line":50,"column":null}},"1":{"start":{"line":60,"column":65},"end":{"line":70,"column":null}},"2":{"start":{"line":80,"column":54},"end":{"line":85,"column":null}},"3":{"start":{"line":96,"column":12},"end":{"line":96,"column":null}},"4":{"start":{"line":97,"column":12},"end":{"line":97,"column":null}},"5":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"weoSdmxPath","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":28}},"loc":{"start":{"line":95,"column":67},"end":{"line":99,"column":null}},"line":95}},"branchMap":{},"s":{"0":19,"1":19,"2":19,"3":7,"4":7,"5":7},"f":{"0":7},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":6,"seen":{"s:25:34:50:Infinity":0,"s:60:65:70:Infinity":1,"s:80:54:85:Infinity":2,"f:95:16:95:28":0,"s:96:12:96:Infinity":3,"s:97:12:97:Infinity":4,"s:98:2:98:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/datamapper.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/datamapper.ts","statementMap":{"0":{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},"1":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"2":{"start":{"line":52,"column":15},"end":{"line":52,"column":null}},"3":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"4":{"start":{"line":54,"column":15},"end":{"line":58,"column":null}},"5":{"start":{"line":60,"column":17},"end":{"line":60,"column":null}},"6":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"7":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":64,"column":null}},"9":{"start":{"line":71,"column":14},"end":{"line":71,"column":null}},"10":{"start":{"line":72,"column":15},"end":{"line":76,"column":null}},"11":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}}},"fnMap":{"0":{"name":"fetchDatamapperWeoIndicator","decl":{"start":{"line":43,"column":22},"end":{"line":43,"column":null}},"loc":{"start":{"line":48,"column":27},"end":{"line":65,"column":null}},"line":48},"1":{"name":"fetchDatamapperIndicators","decl":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"loc":{"start":{"line":70,"column":52},"end":{"line":78,"column":null}},"line":70}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":49},"1":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":45}},"type":"binary-expr","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":19}},{"start":{"line":49,"column":19},"end":{"line":49,"column":45}}],"line":49},"2":{"loc":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"3":{"loc":{"start":{"line":61,"column":6},"end":{"line":61,"column":61}},"type":"binary-expr","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":29}},{"start":{"line":61,"column":29},"end":{"line":61,"column":61}}],"line":61}},"s":{"0":36,"1":3,"2":33,"3":33,"4":33,"5":23,"6":23,"7":2,"8":21,"9":1,"10":1,"11":1},"f":{"0":36,"1":1},"b":{"0":[3,33],"1":[36,34],"2":[2,21],"3":[23,7]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":12,"seen":{"f:43:22:43:Infinity":0,"b:49:2:51:Infinity:undefined:undefined:undefined:undefined":0,"s:49:2:51:Infinity":0,"b:49:6:49:19:49:19:49:45":1,"s:50:4:50:Infinity":1,"s:52:15:52:Infinity":2,"s:53:14:53:Infinity":3,"s:54:15:58:Infinity":4,"s:60:17:60:Infinity":5,"b:61:2:63:Infinity:undefined:undefined:undefined:undefined":2,"s:61:2:63:Infinity":6,"b:61:6:61:29:61:29:61:61":3,"s:62:4:62:Infinity":7,"s:64:2:64:Infinity":8,"f:68:22:68:Infinity":1,"s:71:14:71:Infinity":9,"s:72:15:76:Infinity":10,"s:77:2:77:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/path-normaliser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/path-normaliser.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"3":{"start":{"line":25,"column":4},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":13},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":12},"end":{"line":28,"column":null}},"6":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},"7":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"8":{"start":{"line":32,"column":64},"end":{"line":32,"column":null}},"9":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}}},"fnMap":{"0":{"name":"normalizeSdmxPathForBase","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":41}},"loc":{"start":{"line":20,"column":89},"end":{"line":34,"column":null}},"line":20}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":21},"1":{"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},{"start":{},"end":{}}],"line":24},"2":{"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":29},"3":{"loc":{"start":{"line":33,"column":63},"end":{"line":33,"column":79}},"type":"binary-expr","locations":[{"start":{"line":33,"column":63},"end":{"line":33,"column":74}},{"start":{"line":33,"column":74},"end":{"line":33,"column":79}}],"line":33},"4":{"loc":{"start":{"line":33,"column":79},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":79},"end":{"line":33,"column":88}},{"start":{"line":33,"column":88},"end":{"line":33,"column":null}}],"line":33}},"s":{"0":17,"1":1,"2":16,"3":1,"4":15,"5":15,"6":15,"7":2,"8":13,"9":13},"f":{"0":17},"b":{"0":[1,16],"1":[1,15],"2":[2,13],"3":[13,1],"4":[17,12]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":10,"seen":{"f:20:16:20:41":0,"b:21:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:21:2:23:Infinity":0,"s:22:4:22:Infinity":1,"b:24:2:26:Infinity:undefined:undefined:undefined:undefined":1,"s:24:2:26:Infinity":2,"s:25:4:25:Infinity":3,"s:27:13:27:Infinity":4,"s:28:12:28:Infinity":5,"b:29:2:31:Infinity:undefined:undefined:undefined:undefined":2,"s:29:2:31:Infinity":6,"s:30:4:30:Infinity":7,"s:32:64:32:Infinity":8,"s:33:2:33:Infinity":9,"b:33:63:33:74:33:74:33:79":3,"b:33:79:33:88:33:88:33:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/fetch-with-retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/fetch-with-retry.ts","statementMap":{"0":{"start":{"line":43,"column":64},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"2":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"3":{"start":{"line":45,"column":37},"end":{"line":45,"column":57}},"4":{"start":{"line":46,"column":2},"end":{"line":73,"column":null}},"5":{"start":{"line":47,"column":21},"end":{"line":54,"column":null}},"6":{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},"7":{"start":{"line":57,"column":34},"end":{"line":57,"column":null}},"8":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"9":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"10":{"start":{"line":63,"column":29},"end":{"line":63,"column":null}},"11":{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},"12":{"start":{"line":65,"column":20},"end":{"line":65,"column":null}},"13":{"start":{"line":66,"column":6},"end":{"line":66,"column":null}},"14":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"15":{"start":{"line":67,"column":37},"end":{"line":67,"column":63}},"16":{"start":{"line":68,"column":6},"end":{"line":68,"column":null}},"17":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"18":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"fetchWithRetry","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":20},"end":{"line":74,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":20},"end":{"line":45,"column":37}},"loc":{"start":{"line":45,"column":37},"end":{"line":45,"column":57}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":67,"column":16},"end":{"line":67,"column":25}},"loc":{"start":{"line":67,"column":37},"end":{"line":67,"column":63}},"line":67}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"type":"default-arg","locations":[{"start":{"line":41,"column":12},"end":{"line":41,"column":null}}],"line":41},"1":{"loc":{"start":{"line":43,"column":42},"end":{"line":43,"column":64}},"type":"default-arg","locations":[{"start":{"line":43,"column":57},"end":{"line":43,"column":64}}],"line":43},"2":{"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":56},"3":{"loc":{"start":{"line":63,"column":29},"end":{"line":63,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":61},"end":{"line":63,"column":86}},{"start":{"line":63,"column":86},"end":{"line":63,"column":null}}],"line":63},"4":{"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":64},"5":{"loc":{"start":{"line":64,"column":8},"end":{"line":64,"column":57}},"type":"binary-expr","locations":[{"start":{"line":64,"column":8},"end":{"line":64,"column":32}},{"start":{"line":64,"column":32},"end":{"line":64,"column":57}}],"line":64}},"s":{"0":45,"1":45,"2":45,"3":0,"4":45,"5":45,"6":42,"7":13,"8":13,"9":29,"10":17,"11":17,"12":2,"13":2,"14":2,"15":2,"16":2,"17":15,"18":45},"f":{"0":45,"1":0,"2":2},"b":{"0":[45],"1":[45],"2":[13,29],"3":[13,4],"4":[2,15],"5":[17,5]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":19,"seen":{"f:38:22:38:Infinity":0,"b:41:12:41:Infinity":0,"s:43:64:43:Infinity":0,"b:43:57:43:64":1,"s:44:21:44:Infinity":1,"s:45:20:45:Infinity":2,"f:45:20:45:37":1,"s:45:37:45:57":3,"s:46:2:73:Infinity":4,"s:47:21:54:Infinity":5,"b:56:4:59:Infinity:undefined:undefined:undefined:undefined":2,"s:56:4:59:Infinity":6,"s:57:34:57:Infinity":7,"s:58:6:58:Infinity":8,"s:61:4:61:Infinity":9,"s:63:29:63:Infinity":10,"b:63:61:63:86:63:86:63:Infinity":3,"b:64:4:69:Infinity:undefined:undefined:undefined:undefined":4,"s:64:4:69:Infinity":11,"b:64:8:64:32:64:32:64:57":5,"s:65:20:65:Infinity":12,"s:66:6:66:Infinity":13,"s:67:6:67:Infinity":14,"f:67:16:67:25":2,"s:67:37:67:63":15,"s:68:6:68:Infinity":16,"s:70:4:70:Infinity":17,"s:72:4:72:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/retry.ts","statementMap":{"0":{"start":{"line":21,"column":28},"end":{"line":21,"column":null}},"1":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":36},"end":{"line":36,"column":null}},"3":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":48,"column":25},"end":{"line":48,"column":null}},"6":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"8":{"start":{"line":50,"column":61},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"10":{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},"11":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"12":{"start":{"line":57,"column":57},"end":{"line":57,"column":84}},"13":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"14":{"start":{"line":59,"column":30},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"16":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"17":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"18":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}}},"fnMap":{"0":{"name":"calculateRetryDelay","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":null}},"loc":{"start":{"line":46,"column":10},"end":{"line":52,"column":null}},"line":46},"1":{"name":"isTransientFetchError","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":38}},"loc":{"start":{"line":55,"column":63},"end":{"line":61,"column":null}},"line":55},"2":{"name":"(anonymous_2)","decl":{"start":{"line":57,"column":39},"end":{"line":57,"column":45}},"loc":{"start":{"line":57,"column":57},"end":{"line":57,"column":84}},"line":57},"3":{"name":"isRetryableError","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":33}},"loc":{"start":{"line":64,"column":58},"end":{"line":69,"column":null}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"1":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"2":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":61}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":41}},{"start":{"line":50,"column":41},"end":{"line":50,"column":61}}],"line":50},"3":{"loc":{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":56},"4":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65}},"s":{"0":20,"1":20,"2":20,"3":17,"4":17,"5":12,"6":5,"7":5,"8":3,"9":2,"10":7,"11":3,"12":9,"13":4,"14":4,"15":0,"16":5,"17":3,"18":2},"f":{"0":17,"1":7,"2":9,"3":5},"b":{"0":[12,5],"1":[3,2],"2":[5,4],"3":[3,4],"4":[4,0],"5":[3,2]},"meta":{"lastBranch":6,"lastFunction":4,"lastStatement":19,"seen":{"s:21:28:21:Infinity":0,"s:29:34:29:Infinity":1,"s:31:36:36:Infinity":2,"f:43:16:43:Infinity":0,"s:47:22:47:Infinity":3,"b:48:2:48:Infinity:undefined:undefined:undefined:undefined":0,"s:48:2:48:Infinity":4,"s:48:25:48:Infinity":5,"s:49:24:49:Infinity":6,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":1,"s:50:2:50:Infinity":7,"b:50:6:50:41:50:41:50:61":2,"s:50:61:50:Infinity":8,"s:51:2:51:Infinity":9,"f:55:16:55:38":1,"b:56:2:58:Infinity:undefined:undefined:undefined:undefined":3,"s:56:2:58:Infinity":10,"s:57:4:57:Infinity":11,"f:57:39:57:45":2,"s:57:57:57:84":12,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":4,"s:59:2:59:Infinity":13,"s:59:30:59:Infinity":14,"s:60:2:60:Infinity":15,"f:64:16:64:33":3,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":5,"s:65:2:67:Infinity":16,"s:66:4:66:Infinity":17,"s:68:2:68:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/sdmx.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/sdmx.ts","statementMap":{"0":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"1":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":14},"end":{"line":44,"column":null}},"3":{"start":{"line":45,"column":42},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"5":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"6":{"start":{"line":51,"column":2},"end":{"line":56,"column":null}}},"fnMap":{"0":{"name":"sdmxFetch","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":41,"column":20},"end":{"line":57,"column":null}},"line":41}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"type":"cond-expr","locations":[{"start":{"line":43,"column":49},"end":{"line":43,"column":54}},{"start":{"line":43,"column":54},"end":{"line":43,"column":null}}],"line":43},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":48}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":4,"6":9},"f":{"0":9},"b":{"0":[8,1],"1":[4,5]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":7,"seen":{"f:38:22:38:Infinity":0,"s:42:21:42:Infinity":0,"s:43:20:43:Infinity":1,"b:43:49:43:54:43:54:43:Infinity":0,"s:44:14:44:Infinity":2,"s:45:42:47:Infinity":3,"b:48:2:50:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:50:Infinity":4,"s:49:4:49:Infinity":5,"s:51:2:56:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/auth.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/auth.ts","statementMap":{"0":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"1":{"start":{"line":39,"column":37},"end":{"line":39,"column":null}},"2":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"3":{"start":{"line":40,"column":42},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"5":{"start":{"line":43,"column":2},"end":{"line":59,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},"7":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"8":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":21},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":18},"end":{"line":49,"column":null}},"12":{"start":{"line":51,"column":25},"end":{"line":51,"column":null}},"13":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"14":{"start":{"line":53,"column":22},"end":{"line":53,"column":null}},"15":{"start":{"line":54,"column":25},"end":{"line":54,"column":null}},"16":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"17":{"start":{"line":55,"column":22},"end":{"line":55,"column":null}},"18":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"19":{"start":{"line":67,"column":46},"end":{"line":67,"column":null}},"20":{"start":{"line":79,"column":16},"end":{"line":79,"column":null}},"21":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}}},"fnMap":{"0":{"name":"getDefaultAuthToken","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":46}},"loc":{"start":{"line":38,"column":46},"end":{"line":61,"column":null}},"line":38},"1":{"name":"hasMcpGatewayApiKey","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":47}},"loc":{"start":{"line":78,"column":47},"end":{"line":81,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"2":{"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":56}},{"start":{"line":42,"column":56},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"5":{"loc":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"6":{"loc":{"start":{"line":80,"column":9},"end":{"line":80,"column":null}},"type":"binary-expr","locations":[{"start":{"line":80,"column":9},"end":{"line":80,"column":38}},{"start":{"line":80,"column":38},"end":{"line":80,"column":null}}],"line":80}},"s":{"0":40,"1":1,"2":39,"3":4,"4":35,"5":40,"6":40,"7":9,"8":9,"9":9,"10":9,"11":5,"12":3,"13":3,"14":9,"15":9,"16":9,"17":2,"18":28,"19":40,"20":39,"21":39},"f":{"0":40,"1":39},"b":{"0":[1,39],"1":[4,35],"2":[35,24],"3":[9,31],"4":[5,4],"5":[2,7],"6":[39,4]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":22,"seen":{"f:38:16:38:46":0,"b:39:2:39:Infinity:undefined:undefined:undefined:undefined":0,"s:39:2:39:Infinity":0,"s:39:37:39:Infinity":1,"b:40:2:40:Infinity:undefined:undefined:undefined:undefined":1,"s:40:2:40:Infinity":2,"s:40:42:40:Infinity":3,"s:42:21:42:Infinity":4,"b:42:21:42:56:42:56:42:Infinity":2,"s:43:2:59:Infinity":5,"b:44:4:56:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:56:Infinity":6,"s:45:18:45:Infinity":7,"s:47:22:47:Infinity":8,"s:48:21:48:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":4,"s:49:6:49:Infinity":10,"s:49:18:49:Infinity":11,"s:51:25:51:Infinity":12,"s:52:23:52:Infinity":13,"s:53:22:53:Infinity":14,"s:54:25:54:Infinity":15,"b:55:6:55:Infinity:undefined:undefined:undefined:undefined":5,"s:55:6:55:Infinity":16,"s:55:22:55:Infinity":17,"s:60:2:60:Infinity":18,"s:67:46:67:Infinity":19,"f:78:16:78:47":1,"s:79:16:79:Infinity":20,"s:80:2:80:Infinity":21,"b:80:9:80:38:80:38:80:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/defaults.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/defaults.ts","statementMap":{"0":{"start":{"line":13,"column":35},"end":{"line":13,"column":null}},"1":{"start":{"line":14,"column":27},"end":{"line":14,"column":null}},"2":{"start":{"line":20,"column":46},"end":{"line":20,"column":69}},"3":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}}},"fnMap":{"0":{"name":"getDefaultTimeout","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":44}},"loc":{"start":{"line":26,"column":44},"end":{"line":29,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":9},"end":{"line":28,"column":null}},"type":"cond-expr","locations":[{"start":{"line":28,"column":19},"end":{"line":28,"column":60}},{"start":{"line":28,"column":60},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":28,"column":19},"end":{"line":28,"column":60}},"type":"binary-expr","locations":[{"start":{"line":28,"column":19},"end":{"line":28,"column":50}},{"start":{"line":28,"column":50},"end":{"line":28,"column":60}}],"line":28}},"s":{"0":38,"1":38,"2":38,"3":135,"4":135},"f":{"0":135},"b":{"0":[2,133],"1":[2,1]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":5,"seen":{"s:13:35:13:Infinity":0,"s:14:27:14:Infinity":1,"s:20:46:20:69":2,"f:26:16:26:44":0,"s:27:17:27:Infinity":3,"s:28:2:28:Infinity":4,"b:28:19:28:60:28:60:28:Infinity":0,"b:28:19:28:50:28:50:28:60":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/lagradet-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/lagradet-fetch.ts","statementMap":{"0":{"start":{"line":34,"column":18},"end":{"line":34,"column":null}},"1":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":39},"end":{"line":36,"column":null}},"3":{"start":{"line":37,"column":34},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":43},"end":{"line":38,"column":null}},"5":{"start":{"line":39,"column":16},"end":{"line":39,"column":null}},"6":{"start":{"line":40,"column":15},"end":{"line":40,"column":null}},"7":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"9":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"10":{"start":{"line":61,"column":19},"end":{"line":61,"column":null}},"11":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"12":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"13":{"start":{"line":67,"column":35},"end":{"line":67,"column":null}},"14":{"start":{"line":68,"column":17},"end":{"line":68,"column":null}},"15":{"start":{"line":69,"column":2},"end":{"line":79,"column":null}},"16":{"start":{"line":70,"column":17},"end":{"line":70,"column":null}},"17":{"start":{"line":71,"column":18},"end":{"line":71,"column":null}},"18":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"19":{"start":{"line":72,"column":25},"end":{"line":72,"column":null}},"20":{"start":{"line":73,"column":21},"end":{"line":73,"column":null}},"21":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"22":{"start":{"line":74,"column":45},"end":{"line":74,"column":null}},"23":{"start":{"line":75,"column":4},"end":{"line":78,"column":null}},"24":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"25":{"start":{"line":84,"column":15},"end":{"line":84,"column":null}},"26":{"start":{"line":85,"column":35},"end":{"line":85,"column":null}},"27":{"start":{"line":86,"column":2},"end":{"line":91,"column":null}},"28":{"start":{"line":87,"column":16},"end":{"line":87,"column":null}},"29":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"30":{"start":{"line":88,"column":23},"end":{"line":88,"column":null}},"31":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"32":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"33":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"34":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"35":{"start":{"line":97,"column":20},"end":{"line":97,"column":null}},"36":{"start":{"line":98,"column":30},"end":{"line":98,"column":null}},"37":{"start":{"line":99,"column":22},"end":{"line":101,"column":null}},"38":{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},"39":{"start":{"line":104,"column":4},"end":{"line":112,"column":null}},"40":{"start":{"line":115,"column":18},"end":{"line":115,"column":null}},"41":{"start":{"line":116,"column":21},"end":{"line":116,"column":null}},"42":{"start":{"line":117,"column":16},"end":{"line":117,"column":null}},"43":{"start":{"line":117,"column":33},"end":{"line":117,"column":53}},"44":{"start":{"line":118,"column":2},"end":{"line":160,"column":null}},"45":{"start":{"line":119,"column":21},"end":{"line":125,"column":null}},"46":{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},"47":{"start":{"line":127,"column":6},"end":{"line":135,"column":null}},"48":{"start":{"line":137,"column":17},"end":{"line":137,"column":null}},"49":{"start":{"line":138,"column":20},"end":{"line":138,"column":null}},"50":{"start":{"line":139,"column":4},"end":{"line":147,"column":null}},"51":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"52":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"53":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"54":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"55":{"start":{"line":166,"column":2},"end":{"line":166,"column":null}},"56":{"start":{"line":170,"column":33},"end":{"line":170,"column":null}},"57":{"start":{"line":171,"column":15},"end":{"line":171,"column":null}},"58":{"start":{"line":172,"column":16},"end":{"line":172,"column":null}},"59":{"start":{"line":173,"column":2},"end":{"line":188,"column":null}},"60":{"start":{"line":173,"column":15},"end":{"line":173,"column":18}},"61":{"start":{"line":174,"column":18},"end":{"line":174,"column":null}},"62":{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},"63":{"start":{"line":176,"column":6},"end":{"line":176,"column":null}},"64":{"start":{"line":177,"column":6},"end":{"line":177,"column":null}},"65":{"start":{"line":178,"column":6},"end":{"line":178,"column":null}},"66":{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},"67":{"start":{"line":181,"column":6},"end":{"line":181,"column":null}},"68":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"69":{"start":{"line":183,"column":6},"end":{"line":183,"column":null}},"70":{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},"71":{"start":{"line":186,"column":6},"end":{"line":186,"column":null}},"72":{"start":{"line":189,"column":2},"end":{"line":189,"column":null}},"73":{"start":{"line":193,"column":15},"end":{"line":193,"column":null}},"74":{"start":{"line":194,"column":17},"end":{"line":194,"column":null}},"75":{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},"76":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"77":{"start":{"line":198,"column":2},"end":{"line":198,"column":null}},"78":{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},"79":{"start":{"line":202,"column":2},"end":{"line":205,"column":null}},"80":{"start":{"line":203,"column":4},"end":{"line":203,"column":null}},"81":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}}},"fnMap":{"0":{"name":"stripHtml","decl":{"start":{"line":42,"column":9},"end":{"line":42,"column":19}},"loc":{"start":{"line":42,"column":41},"end":{"line":44,"column":null}},"line":42},"1":{"name":"escapeRegExp","decl":{"start":{"line":46,"column":9},"end":{"line":46,"column":22}},"loc":{"start":{"line":46,"column":45},"end":{"line":48,"column":null}},"line":46},"2":{"name":"referenceMatches","decl":{"start":{"line":55,"column":9},"end":{"line":55,"column":26}},"loc":{"start":{"line":55,"column":72},"end":{"line":64,"column":null}},"line":55},"3":{"name":"extractLagradetMatches","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":39}},"loc":{"start":{"line":66,"column":126},"end":{"line":81,"column":null}},"line":66},"4":{"name":"dedupeMatches","decl":{"start":{"line":83,"column":9},"end":{"line":83,"column":23}},"loc":{"start":{"line":83,"column":75},"end":{"line":93,"column":null}},"line":83},"5":{"name":"fetchLagradetStatus","decl":{"start":{"line":95,"column":22},"end":{"line":95,"column":42}},"loc":{"start":{"line":95,"column":127},"end":{"line":161,"column":null}},"line":95},"6":{"name":"(anonymous_6)","decl":{"start":{"line":117,"column":16},"end":{"line":117,"column":33}},"loc":{"start":{"line":117,"column":33},"end":{"line":117,"column":53}},"line":117},"7":{"name":"persistLagradetStatus","decl":{"start":{"line":163,"column":16},"end":{"line":163,"column":38}},"loc":{"start":{"line":163,"column":108},"end":{"line":167,"column":null}},"line":163},"8":{"name":"parseArgs","decl":{"start":{"line":169,"column":9},"end":{"line":169,"column":19}},"loc":{"start":{"line":169,"column":108},"end":{"line":190,"column":null}},"line":169},"9":{"name":"main","decl":{"start":{"line":192,"column":15},"end":{"line":192,"column":37}},"loc":{"start":{"line":192,"column":37},"end":{"line":199,"column":null}},"line":192},"10":{"name":"(anonymous_10)","decl":{"start":{"line":202,"column":9},"end":{"line":202,"column":16}},"loc":{"start":{"line":202,"column":35},"end":{"line":205,"column":3}},"line":202}},"branchMap":{"0":{"loc":{"start":{"line":66,"column":72},"end":{"line":66,"column":126}},"type":"default-arg","locations":[{"start":{"line":66,"column":82},"end":{"line":66,"column":126}}],"line":66},"1":{"loc":{"start":{"line":71,"column":28},"end":{"line":71,"column":42}},"type":"binary-expr","locations":[{"start":{"line":71,"column":28},"end":{"line":71,"column":40}},{"start":{"line":71,"column":40},"end":{"line":71,"column":42}}],"line":71},"2":{"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"3":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":25}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":17}},{"start":{"line":72,"column":17},"end":{"line":72,"column":25}}],"line":72},"4":{"loc":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74},"5":{"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":88},"6":{"loc":{"start":{"line":95,"column":68},"end":{"line":95,"column":127}},"type":"default-arg","locations":[{"start":{"line":95,"column":98},"end":{"line":95,"column":127}}],"line":95},"7":{"loc":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":96,"column":18},"end":{"line":96,"column":36}},{"start":{"line":96,"column":36},"end":{"line":96,"column":null}}],"line":96},"8":{"loc":{"start":{"line":97,"column":20},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":20},"end":{"line":97,"column":38}},{"start":{"line":97,"column":38},"end":{"line":97,"column":null}}],"line":97},"9":{"loc":{"start":{"line":98,"column":30},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":30},"end":{"line":98,"column":51}},{"start":{"line":98,"column":51},"end":{"line":98,"column":null}}],"line":98},"10":{"loc":{"start":{"line":99,"column":22},"end":{"line":101,"column":null}},"type":"cond-expr","locations":[{"start":{"line":100,"column":6},"end":{"line":100,"column":null}},{"start":{"line":101,"column":6},"end":{"line":101,"column":null}}],"line":99},"11":{"loc":{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":103},"12":{"loc":{"start":{"line":115,"column":18},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":18},"end":{"line":115,"column":36}},{"start":{"line":115,"column":36},"end":{"line":115,"column":null}}],"line":115},"13":{"loc":{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":126},"14":{"loc":{"start":{"line":144,"column":14},"end":{"line":144,"column":null}},"type":"cond-expr","locations":[{"start":{"line":144,"column":35},"end":{"line":144,"column":45}},{"start":{"line":144,"column":45},"end":{"line":144,"column":null}}],"line":144},"15":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":33},"end":{"line":146,"column":108}},{"start":{"line":146,"column":108},"end":{"line":146,"column":null}}],"line":146},"16":{"loc":{"start":{"line":156,"column":13},"end":{"line":156,"column":null}},"type":"cond-expr","locations":[{"start":{"line":156,"column":38},"end":{"line":156,"column":54}},{"start":{"line":156,"column":54},"end":{"line":156,"column":null}}],"line":156},"17":{"loc":{"start":{"line":163,"column":62},"end":{"line":163,"column":108}},"type":"default-arg","locations":[{"start":{"line":163,"column":75},"end":{"line":163,"column":108}}],"line":163},"18":{"loc":{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":175},"19":{"loc":{"start":{"line":176,"column":18},"end":{"line":176,"column":null}},"type":"binary-expr","locations":[{"start":{"line":176,"column":18},"end":{"line":176,"column":33}},{"start":{"line":176,"column":33},"end":{"line":176,"column":null}}],"line":176},"20":{"loc":{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},{"start":{},"end":{}}],"line":180},"21":{"loc":{"start":{"line":181,"column":15},"end":{"line":181,"column":null}},"type":"binary-expr","locations":[{"start":{"line":181,"column":15},"end":{"line":181,"column":30}},{"start":{"line":181,"column":30},"end":{"line":181,"column":null}}],"line":181},"22":{"loc":{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":185},"23":{"loc":{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":195},"24":{"loc":{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},"type":"if","locations":[{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},{"start":{},"end":{}}],"line":201},"25":{"loc":{"start":{"line":201,"column":66},"end":{"line":201,"column":87}},"type":"binary-expr","locations":[{"start":{"line":201,"column":66},"end":{"line":201,"column":85}},{"start":{"line":201,"column":85},"end":{"line":201,"column":87}}],"line":201},"26":{"loc":{"start":{"line":203,"column":37},"end":{"line":203,"column":93}},"type":"cond-expr","locations":[{"start":{"line":203,"column":62},"end":{"line":203,"column":78}},{"start":{"line":203,"column":78},"end":{"line":203,"column":93}}],"line":203}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":4,"8":4,"9":4,"10":4,"11":4,"12":4,"13":2,"14":2,"15":2,"16":4,"17":4,"18":4,"19":0,"20":4,"21":4,"22":3,"23":1,"24":2,"25":2,"26":2,"27":2,"28":1,"29":1,"30":0,"31":1,"32":1,"33":2,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":0,"41":1,"42":1,"43":0,"44":1,"45":1,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":1,"79":0,"80":0,"81":0},"f":{"0":4,"1":4,"2":4,"3":2,"4":2,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[2],"1":[4,0],"2":[0,4],"3":[4,4],"4":[3,1],"5":[0,1],"6":[1],"7":[1,1],"8":[1,1],"9":[1,1],"10":[0,1],"11":[1,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0],"18":[0,0],"19":[0,0],"20":[0,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[0,1],"25":[1,0],"26":[0,0]},"meta":{"lastBranch":27,"lastFunction":11,"lastStatement":82,"seen":{"s:34:18:34:Infinity":0,"s:35:18:35:Infinity":1,"s:36:39:36:Infinity":2,"s:37:34:37:Infinity":3,"s:38:43:38:Infinity":4,"s:39:16:39:Infinity":5,"s:40:15:40:Infinity":6,"f:42:9:42:19":0,"s:43:2:43:Infinity":7,"f:46:9:46:22":1,"s:47:2:47:Infinity":8,"f:55:9:55:26":2,"s:60:18:60:Infinity":9,"s:61:19:61:Infinity":10,"s:62:19:62:Infinity":11,"s:63:2:63:Infinity":12,"f:66:16:66:39":3,"b:66:82:66:126":0,"s:67:35:67:Infinity":13,"s:68:17:68:Infinity":14,"s:69:2:79:Infinity":15,"s:70:17:70:Infinity":16,"s:71:18:71:Infinity":17,"b:71:28:71:40:71:40:71:42":1,"b:72:4:72:Infinity:undefined:undefined:undefined:undefined":2,"s:72:4:72:Infinity":18,"b:72:8:72:17:72:17:72:25":3,"s:72:25:72:Infinity":19,"s:73:21:73:Infinity":20,"b:74:4:74:Infinity:undefined:undefined:undefined:undefined":4,"s:74:4:74:Infinity":21,"s:74:45:74:Infinity":22,"s:75:4:78:Infinity":23,"s:80:2:80:Infinity":24,"f:83:9:83:23":4,"s:84:15:84:Infinity":25,"s:85:35:85:Infinity":26,"s:86:2:91:Infinity":27,"s:87:16:87:Infinity":28,"b:88:4:88:Infinity:undefined:undefined:undefined:undefined":5,"s:88:4:88:Infinity":29,"s:88:23:88:Infinity":30,"s:89:4:89:Infinity":31,"s:90:4:90:Infinity":32,"s:92:2:92:Infinity":33,"f:95:22:95:42":5,"b:95:98:95:127":6,"s:96:18:96:Infinity":34,"b:96:18:96:36:96:36:96:Infinity":7,"s:97:20:97:Infinity":35,"b:97:20:97:38:97:38:97:Infinity":8,"s:98:30:98:Infinity":36,"b:98:30:98:51:98:51:98:Infinity":9,"s:99:22:101:Infinity":37,"b:100:6:100:Infinity:101:6:101:Infinity":10,"b:103:2:113:Infinity:undefined:undefined:undefined:undefined":11,"s:103:2:113:Infinity":38,"s:104:4:112:Infinity":39,"s:115:18:115:Infinity":40,"b:115:18:115:36:115:36:115:Infinity":12,"s:116:21:116:Infinity":41,"s:117:16:117:Infinity":42,"f:117:16:117:33":6,"s:117:33:117:53":43,"s:118:2:160:Infinity":44,"s:119:21:125:Infinity":45,"b:126:4:136:Infinity:undefined:undefined:undefined:undefined":13,"s:126:4:136:Infinity":46,"s:127:6:135:Infinity":47,"s:137:17:137:Infinity":48,"s:138:20:138:Infinity":49,"s:139:4:147:Infinity":50,"b:144:35:144:45:144:45:144:Infinity":14,"b:146:33:146:108:146:108:146:Infinity":15,"s:149:4:157:Infinity":51,"b:156:38:156:54:156:54:156:Infinity":16,"s:159:4:159:Infinity":52,"f:163:16:163:38":7,"b:163:75:163:108":17,"s:164:2:164:Infinity":53,"s:165:2:165:Infinity":54,"s:166:2:166:Infinity":55,"f:169:9:169:19":8,"s:170:33:170:Infinity":56,"s:171:15:171:Infinity":57,"s:172:16:172:Infinity":58,"s:173:2:188:Infinity":59,"s:173:15:173:18":60,"s:174:18:174:Infinity":61,"b:175:4:179:Infinity:undefined:undefined:undefined:undefined":18,"s:175:4:179:Infinity":62,"s:176:6:176:Infinity":63,"b:176:18:176:33:176:33:176:Infinity":19,"s:177:6:177:Infinity":64,"s:178:6:178:Infinity":65,"b:180:4:184:Infinity:undefined:undefined:undefined:undefined":20,"s:180:4:184:Infinity":66,"s:181:6:181:Infinity":67,"b:181:15:181:30:181:30:181:Infinity":21,"s:182:6:182:Infinity":68,"s:183:6:183:Infinity":69,"b:185:4:187:Infinity:undefined:undefined:undefined:undefined":22,"s:185:4:187:Infinity":70,"s:186:6:186:Infinity":71,"s:189:2:189:Infinity":72,"f:192:15:192:37":9,"s:193:15:193:Infinity":73,"s:194:17:194:Infinity":74,"b:195:2:197:Infinity:undefined:undefined:undefined:undefined":23,"s:195:2:197:Infinity":75,"s:196:4:196:Infinity":76,"s:198:2:198:Infinity":77,"b:201:0:206:Infinity:undefined:undefined:undefined:undefined":24,"s:201:0:206:Infinity":78,"b:201:66:201:85:201:85:201:87":25,"s:202:2:205:Infinity":79,"f:202:9:202:16":10,"s:203:4:203:Infinity":80,"b:203:62:203:78:203:78:203:93":26,"s:204:4:204:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/gateway-resolver.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/gateway-resolver.ts","statementMap":{"0":{"start":{"line":24,"column":33},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":35},"end":{"line":25,"column":null}},"2":{"start":{"line":33,"column":37},"end":{"line":33,"column":null}},"3":{"start":{"line":42,"column":18},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":44,"column":19},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"7":{"start":{"line":45,"column":47},"end":{"line":45,"column":null}},"8":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":61,"column":null}},"10":{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},"11":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"12":{"start":{"line":51,"column":22},"end":{"line":51,"column":null}},"13":{"start":{"line":52,"column":19},"end":{"line":52,"column":null}},"14":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"15":{"start":{"line":53,"column":48},"end":{"line":53,"column":null}},"16":{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},"17":{"start":{"line":55,"column":23},"end":{"line":55,"column":null}},"18":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"19":{"start":{"line":56,"column":51},"end":{"line":56,"column":null}},"20":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"21":{"start":{"line":72,"column":20},"end":{"line":72,"column":null}},"22":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"23":{"start":{"line":73,"column":17},"end":{"line":73,"column":null}},"24":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"25":{"start":{"line":75,"column":2},"end":{"line":84,"column":null}},"26":{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},"27":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"28":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"29":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"30":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"31":{"start":{"line":80,"column":59},"end":{"line":80,"column":null}},"32":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"33":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"34":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"35":{"start":{"line":114,"column":29},"end":{"line":114,"column":null}},"36":{"start":{"line":115,"column":21},"end":{"line":115,"column":null}},"37":{"start":{"line":116,"column":2},"end":{"line":127,"column":null}},"38":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"39":{"start":{"line":117,"column":36},"end":{"line":117,"column":null}},"40":{"start":{"line":118,"column":16},"end":{"line":118,"column":null}},"41":{"start":{"line":119,"column":20},"end":{"line":119,"column":null}},"42":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"43":{"start":{"line":120,"column":29},"end":{"line":120,"column":null}},"44":{"start":{"line":121,"column":23},"end":{"line":121,"column":null}},"45":{"start":{"line":122,"column":21},"end":{"line":122,"column":null}},"46":{"start":{"line":123,"column":20},"end":{"line":123,"column":null}},"47":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"48":{"start":{"line":124,"column":36},"end":{"line":124,"column":null}},"49":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"50":{"start":{"line":140,"column":19},"end":{"line":140,"column":null}},"51":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"52":{"start":{"line":141,"column":16},"end":{"line":141,"column":null}},"53":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"54":{"start":{"line":142,"column":28},"end":{"line":142,"column":null}},"55":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}}},"fnMap":{"0":{"name":"getAwfGatewayPort","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":44}},"loc":{"start":{"line":41,"column":44},"end":{"line":63,"column":null}},"line":41},"1":{"name":"getAwfGatewayDomain","decl":{"start":{"line":71,"column":16},"end":{"line":71,"column":46}},"loc":{"start":{"line":71,"column":46},"end":{"line":86,"column":null}},"line":71},"2":{"name":"buildAwfGatewayUrl","decl":{"start":{"line":92,"column":16},"end":{"line":92,"column":35}},"loc":{"start":{"line":92,"column":63},"end":{"line":94,"column":null}},"line":92},"3":{"name":"isAwfGatewayActive","decl":{"start":{"line":113,"column":16},"end":{"line":113,"column":46}},"loc":{"start":{"line":113,"column":46},"end":{"line":129,"column":null}},"line":113},"4":{"name":"getDefaultMcpServerUrl","decl":{"start":{"line":139,"column":16},"end":{"line":139,"column":49}},"loc":{"start":{"line":139,"column":49},"end":{"line":144,"column":null}},"line":139}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":45,"column":8},"end":{"line":45,"column":47}},"type":"binary-expr","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":35}},{"start":{"line":45,"column":35},"end":{"line":45,"column":47}}],"line":45},"3":{"loc":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":21},"end":{"line":47,"column":56}},{"start":{"line":47,"column":56},"end":{"line":47,"column":null}}],"line":47},"4":{"loc":{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":49},"5":{"loc":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"6":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":48}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":38}},{"start":{"line":53,"column":38},"end":{"line":53,"column":48}}],"line":53},"7":{"loc":{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":54},"8":{"loc":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"9":{"loc":{"start":{"line":56,"column":12},"end":{"line":56,"column":51}},"type":"binary-expr","locations":[{"start":{"line":56,"column":12},"end":{"line":56,"column":39}},{"start":{"line":56,"column":39},"end":{"line":56,"column":51}}],"line":56},"10":{"loc":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"11":{"loc":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":21},"end":{"line":74,"column":56}},{"start":{"line":74,"column":56},"end":{"line":74,"column":null}}],"line":74},"12":{"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":76},"13":{"loc":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"14":{"loc":{"start":{"line":80,"column":10},"end":{"line":80,"column":59}},"type":"binary-expr","locations":[{"start":{"line":80,"column":10},"end":{"line":80,"column":40}},{"start":{"line":80,"column":40},"end":{"line":80,"column":59}}],"line":80},"15":{"loc":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"16":{"loc":{"start":{"line":115,"column":21},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":21},"end":{"line":115,"column":56}},{"start":{"line":115,"column":56},"end":{"line":115,"column":null}}],"line":115},"17":{"loc":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":117},"18":{"loc":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":120},"19":{"loc":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":124},"20":{"loc":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"21":{"loc":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":142}},"s":{"0":38,"1":38,"2":38,"3":10,"4":10,"5":1,"6":1,"7":1,"8":9,"9":10,"10":10,"11":7,"12":7,"13":7,"14":7,"15":3,"16":4,"17":0,"18":0,"19":0,"20":6,"21":10,"22":10,"23":0,"24":10,"25":10,"26":10,"27":7,"28":7,"29":7,"30":7,"31":3,"32":7,"33":10,"34":37,"35":3,"36":34,"37":37,"38":37,"39":25,"40":9,"41":9,"42":9,"43":5,"44":3,"45":3,"46":37,"47":37,"48":2,"49":2,"50":38,"51":38,"52":1,"53":37,"54":37,"55":27},"f":{"0":10,"1":10,"2":10,"3":37,"4":38},"b":{"0":[1,9],"1":[1,0],"2":[1,1],"3":[9,2],"4":[7,3],"5":[3,4],"6":[7,3],"7":[0,4],"8":[0,0],"9":[0,0],"10":[0,10],"11":[10,3],"12":[7,3],"13":[3,4],"14":[7,3],"15":[3,34],"16":[34,23],"17":[25,12],"18":[5,4],"19":[2,35],"20":[1,37],"21":[10,27]},"meta":{"lastBranch":22,"lastFunction":5,"lastStatement":56,"seen":{"s:24:33:24:Infinity":0,"s:25:35:25:Infinity":1,"s:33:37:33:Infinity":2,"f:41:16:41:44":0,"s:42:18:42:Infinity":3,"b:43:2:46:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:46:Infinity":4,"s:44:19:44:Infinity":5,"b:45:4:45:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:45:Infinity":6,"b:45:8:45:35:45:35:45:47":2,"s:45:47:45:Infinity":7,"s:47:21:47:Infinity":8,"b:47:21:47:56:47:56:47:Infinity":3,"s:48:2:61:Infinity":9,"b:49:4:58:Infinity:undefined:undefined:undefined:undefined":4,"s:49:4:58:Infinity":10,"s:50:18:50:Infinity":11,"s:51:22:51:Infinity":12,"s:52:19:52:Infinity":13,"b:53:6:53:Infinity:undefined:undefined:undefined:undefined":5,"s:53:6:53:Infinity":14,"b:53:10:53:38:53:38:53:48":6,"s:53:48:53:Infinity":15,"b:54:6:57:Infinity:undefined:undefined:undefined:undefined":7,"s:54:6:57:Infinity":16,"s:55:23:55:Infinity":17,"b:56:8:56:Infinity:undefined:undefined:undefined:undefined":8,"s:56:8:56:Infinity":18,"b:56:12:56:39:56:39:56:51":9,"s:56:51:56:Infinity":19,"s:62:2:62:Infinity":20,"f:71:16:71:46":1,"s:72:20:72:Infinity":21,"b:73:2:73:Infinity:undefined:undefined:undefined:undefined":10,"s:73:2:73:Infinity":22,"s:73:17:73:Infinity":23,"s:74:21:74:Infinity":24,"b:74:21:74:56:74:56:74:Infinity":11,"s:75:2:84:Infinity":25,"b:76:4:81:Infinity:undefined:undefined:undefined:undefined":12,"s:76:4:81:Infinity":26,"s:77:18:77:Infinity":27,"s:78:22:78:Infinity":28,"s:79:21:79:Infinity":29,"b:80:6:80:Infinity:undefined:undefined:undefined:undefined":13,"s:80:6:80:Infinity":30,"b:80:10:80:40:80:40:80:59":14,"s:80:59:80:Infinity":31,"s:85:2:85:Infinity":32,"f:92:16:92:35":2,"s:93:2:93:Infinity":33,"f:113:16:113:46":3,"b:114:2:114:Infinity:undefined:undefined:undefined:undefined":15,"s:114:2:114:Infinity":34,"s:114:29:114:Infinity":35,"s:115:21:115:Infinity":36,"b:115:21:115:56:115:56:115:Infinity":16,"s:116:2:127:Infinity":37,"b:117:4:117:Infinity:undefined:undefined:undefined:undefined":17,"s:117:4:117:Infinity":38,"s:117:36:117:Infinity":39,"s:118:16:118:Infinity":40,"s:119:20:119:Infinity":41,"b:120:4:120:Infinity:undefined:undefined:undefined:undefined":18,"s:120:4:120:Infinity":42,"s:120:29:120:Infinity":43,"s:121:23:121:Infinity":44,"s:122:21:122:Infinity":45,"s:123:20:123:Infinity":46,"b:124:4:124:Infinity:undefined:undefined:undefined:undefined":19,"s:124:4:124:Infinity":47,"s:124:36:124:Infinity":48,"s:128:2:128:Infinity":49,"f:139:16:139:49":4,"s:140:19:140:Infinity":50,"b:141:2:141:Infinity:undefined:undefined:undefined:undefined":20,"s:141:2:141:Infinity":51,"s:141:16:141:Infinity":52,"b:142:2:142:Infinity:undefined:undefined:undefined:undefined":21,"s:142:2:142:Infinity":53,"s:142:28:142:Infinity":54,"s:143:2:143:Infinity":55}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/coverage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/coverage.ts","statementMap":{"0":{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},"1":{"start":{"line":11,"column":33},"end":{"line":11,"column":null}},"2":{"start":{"line":12,"column":18},"end":{"line":12,"column":null}},"3":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"4":{"start":{"line":20,"column":21},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":2},"end":{"line":31,"column":null}},"6":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"7":{"start":{"line":29,"column":6},"end":{"line":29,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"9":{"start":{"line":39,"column":24},"end":{"line":39,"column":null}},"10":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"11":{"start":{"line":40,"column":39},"end":{"line":40,"column":104}},"12":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"13":{"start":{"line":56,"column":38},"end":{"line":56,"column":null}},"14":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"15":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"16":{"start":{"line":66,"column":18},"end":{"line":68,"column":null}},"17":{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},"18":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"19":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"20":{"start":{"line":90,"column":2},"end":{"line":100,"column":null}},"21":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"asCleanString","decl":{"start":{"line":10,"column":9},"end":{"line":10,"column":23}},"loc":{"start":{"line":10,"column":47},"end":{"line":14,"column":null}},"line":10},"1":{"name":"extractDocumentDate","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":36}},"loc":{"start":{"line":19,"column":84},"end":{"line":33,"column":null}},"line":19},"2":{"name":"hasSubstantiveFullText","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":39}},"loc":{"start":{"line":38,"column":81},"end":{"line":41,"column":null}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":40,"column":23},"end":{"line":40,"column":29}},"loc":{"start":{"line":40,"column":39},"end":{"line":40,"column":104}},"line":40},"4":{"name":"inferDocumentCoverageState","decl":{"start":{"line":52,"column":16},"end":{"line":52,"column":null}},"loc":{"start":{"line":55,"column":20},"end":{"line":75,"column":null}},"line":55},"5":{"name":"buildMcpProvenance","decl":{"start":{"line":80,"column":16},"end":{"line":80,"column":35}},"loc":{"start":{"line":89,"column":18},"end":{"line":101,"column":null}},"line":89},"6":{"name":"attachCoverageMetadata","decl":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"loc":{"start":{"line":113,"column":2},"end":{"line":122,"column":null}},"line":113}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},"type":"if","locations":[{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},{"start":{},"end":{}}],"line":11},"1":{"loc":{"start":{"line":13,"column":9},"end":{"line":13,"column":null}},"type":"cond-expr","locations":[{"start":{"line":13,"column":40},"end":{"line":13,"column":45}},{"start":{"line":13,"column":45},"end":{"line":13,"column":null}}],"line":13},"2":{"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"3":{"loc":{"start":{"line":28,"column":8},"end":{"line":28,"column":72}},"type":"binary-expr","locations":[{"start":{"line":28,"column":8},"end":{"line":28,"column":41}},{"start":{"line":28,"column":41},"end":{"line":28,"column":72}}],"line":28},"4":{"loc":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"type":"default-arg","locations":[{"start":{"line":54,"column":76},"end":{"line":54,"column":null}}],"line":54},"5":{"loc":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":24},"end":{"line":58,"column":63}},{"start":{"line":58,"column":63},"end":{"line":58,"column":null}}],"line":58},"7":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":21}},{"start":{"line":67,"column":21},"end":{"line":67,"column":37}},{"start":{"line":67,"column":37},"end":{"line":67,"column":null}}],"line":67},"8":{"loc":{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":70},"9":{"loc":{"start":{"line":70,"column":6},"end":{"line":70,"column":44}},"type":"binary-expr","locations":[{"start":{"line":70,"column":6},"end":{"line":70,"column":35}},{"start":{"line":70,"column":35},"end":{"line":70,"column":44}}],"line":70},"10":{"loc":{"start":{"line":97,"column":15},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":15},"end":{"line":97,"column":36}},{"start":{"line":97,"column":36},"end":{"line":97,"column":null}}],"line":97},"11":{"loc":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":17},"end":{"line":98,"column":40}},{"start":{"line":98,"column":40},"end":{"line":98,"column":null}}],"line":98},"12":{"loc":{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},"type":"cond-expr","locations":[{"start":{"line":99,"column":56},"end":{"line":99,"column":87}},{"start":{"line":99,"column":87},"end":{"line":99,"column":null}}],"line":99},"13":{"loc":{"start":{"line":99,"column":8},"end":{"line":99,"column":56}},"type":"binary-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":27}},{"start":{"line":99,"column":27},"end":{"line":99,"column":56}}],"line":99},"14":{"loc":{"start":{"line":118,"column":8},"end":{"line":120,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":null}},{"start":{"line":120,"column":8},"end":{"line":120,"column":null}}],"line":118},"15":{"loc":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"type":"binary-expr","locations":[{"start":{"line":118,"column":8},"end":{"line":118,"column":30}},{"start":{"line":118,"column":30},"end":{"line":118,"column":null}}],"line":118}},"s":{"0":247,"1":219,"2":28,"3":28,"4":49,"5":49,"6":81,"7":41,"8":8,"9":68,"10":68,"11":247,"12":68,"13":19,"14":49,"15":68,"16":68,"17":68,"18":1,"19":48,"20":112,"21":34},"f":{"0":247,"1":49,"2":68,"3":247,"4":68,"5":112,"6":34},"b":{"0":[219,28],"1":[2,26],"2":[41,40],"3":[81,41],"4":[68],"5":[19,49],"6":[49,30],"7":[68,19,19],"8":[1,67],"9":[68,19],"10":[112,111],"11":[112,112],"12":[1,111],"13":[112,1],"14":[0,34],"15":[34,0]},"meta":{"lastBranch":16,"lastFunction":7,"lastStatement":22,"seen":{"f:10:9:10:23":0,"b:11:2:11:Infinity:undefined:undefined:undefined:undefined":0,"s:11:2:11:Infinity":0,"s:11:33:11:Infinity":1,"s:12:18:12:Infinity":2,"s:13:2:13:Infinity":3,"b:13:40:13:45:13:45:13:Infinity":1,"f:19:16:19:36":1,"s:20:21:26:Infinity":4,"s:27:2:31:Infinity":5,"b:28:4:30:Infinity:undefined:undefined:undefined:undefined":2,"s:28:4:30:Infinity":6,"b:28:8:28:41:28:41:28:72":3,"s:29:6:29:Infinity":7,"s:32:2:32:Infinity":8,"f:38:16:38:39":2,"s:39:24:39:Infinity":9,"s:40:2:40:Infinity":10,"f:40:23:40:29":3,"s:40:39:40:104":11,"f:52:16:52:Infinity":4,"b:54:76:54:Infinity":4,"b:56:2:56:Infinity:undefined:undefined:undefined:undefined":5,"s:56:2:56:Infinity":12,"s:56:38:56:Infinity":13,"s:58:24:58:Infinity":14,"b:58:24:58:63:58:63:58:Infinity":6,"s:59:23:59:Infinity":15,"s:66:18:68:Infinity":16,"b:67:4:67:21:67:21:67:37:67:37:67:Infinity":7,"b:70:2:72:Infinity:undefined:undefined:undefined:undefined":8,"s:70:2:72:Infinity":17,"b:70:6:70:35:70:35:70:44":9,"s:71:4:71:Infinity":18,"s:74:2:74:Infinity":19,"f:80:16:80:35":5,"s:90:2:100:Infinity":20,"b:97:15:97:36:97:36:97:Infinity":10,"b:98:17:98:40:98:40:98:Infinity":11,"b:99:56:99:87:99:87:99:Infinity":12,"b:99:8:99:27:99:27:99:56":13,"f:106:16:106:Infinity":6,"s:114:2:121:Infinity":21,"b:119:8:119:Infinity:120:8:120:Infinity":14,"b:118:8:118:30:118:30:118:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/document-types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/document-types.ts","statementMap":{"0":{"start":{"line":16,"column":57},"end":{"line":36,"column":null}},"1":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"2":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"3":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":17},"end":{"line":57,"column":null}},"7":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"8":{"start":{"line":58,"column":23},"end":{"line":58,"column":null}},"9":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"10":{"start":{"line":59,"column":33},"end":{"line":59,"column":null}},"11":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}}},"fnMap":{"0":{"name":"normalizeDocumentType","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":38}},"loc":{"start":{"line":43,"column":74},"end":{"line":47,"column":null}},"line":43},"1":{"name":"annotateDocumentTypes","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":38}},"loc":{"start":{"line":55,"column":93},"end":{"line":61,"column":null}},"line":55}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":9},"end":{"line":46,"column":34}},{"start":{"line":46,"column":34},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":56,"column":53},"end":{"line":56,"column":69}},{"start":{"line":56,"column":69},"end":{"line":56,"column":null}}],"line":56},"3":{"loc":{"start":{"line":57,"column":17},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":53},"end":{"line":57,"column":69}},{"start":{"line":57,"column":69},"end":{"line":57,"column":null}}],"line":57},"4":{"loc":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"5":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"6":{"loc":{"start":{"line":59,"column":6},"end":{"line":59,"column":33}},"type":"binary-expr","locations":[{"start":{"line":59,"column":6},"end":{"line":59,"column":25}},{"start":{"line":59,"column":25},"end":{"line":59,"column":33}}],"line":59}},"s":{"0":32,"1":25,"2":4,"3":21,"4":21,"5":8,"6":8,"7":8,"8":7,"9":8,"10":1,"11":8},"f":{"0":25,"1":8},"b":{"0":[4,21],"1":[21,1],"2":[6,2],"3":[1,7],"4":[7,1],"5":[1,7],"6":[8,8]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":12,"seen":{"s:16:57:36:Infinity":0,"f:43:16:43:38":0,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:44:Infinity":1,"s:44:15:44:Infinity":2,"s:45:16:45:Infinity":3,"s:46:2:46:Infinity":4,"b:46:9:46:34:46:34:46:Infinity":1,"f:55:16:55:38":1,"s:56:17:56:Infinity":5,"b:56:53:56:69:56:69:56:Infinity":2,"s:57:17:57:Infinity":6,"b:57:53:57:69:57:69:57:Infinity":3,"b:58:2:58:Infinity:undefined:undefined:undefined:undefined":4,"s:58:2:58:Infinity":7,"s:58:23:58:Infinity":8,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":5,"s:59:2:59:Infinity":9,"b:59:6:59:25:59:25:59:33":6,"s:59:33:59:Infinity":10,"s:60:2:60:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/not-indexed.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/not-indexed.ts","statementMap":{"0":{"start":{"line":27,"column":42},"end":{"line":32,"column":null}},"1":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"2":{"start":{"line":43,"column":16},"end":{"line":43,"column":null}},"3":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"4":{"start":{"line":44,"column":40},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"7":{"start":{"line":46,"column":45},"end":{"line":46,"column":62}},"8":{"start":{"line":46,"column":65},"end":{"line":46,"column":null}},"9":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"10":{"start":{"line":50,"column":83},"end":{"line":50,"column":null}},"11":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}}},"fnMap":{"0":{"name":"classifyDocumentErrorAsNotIndexed","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":50}},"loc":{"start":{"line":42,"column":92},"end":{"line":52,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":46,"column":33},"end":{"line":46,"column":39}},"loc":{"start":{"line":46,"column":45},"end":{"line":46,"column":62}},"line":46}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"2":{"loc":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":46},"3":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"4":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":83}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":15}},{"start":{"line":50,"column":15},"end":{"line":50,"column":54}},{"start":{"line":50,"column":54},"end":{"line":50,"column":83}}],"line":50}},"s":{"0":35,"1":25,"2":1,"3":24,"4":10,"5":14,"6":14,"7":45,"8":6,"9":8,"10":4,"11":4},"f":{"0":25,"1":45},"b":{"0":[1,24],"1":[10,14],"2":[6,8],"3":[4,4],"4":[8,7,4]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":12,"seen":{"s:27:42:32:Infinity":0,"f:42:16:42:50":0,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":1,"s:43:16:43:Infinity":2,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":1,"s:44:2:44:Infinity":3,"s:44:40:44:Infinity":4,"s:45:16:45:Infinity":5,"b:46:2:46:Infinity:undefined:undefined:undefined:undefined":2,"s:46:2:46:Infinity":6,"f:46:33:46:39":1,"s:46:45:46:62":7,"s:46:65:46:Infinity":8,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":3,"s:50:2:50:Infinity":9,"b:50:6:50:15:50:15:50:54:50:54:50:83":4,"s:50:83:50:Infinity":10,"s:51:2:51:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/transport.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/transport.ts","statementMap":{"0":{"start":{"line":18,"column":34},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":36},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:34:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/calendar.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/calendar.ts","statementMap":{"0":{"start":{"line":30,"column":42},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"2":{"start":{"line":31,"column":11},"end":{"line":31,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":32,"column":11},"end":{"line":32,"column":null}},"5":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},"7":{"start":{"line":37,"column":22},"end":{"line":37,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":40,"column":null}},"9":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"fetchCalendarEvents","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":29,"column":22},"end":{"line":44,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"default-arg","locations":[{"start":{"line":27,"column":23},"end":{"line":27,"column":null}}],"line":27},"1":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":23},"end":{"line":28,"column":null}}],"line":28},"2":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":31},"3":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"4":{"loc":{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":36},"5":{"loc":{"start":{"line":39,"column":39},"end":{"line":39,"column":null}},"type":"cond-expr","locations":[{"start":{"line":39,"column":71},"end":{"line":39,"column":83}},{"start":{"line":39,"column":83},"end":{"line":39,"column":null}}],"line":39},"6":{"loc":{"start":{"line":43,"column":10},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":10},"end":{"line":43,"column":34}},{"start":{"line":43,"column":34},"end":{"line":43,"column":56}},{"start":{"line":43,"column":56},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":9,"1":9,"2":1,"3":9,"4":1,"5":9,"6":9,"7":3,"8":3,"9":6},"f":{"0":9},"b":{"0":[9],"1":[9],"2":[1,8],"3":[1,8],"4":[3,6],"5":[2,1],"6":[6,6,2]},"meta":{"lastBranch":7,"lastFunction":1,"lastStatement":10,"seen":{"f:23:22:23:Infinity":0,"b:27:23:27:Infinity":0,"b:28:23:28:Infinity":1,"s:30:42:30:Infinity":0,"b:31:2:31:Infinity:undefined:undefined:undefined:undefined":2,"s:31:2:31:Infinity":1,"s:31:11:31:Infinity":2,"b:32:2:32:Infinity:undefined:undefined:undefined:undefined":3,"s:32:2:32:Infinity":3,"s:32:11:32:Infinity":4,"s:34:19:34:Infinity":5,"b:36:2:41:Infinity:undefined:undefined:undefined:undefined":4,"s:36:2:41:Infinity":6,"s:37:22:37:Infinity":7,"s:38:4:40:Infinity":8,"b:39:71:39:83:39:83:39:Infinity":5,"s:43:2:43:Infinity":9,"b:43:10:43:34:43:34:43:56:43:56:43:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/index.ts","statementMap":{"0":{"start":{"line":31,"column":38},"end":{"line":31,"column":null}},"1":{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"6":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"7":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"8":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"9":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"10":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"11":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"12":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"13":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"14":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"15":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"16":{"start":{"line":116,"column":2},"end":{"line":116,"column":null}},"17":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}},"18":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}}},"fnMap":{"0":{"name":"getDefaultClient","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":46}},"loc":{"start":{"line":34,"column":46},"end":{"line":39,"column":null}},"line":34},"1":{"name":"fetchCalendarEvents","decl":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"loc":{"start":{"line":43,"column":48},"end":{"line":45,"column":null}},"line":43},"2":{"name":"fetchCommitteeReports","decl":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"loc":{"start":{"line":49,"column":50},"end":{"line":51,"column":null}},"line":49},"3":{"name":"fetchPropositions","decl":{"start":{"line":53,"column":22},"end":{"line":53,"column":null}},"loc":{"start":{"line":55,"column":46},"end":{"line":57,"column":null}},"line":55},"4":{"name":"fetchMotions","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":null}},"loc":{"start":{"line":61,"column":41},"end":{"line":63,"column":null}},"line":61},"5":{"name":"searchDocuments","decl":{"start":{"line":65,"column":22},"end":{"line":65,"column":null}},"loc":{"start":{"line":67,"column":44},"end":{"line":69,"column":null}},"line":67},"6":{"name":"searchDocumentsWithDiagnostics","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":null}},"loc":{"start":{"line":73,"column":59},"end":{"line":75,"column":null}},"line":73},"7":{"name":"searchSpeeches","decl":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"loc":{"start":{"line":79,"column":43},"end":{"line":81,"column":null}},"line":79},"8":{"name":"fetchMPs","decl":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"loc":{"start":{"line":85,"column":37},"end":{"line":87,"column":null}},"line":85},"9":{"name":"fetchVotingRecords","decl":{"start":{"line":89,"column":22},"end":{"line":89,"column":null}},"loc":{"start":{"line":91,"column":47},"end":{"line":93,"column":null}},"line":91},"10":{"name":"fetchVotingRecordsWithDiagnostics","decl":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"loc":{"start":{"line":97,"column":62},"end":{"line":99,"column":null}},"line":97},"11":{"name":"fetchVotingGroup","decl":{"start":{"line":101,"column":22},"end":{"line":101,"column":null}},"loc":{"start":{"line":103,"column":45},"end":{"line":105,"column":null}},"line":103},"12":{"name":"fetchGovernmentDocuments","decl":{"start":{"line":107,"column":22},"end":{"line":107,"column":null}},"loc":{"start":{"line":109,"column":53},"end":{"line":111,"column":null}},"line":109},"13":{"name":"fetchDocumentDetails","decl":{"start":{"line":113,"column":22},"end":{"line":113,"column":null}},"loc":{"start":{"line":115,"column":49},"end":{"line":117,"column":null}},"line":115},"14":{"name":"fetchDocumentDetailsWithCoverage","decl":{"start":{"line":119,"column":22},"end":{"line":119,"column":null}},"loc":{"start":{"line":121,"column":61},"end":{"line":123,"column":null}},"line":121},"15":{"name":"enrichDocumentsWithContent","decl":{"start":{"line":125,"column":22},"end":{"line":125,"column":null}},"loc":{"start":{"line":127,"column":55},"end":{"line":129,"column":null}},"line":127}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":35}},"s":{"0":29,"1":28,"2":17,"3":28,"4":1,"5":1,"6":1,"7":1,"8":1,"9":0,"10":1,"11":1,"12":1,"13":0,"14":0,"15":1,"16":0,"17":0,"18":0},"f":{"0":28,"1":1,"2":1,"3":1,"4":1,"5":1,"6":0,"7":1,"8":1,"9":1,"10":0,"11":0,"12":1,"13":0,"14":0,"15":0},"b":{"0":[17,11]},"meta":{"lastBranch":1,"lastFunction":16,"lastStatement":19,"seen":{"s:31:38:31:Infinity":0,"f:34:16:34:46":0,"b:35:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:35:2:37:Infinity":1,"s:36:4:36:Infinity":2,"s:38:2:38:Infinity":3,"f:41:22:41:Infinity":1,"s:44:2:44:Infinity":4,"f:47:22:47:Infinity":2,"s:50:2:50:Infinity":5,"f:53:22:53:Infinity":3,"s:56:2:56:Infinity":6,"f:59:22:59:Infinity":4,"s:62:2:62:Infinity":7,"f:65:22:65:Infinity":5,"s:68:2:68:Infinity":8,"f:71:22:71:Infinity":6,"s:74:2:74:Infinity":9,"f:77:22:77:Infinity":7,"s:80:2:80:Infinity":10,"f:83:22:83:Infinity":8,"s:86:2:86:Infinity":11,"f:89:22:89:Infinity":9,"s:92:2:92:Infinity":12,"f:95:22:95:Infinity":10,"s:98:2:98:Infinity":13,"f:101:22:101:Infinity":11,"s:104:2:104:Infinity":14,"f:107:22:107:Infinity":12,"s:110:2:110:Infinity":15,"f:113:22:113:Infinity":13,"s:116:2:116:Infinity":16,"f:119:22:119:Infinity":14,"s:122:2:122:Infinity":17,"f:125:22:125:Infinity":15,"s:128:2:128:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/documents.ts","statementMap":{"0":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"1":{"start":{"line":43,"column":19},"end":{"line":46,"column":null}},"2":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"3":{"start":{"line":48,"column":22},"end":{"line":48,"column":null}},"4":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"5":{"start":{"line":50,"column":21},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":16},"end":{"line":65,"column":null}},"7":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"8":{"start":{"line":59,"column":24},"end":{"line":59,"column":null}},"9":{"start":{"line":60,"column":26},"end":{"line":63,"column":null}},"10":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"11":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"12":{"start":{"line":79,"column":19},"end":{"line":82,"column":null}},"13":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"14":{"start":{"line":91,"column":19},"end":{"line":94,"column":null}},"15":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"16":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"17":{"start":{"line":108,"column":2},"end":{"line":154,"column":null}},"18":{"start":{"line":109,"column":21},"end":{"line":109,"column":null}},"19":{"start":{"line":110,"column":26},"end":{"line":113,"column":null}},"20":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"21":{"start":{"line":115,"column":23},"end":{"line":122,"column":null}},"22":{"start":{"line":123,"column":4},"end":{"line":129,"column":null}},"23":{"start":{"line":131,"column":16},"end":{"line":131,"column":null}},"24":{"start":{"line":132,"column":27},"end":{"line":132,"column":null}},"25":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"26":{"start":{"line":133,"column":25},"end":{"line":133,"column":null}},"27":{"start":{"line":135,"column":26},"end":{"line":135,"column":null}},"28":{"start":{"line":136,"column":23},"end":{"line":143,"column":null}},"29":{"start":{"line":144,"column":4},"end":{"line":153,"column":null}},"30":{"start":{"line":162,"column":26},"end":{"line":162,"column":null}},"31":{"start":{"line":163,"column":38},"end":{"line":163,"column":null}},"32":{"start":{"line":165,"column":2},"end":{"line":222,"column":null}},"33":{"start":{"line":165,"column":15},"end":{"line":165,"column":18}},"34":{"start":{"line":166,"column":18},"end":{"line":166,"column":null}},"35":{"start":{"line":168,"column":25},"end":{"line":205,"column":null}},"36":{"start":{"line":170,"column":23},"end":{"line":170,"column":null}},"37":{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},"38":{"start":{"line":172,"column":10},"end":{"line":172,"column":null}},"39":{"start":{"line":173,"column":10},"end":{"line":173,"column":null}},"40":{"start":{"line":176,"column":8},"end":{"line":203,"column":null}},"41":{"start":{"line":177,"column":26},"end":{"line":177,"column":null}},"42":{"start":{"line":178,"column":30},"end":{"line":178,"column":null}},"43":{"start":{"line":179,"column":25},"end":{"line":181,"column":null}},"44":{"start":{"line":182,"column":24},"end":{"line":182,"column":null}},"45":{"start":{"line":184,"column":13},"end":{"line":188,"column":null}},"46":{"start":{"line":190,"column":10},"end":{"line":198,"column":null}},"47":{"start":{"line":200,"column":26},"end":{"line":200,"column":null}},"48":{"start":{"line":201,"column":10},"end":{"line":201,"column":null}},"49":{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},"50":{"start":{"line":207,"column":4},"end":{"line":217,"column":null}},"51":{"start":{"line":207,"column":19},"end":{"line":207,"column":22}},"52":{"start":{"line":208,"column":21},"end":{"line":208,"column":null}},"53":{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},"54":{"start":{"line":210,"column":8},"end":{"line":210,"column":null}},"55":{"start":{"line":212,"column":26},"end":{"line":212,"column":null}},"56":{"start":{"line":213,"column":28},"end":{"line":213,"column":null}},"57":{"start":{"line":214,"column":8},"end":{"line":214,"column":null}},"58":{"start":{"line":215,"column":8},"end":{"line":215,"column":null}},"59":{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},"60":{"start":{"line":220,"column":6},"end":{"line":220,"column":null}},"61":{"start":{"line":220,"column":43},"end":{"line":220,"column":67}},"62":{"start":{"line":224,"column":2},"end":{"line":224,"column":null}},"63":{"start":{"line":240,"column":2},"end":{"line":248,"column":null}},"64":{"start":{"line":241,"column":21},"end":{"line":243,"column":null}},"65":{"start":{"line":244,"column":4},"end":{"line":244,"column":null}},"66":{"start":{"line":246,"column":4},"end":{"line":246,"column":null}},"67":{"start":{"line":247,"column":4},"end":{"line":247,"column":null}},"68":{"start":{"line":261,"column":2},"end":{"line":261,"column":null}}},"fnMap":{"0":{"name":"searchDocuments","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":35,"column":22},"end":{"line":37,"column":null}},"line":35},"1":{"name":"searchDocumentsWithDiagnostics","decl":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"loc":{"start":{"line":42,"column":53},"end":{"line":73,"column":null}},"line":42},"2":{"name":"(anonymous_2)","decl":{"start":{"line":57,"column":20},"end":{"line":57,"column":25}},"loc":{"start":{"line":57,"column":31},"end":{"line":65,"column":3}},"line":57},"3":{"name":"fetchGovernmentDocuments","decl":{"start":{"line":75,"column":22},"end":{"line":75,"column":null}},"loc":{"start":{"line":78,"column":22},"end":{"line":84,"column":null}},"line":78},"4":{"name":"fetchDocumentDetails","decl":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"loc":{"start":{"line":90,"column":36},"end":{"line":96,"column":null}},"line":90},"5":{"name":"fetchDocumentDetailsWithCoverage","decl":{"start":{"line":98,"column":22},"end":{"line":98,"column":null}},"loc":{"start":{"line":106,"column":55},"end":{"line":155,"column":null}},"line":106},"6":{"name":"enrichDocumentsWithContent","decl":{"start":{"line":157,"column":22},"end":{"line":157,"column":null}},"loc":{"start":{"line":161,"column":30},"end":{"line":225,"column":null}},"line":161},"7":{"name":"(anonymous_7)","decl":{"start":{"line":169,"column":16},"end":{"line":169,"column":23}},"loc":{"start":{"line":169,"column":57},"end":{"line":204,"column":7}},"line":169},"8":{"name":"(anonymous_8)","decl":{"start":{"line":220,"column":16},"end":{"line":220,"column":31}},"loc":{"start":{"line":220,"column":43},"end":{"line":220,"column":67}},"line":220},"9":{"name":"fetchGovernmentDocumentContent","decl":{"start":{"line":236,"column":22},"end":{"line":236,"column":null}},"loc":{"start":{"line":239,"column":26},"end":{"line":249,"column":null}},"line":239},"10":{"name":"fetchExternalUrlContent","decl":{"start":{"line":257,"column":22},"end":{"line":257,"column":null}},"loc":{"start":{"line":260,"column":26},"end":{"line":262,"column":null}},"line":260}},"branchMap":{"0":{"loc":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":15},"end":{"line":47,"column":39}},{"start":{"line":47,"column":39},"end":{"line":47,"column":64}},{"start":{"line":47,"column":64},"end":{"line":47,"column":null}}],"line":47},"1":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":44},"end":{"line":49,"column":61}},{"start":{"line":49,"column":61},"end":{"line":49,"column":null}}],"line":49},"2":{"loc":{"start":{"line":83,"column":10},"end":{"line":83,"column":null}},"type":"binary-expr","locations":[{"start":{"line":83,"column":10},"end":{"line":83,"column":35}},{"start":{"line":83,"column":35},"end":{"line":83,"column":null}}],"line":83},"3":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"default-arg","locations":[{"start":{"line":89,"column":22},"end":{"line":89,"column":null}}],"line":89},"4":{"loc":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"type":"default-arg","locations":[{"start":{"line":101,"column":22},"end":{"line":101,"column":null}}],"line":101},"5":{"loc":{"start":{"line":102,"column":2},"end":{"line":105,"column":null}},"type":"default-arg","locations":[{"start":{"line":105,"column":6},"end":{"line":105,"column":null}}],"line":102},"6":{"loc":{"start":{"line":111,"column":21},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":21},"end":{"line":111,"column":46}},{"start":{"line":111,"column":46},"end":{"line":111,"column":null}}],"line":111},"7":{"loc":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"type":"cond-expr","locations":[{"start":{"line":114,"column":59},"end":{"line":114,"column":63}},{"start":{"line":114,"column":63},"end":{"line":114,"column":null}}],"line":114},"8":{"loc":{"start":{"line":121,"column":17},"end":{"line":121,"column":null}},"type":"binary-expr","locations":[{"start":{"line":121,"column":17},"end":{"line":121,"column":38}},{"start":{"line":121,"column":38},"end":{"line":121,"column":null}}],"line":121},"9":{"loc":{"start":{"line":132,"column":61},"end":{"line":132,"column":80}},"type":"binary-expr","locations":[{"start":{"line":132,"column":61},"end":{"line":132,"column":76}},{"start":{"line":132,"column":76},"end":{"line":132,"column":80}}],"line":132},"10":{"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},{"start":{},"end":{}}],"line":133},"11":{"loc":{"start":{"line":142,"column":17},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":17},"end":{"line":142,"column":38}},{"start":{"line":142,"column":38},"end":{"line":142,"column":null}}],"line":142},"12":{"loc":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}},"type":"default-arg","locations":[{"start":{"line":160,"column":16},"end":{"line":160,"column":null}}],"line":160},"13":{"loc":{"start":{"line":170,"column":23},"end":{"line":170,"column":null}},"type":"binary-expr","locations":[{"start":{"line":170,"column":23},"end":{"line":170,"column":43}},{"start":{"line":170,"column":43},"end":{"line":170,"column":57}},{"start":{"line":170,"column":57},"end":{"line":170,"column":null}}],"line":170},"14":{"loc":{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":171},"15":{"loc":{"start":{"line":178,"column":30},"end":{"line":178,"column":null}},"type":"binary-expr","locations":[{"start":{"line":178,"column":30},"end":{"line":178,"column":55}},{"start":{"line":178,"column":55},"end":{"line":178,"column":null}}],"line":178},"16":{"loc":{"start":{"line":179,"column":25},"end":{"line":181,"column":null}},"type":"cond-expr","locations":[{"start":{"line":180,"column":14},"end":{"line":180,"column":null}},{"start":{"line":181,"column":14},"end":{"line":181,"column":null}}],"line":179},"17":{"loc":{"start":{"line":181,"column":14},"end":{"line":181,"column":null}},"type":"binary-expr","locations":[{"start":{"line":181,"column":14},"end":{"line":181,"column":37}},{"start":{"line":181,"column":37},"end":{"line":181,"column":59}},{"start":{"line":181,"column":59},"end":{"line":181,"column":null}}],"line":181},"18":{"loc":{"start":{"line":182,"column":24},"end":{"line":182,"column":null}},"type":"binary-expr","locations":[{"start":{"line":182,"column":24},"end":{"line":182,"column":47}},{"start":{"line":182,"column":47},"end":{"line":182,"column":60}},{"start":{"line":182,"column":60},"end":{"line":182,"column":null}}],"line":182},"19":{"loc":{"start":{"line":184,"column":13},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":184,"column":13},"end":{"line":184,"column":null}},{"start":{"line":185,"column":12},"end":{"line":185,"column":null}},{"start":{"line":186,"column":13},"end":{"line":186,"column":null}},{"start":{"line":187,"column":12},"end":{"line":187,"column":null}},{"start":{"line":188,"column":12},"end":{"line":188,"column":null}}],"line":184},"20":{"loc":{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},"type":"if","locations":[{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},{"start":{"line":211,"column":13},"end":{"line":216,"column":null}}],"line":209},"21":{"loc":{"start":{"line":213,"column":28},"end":{"line":213,"column":null}},"type":"binary-expr","locations":[{"start":{"line":213,"column":28},"end":{"line":213,"column":54}},{"start":{"line":213,"column":54},"end":{"line":213,"column":74}},{"start":{"line":213,"column":74},"end":{"line":213,"column":90}},{"start":{"line":213,"column":90},"end":{"line":213,"column":null}}],"line":213},"22":{"loc":{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":219},"23":{"loc":{"start":{"line":244,"column":12},"end":{"line":244,"column":null}},"type":"binary-expr","locations":[{"start":{"line":244,"column":12},"end":{"line":244,"column":35}},{"start":{"line":244,"column":35},"end":{"line":244,"column":59}},{"start":{"line":244,"column":59},"end":{"line":244,"column":79}},{"start":{"line":244,"column":79},"end":{"line":244,"column":null}}],"line":244}},"s":{"0":13,"1":14,"2":14,"3":14,"4":14,"5":14,"6":14,"7":8,"8":8,"9":8,"10":8,"11":14,"12":6,"13":6,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0},"f":{"0":13,"1":14,"2":8,"3":6,"4":1,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[14,7,2],"1":[6,8],"2":[6,2],"3":[1],"4":[1],"5":[1],"6":[1,0],"7":[1,0],"8":[1,1],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0],"13":[0,0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0,0],"18":[0,0,0],"19":[0,0,0,0,0],"20":[0,0],"21":[0,0,0,0],"22":[0,0],"23":[0,0,0,0]},"meta":{"lastBranch":24,"lastFunction":11,"lastStatement":69,"seen":{"f:32:22:32:Infinity":0,"s:36:2:36:Infinity":0,"f:39:22:39:Infinity":1,"s:43:19:46:Infinity":1,"s:47:15:47:Infinity":2,"b:47:15:47:39:47:39:47:64:47:64:47:Infinity":0,"s:48:22:48:Infinity":3,"s:49:24:49:Infinity":4,"b:49:44:49:61:49:61:49:Infinity":1,"s:50:21:56:Infinity":5,"s:57:16:65:Infinity":6,"f:57:20:57:25":2,"s:58:22:58:Infinity":7,"s:59:24:59:Infinity":8,"s:60:26:63:Infinity":9,"s:64:4:64:Infinity":10,"s:66:2:72:Infinity":11,"f:75:22:75:Infinity":3,"s:79:19:82:Infinity":12,"s:83:2:83:Infinity":13,"b:83:10:83:35:83:35:83:Infinity":2,"f:86:22:86:Infinity":4,"b:89:22:89:Infinity":3,"s:91:19:94:Infinity":14,"s:95:2:95:Infinity":15,"f:98:22:98:Infinity":5,"b:101:22:101:Infinity":4,"b:105:6:105:Infinity":5,"s:107:16:107:Infinity":16,"s:108:2:154:Infinity":17,"s:109:21:109:Infinity":18,"s:110:26:113:Infinity":19,"b:111:21:111:46:111:46:111:Infinity":6,"s:114:24:114:Infinity":20,"b:114:59:114:63:114:63:114:Infinity":7,"s:115:23:122:Infinity":21,"b:121:17:121:38:121:38:121:Infinity":8,"s:123:4:129:Infinity":22,"s:131:16:131:Infinity":23,"s:132:27:132:Infinity":24,"b:132:61:132:76:132:76:132:80":9,"b:133:4:133:Infinity:undefined:undefined:undefined:undefined":10,"s:133:4:133:Infinity":25,"s:133:25:133:Infinity":26,"s:135:26:135:Infinity":27,"s:136:23:143:Infinity":28,"b:142:17:142:38:142:38:142:Infinity":11,"s:144:4:153:Infinity":29,"f:157:22:157:Infinity":6,"b:160:16:160:Infinity":12,"s:162:26:162:Infinity":30,"s:163:38:163:Infinity":31,"s:165:2:222:Infinity":32,"s:165:15:165:18":33,"s:166:18:166:Infinity":34,"s:168:25:205:Infinity":35,"f:169:16:169:23":7,"s:170:23:170:Infinity":36,"b:170:23:170:43:170:43:170:57:170:57:170:Infinity":13,"b:171:8:174:Infinity:undefined:undefined:undefined:undefined":14,"s:171:8:174:Infinity":37,"s:172:10:172:Infinity":38,"s:173:10:173:Infinity":39,"s:176:8:203:Infinity":40,"s:177:26:177:Infinity":41,"s:178:30:178:Infinity":42,"b:178:30:178:55:178:55:178:Infinity":15,"s:179:25:181:Infinity":43,"b:180:14:180:Infinity:181:14:181:Infinity":16,"b:181:14:181:37:181:37:181:59:181:59:181:Infinity":17,"s:182:24:182:Infinity":44,"b:182:24:182:47:182:47:182:60:182:60:182:Infinity":18,"s:184:13:188:Infinity":45,"b:184:13:184:Infinity:185:12:185:Infinity:186:13:186:Infinity:187:12:187:Infinity:188:12:188:Infinity":19,"s:190:10:198:Infinity":46,"s:200:26:200:Infinity":47,"s:201:10:201:Infinity":48,"s:202:10:202:Infinity":49,"s:207:4:217:Infinity":50,"s:207:19:207:22":51,"s:208:21:208:Infinity":52,"b:209:6:216:Infinity:211:13:216:Infinity":20,"s:209:6:216:Infinity":53,"s:210:8:210:Infinity":54,"s:212:26:212:Infinity":55,"s:213:28:213:Infinity":56,"b:213:28:213:54:213:54:213:74:213:74:213:90:213:90:213:Infinity":21,"s:214:8:214:Infinity":57,"s:215:8:215:Infinity":58,"b:219:4:221:Infinity:undefined:undefined:undefined:undefined":22,"s:219:4:221:Infinity":59,"s:220:6:220:Infinity":60,"f:220:16:220:31":8,"s:220:43:220:67":61,"s:224:2:224:Infinity":62,"f:236:22:236:Infinity":9,"s:240:2:248:Infinity":63,"s:241:21:243:Infinity":64,"s:244:4:244:Infinity":65,"b:244:12:244:35:244:35:244:59:244:59:244:79:244:79:244:Infinity":23,"s:246:4:246:Infinity":66,"s:247:4:247:Infinity":67,"f:257:22:257:Infinity":10,"s:261:2:261:Infinity":68}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/members.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/members.ts","statementMap":{"0":{"start":{"line":16,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"fetchMPs","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":15,"column":22},"end":{"line":21,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"type":"default-arg","locations":[{"start":{"line":14,"column":29},"end":{"line":14,"column":null}}],"line":14},"1":{"loc":{"start":{"line":20,"column":10},"end":{"line":20,"column":null}},"type":"binary-expr","locations":[{"start":{"line":20,"column":10},"end":{"line":20,"column":29}},{"start":{"line":20,"column":29},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":9,"1":9},"f":{"0":9},"b":{"0":[9],"1":[9,2]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":2,"seen":{"f:12:22:12:Infinity":0,"b:14:29:14:Infinity":0,"s:16:19:19:Infinity":0,"s:20:2:20:Infinity":1,"b:20:10:20:29:20:29:20:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/reports.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/reports.ts","statementMap":{"0":{"start":{"line":18,"column":42},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"2":{"start":{"line":19,"column":10},"end":{"line":19,"column":null}},"3":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"4":{"start":{"line":20,"column":13},"end":{"line":20,"column":null}},"5":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"6":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"7":{"start":{"line":31,"column":42},"end":{"line":31,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"9":{"start":{"line":32,"column":10},"end":{"line":32,"column":null}},"10":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"11":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"12":{"start":{"line":43,"column":42},"end":{"line":43,"column":null}},"13":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"14":{"start":{"line":44,"column":10},"end":{"line":44,"column":null}},"15":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"16":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"17":{"start":{"line":54,"column":45},"end":{"line":54,"column":null}},"18":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"19":{"start":{"line":55,"column":17},"end":{"line":55,"column":null}},"20":{"start":{"line":56,"column":19},"end":{"line":56,"column":null}},"21":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"22":{"start":{"line":64,"column":45},"end":{"line":64,"column":null}},"23":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"24":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"25":{"start":{"line":66,"column":19},"end":{"line":66,"column":null}},"26":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}}},"fnMap":{"0":{"name":"fetchCommitteeReports","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":17,"column":22},"end":{"line":24,"column":null}},"line":17},"1":{"name":"fetchPropositions","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":null}},"loc":{"start":{"line":30,"column":22},"end":{"line":36,"column":null}},"line":30},"2":{"name":"fetchMotions","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":22},"end":{"line":48,"column":null}},"line":42},"3":{"name":"fetchWrittenQuestions","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":null}},"loc":{"start":{"line":53,"column":22},"end":{"line":58,"column":null}},"line":53},"4":{"name":"fetchInterpellations","decl":{"start":{"line":60,"column":22},"end":{"line":60,"column":null}},"loc":{"start":{"line":63,"column":22},"end":{"line":68,"column":null}},"line":63}},"branchMap":{"0":{"loc":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"type":"default-arg","locations":[{"start":{"line":14,"column":10},"end":{"line":14,"column":null}}],"line":14},"1":{"loc":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"type":"default-arg","locations":[{"start":{"line":15,"column":22},"end":{"line":15,"column":null}}],"line":15},"2":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"default-arg","locations":[{"start":{"line":16,"column":25},"end":{"line":16,"column":null}}],"line":16},"3":{"loc":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},{"start":{},"end":{}}],"line":19},"4":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"5":{"loc":{"start":{"line":23,"column":10},"end":{"line":23,"column":null}},"type":"binary-expr","locations":[{"start":{"line":23,"column":10},"end":{"line":23,"column":34}},{"start":{"line":23,"column":34},"end":{"line":23,"column":57}},{"start":{"line":23,"column":57},"end":{"line":23,"column":null}}],"line":23},"6":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":10},"end":{"line":28,"column":null}}],"line":28},"7":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"default-arg","locations":[{"start":{"line":29,"column":22},"end":{"line":29,"column":null}}],"line":29},"8":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"9":{"loc":{"start":{"line":35,"column":10},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":10},"end":{"line":35,"column":34}},{"start":{"line":35,"column":34},"end":{"line":35,"column":62}},{"start":{"line":35,"column":62},"end":{"line":35,"column":null}}],"line":35},"10":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"default-arg","locations":[{"start":{"line":40,"column":10},"end":{"line":40,"column":null}}],"line":40},"11":{"loc":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"type":"default-arg","locations":[{"start":{"line":41,"column":22},"end":{"line":41,"column":null}}],"line":41},"12":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"13":{"loc":{"start":{"line":47,"column":10},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":10},"end":{"line":47,"column":34}},{"start":{"line":47,"column":34},"end":{"line":47,"column":57}},{"start":{"line":47,"column":57},"end":{"line":47,"column":null}}],"line":47},"14":{"loc":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"type":"default-arg","locations":[{"start":{"line":52,"column":44},"end":{"line":52,"column":null}}],"line":52},"15":{"loc":{"start":{"line":54,"column":54},"end":{"line":54,"column":73}},"type":"binary-expr","locations":[{"start":{"line":54,"column":54},"end":{"line":54,"column":70}},{"start":{"line":54,"column":70},"end":{"line":54,"column":73}}],"line":54},"16":{"loc":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"17":{"loc":{"start":{"line":57,"column":10},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":34}},{"start":{"line":57,"column":34},"end":{"line":57,"column":59}},{"start":{"line":57,"column":59},"end":{"line":57,"column":null}}],"line":57},"18":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"default-arg","locations":[{"start":{"line":62,"column":44},"end":{"line":62,"column":null}}],"line":62},"19":{"loc":{"start":{"line":64,"column":54},"end":{"line":64,"column":73}},"type":"binary-expr","locations":[{"start":{"line":64,"column":54},"end":{"line":64,"column":70}},{"start":{"line":64,"column":70},"end":{"line":64,"column":73}}],"line":64},"20":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"21":{"loc":{"start":{"line":67,"column":10},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":10},"end":{"line":67,"column":34}},{"start":{"line":67,"column":34},"end":{"line":67,"column":65}},{"start":{"line":67,"column":65},"end":{"line":67,"column":null}}],"line":67}},"s":{"0":5,"1":5,"2":2,"3":5,"4":1,"5":5,"6":5,"7":7,"8":7,"9":2,"10":7,"11":7,"12":6,"13":6,"14":2,"15":6,"16":6,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1},"f":{"0":5,"1":7,"2":6,"3":1,"4":1},"b":{"0":[5],"1":[5],"2":[5],"3":[2,3],"4":[1,4],"5":[5,5,2],"6":[7],"7":[7],"8":[2,5],"9":[7,7,2],"10":[6],"11":[6],"12":[2,4],"13":[6,6,2],"14":[1],"15":[1,0],"16":[1,0],"17":[1,1,1],"18":[1],"19":[1,0],"20":[1,0],"21":[1,1,1]},"meta":{"lastBranch":22,"lastFunction":5,"lastStatement":27,"seen":{"f:12:22:12:Infinity":0,"b:14:10:14:Infinity":0,"b:15:22:15:Infinity":1,"b:16:25:16:Infinity":2,"s:18:42:18:Infinity":0,"b:19:2:19:Infinity:undefined:undefined:undefined:undefined":3,"s:19:2:19:Infinity":1,"s:19:10:19:Infinity":2,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":4,"s:20:2:20:Infinity":3,"s:20:13:20:Infinity":4,"s:22:19:22:Infinity":5,"s:23:2:23:Infinity":6,"b:23:10:23:34:23:34:23:57:23:57:23:Infinity":5,"f:26:22:26:Infinity":1,"b:28:10:28:Infinity":6,"b:29:22:29:Infinity":7,"s:31:42:31:Infinity":7,"b:32:2:32:Infinity:undefined:undefined:undefined:undefined":8,"s:32:2:32:Infinity":8,"s:32:10:32:Infinity":9,"s:34:19:34:Infinity":10,"s:35:2:35:Infinity":11,"b:35:10:35:34:35:34:35:62:35:62:35:Infinity":9,"f:38:22:38:Infinity":2,"b:40:10:40:Infinity":10,"b:41:22:41:Infinity":11,"s:43:42:43:Infinity":12,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":12,"s:44:2:44:Infinity":13,"s:44:10:44:Infinity":14,"s:46:19:46:Infinity":15,"s:47:2:47:Infinity":16,"b:47:10:47:34:47:34:47:57:47:57:47:Infinity":13,"f:50:22:50:Infinity":3,"b:52:44:52:Infinity":14,"s:54:45:54:Infinity":17,"b:54:54:54:70:54:70:54:73":15,"b:55:2:55:Infinity:undefined:undefined:undefined:undefined":16,"s:55:2:55:Infinity":18,"s:55:17:55:Infinity":19,"s:56:19:56:Infinity":20,"s:57:2:57:Infinity":21,"b:57:10:57:34:57:34:57:59:57:59:57:Infinity":17,"f:60:22:60:Infinity":4,"b:62:44:62:Infinity":18,"s:64:45:64:Infinity":22,"b:64:54:64:70:64:70:64:73":19,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":20,"s:65:2:65:Infinity":23,"s:65:17:65:Infinity":24,"s:66:19:66:Infinity":25,"s:67:2:67:Infinity":26,"b:67:10:67:34:67:34:67:65:67:65:67:Infinity":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/speeches.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/speeches.ts","statementMap":{"0":{"start":{"line":16,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"searchSpeeches","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":15,"column":22},"end":{"line":21,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":10},"end":{"line":20,"column":null}},"type":"binary-expr","locations":[{"start":{"line":20,"column":10},"end":{"line":20,"column":36}},{"start":{"line":20,"column":36},"end":{"line":20,"column":60}},{"start":{"line":20,"column":60},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":8,"1":8},"f":{"0":8},"b":{"0":[8,8,3]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":2,"seen":{"f:12:22:12:Infinity":0,"s:16:19:19:Infinity":0,"s:20:2:20:Infinity":1,"b:20:10:20:36:20:36:20:60:20:60:20:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/votes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/votes.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":31,"column":19},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":8},"end":{"line":36,"column":null}},"3":{"start":{"line":36,"column":20},"end":{"line":36,"column":32}},"4":{"start":{"line":37,"column":22},"end":{"line":37,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},"6":{"start":{"line":41,"column":25},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},"8":{"start":{"line":43,"column":6},"end":{"line":66,"column":null}},"9":{"start":{"line":44,"column":35},"end":{"line":47,"column":null}},"10":{"start":{"line":48,"column":14},"end":{"line":50,"column":null}},"11":{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},"12":{"start":{"line":52,"column":10},"end":{"line":62,"column":null}},"13":{"start":{"line":70,"column":24},"end":{"line":70,"column":null}},"14":{"start":{"line":71,"column":36},"end":{"line":78,"column":null}},"15":{"start":{"line":80,"column":2},"end":{"line":87,"column":null}},"16":{"start":{"line":81,"column":31},"end":{"line":81,"column":71}},"17":{"start":{"line":94,"column":19},"end":{"line":97,"column":null}},"18":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"fetchVotingRecords","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":23,"column":22},"end":{"line":25,"column":null}},"line":23},"1":{"name":"fetchVotingRecordsWithDiagnostics","decl":{"start":{"line":27,"column":22},"end":{"line":27,"column":null}},"loc":{"start":{"line":30,"column":88},"end":{"line":88,"column":null}},"line":30},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":10}},"loc":{"start":{"line":36,"column":20},"end":{"line":36,"column":32}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":81,"column":17},"end":{"line":81,"column":22}},"loc":{"start":{"line":81,"column":31},"end":{"line":81,"column":71}},"line":81},"4":{"name":"fetchVotingGroup","decl":{"start":{"line":90,"column":22},"end":{"line":90,"column":null}},"loc":{"start":{"line":93,"column":22},"end":{"line":99,"column":null}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":67}},"type":"binary-expr","locations":[{"start":{"line":35,"column":18},"end":{"line":35,"column":39}},{"start":{"line":35,"column":39},"end":{"line":35,"column":65}},{"start":{"line":35,"column":65},"end":{"line":35,"column":67}}],"line":35},"1":{"loc":{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":40},"2":{"loc":{"start":{"line":40,"column":6},"end":{"line":40,"column":59}},"type":"binary-expr","locations":[{"start":{"line":40,"column":6},"end":{"line":40,"column":27}},{"start":{"line":40,"column":27},"end":{"line":40,"column":59}}],"line":40},"3":{"loc":{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":42},"4":{"loc":{"start":{"line":49,"column":11},"end":{"line":49,"column":80}},"type":"binary-expr","locations":[{"start":{"line":49,"column":11},"end":{"line":49,"column":42}},{"start":{"line":49,"column":42},"end":{"line":49,"column":78}},{"start":{"line":49,"column":78},"end":{"line":49,"column":80}}],"line":49},"5":{"loc":{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":51},"6":{"loc":{"start":{"line":70,"column":24},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":44},"end":{"line":70,"column":61}},{"start":{"line":70,"column":61},"end":{"line":70,"column":null}}],"line":70},"7":{"loc":{"start":{"line":77,"column":13},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":22},"end":{"line":77,"column":33}},{"start":{"line":77,"column":33},"end":{"line":77,"column":null}}],"line":77},"8":{"loc":{"start":{"line":86,"column":8},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":17},"end":{"line":86,"column":30}},{"start":{"line":86,"column":30},"end":{"line":86,"column":null}}],"line":86},"9":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"default-arg","locations":[{"start":{"line":92,"column":36},"end":{"line":92,"column":null}}],"line":92},"10":{"loc":{"start":{"line":98,"column":10},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":10},"end":{"line":98,"column":32}},{"start":{"line":98,"column":32},"end":{"line":98,"column":53}},{"start":{"line":98,"column":53},"end":{"line":98,"column":null}}],"line":98}},"s":{"0":6,"1":8,"2":8,"3":3,"4":8,"5":8,"6":5,"7":5,"8":5,"9":5,"10":5,"11":5,"12":1,"13":8,"14":8,"15":8,"16":3,"17":3,"18":3},"f":{"0":6,"1":8,"2":3,"3":3,"4":3},"b":{"0":[8,2,2],"1":[5,3],"2":[8,5],"3":[5,0],"4":[5,2,2],"5":[1,4],"6":[5,3],"7":[1,7],"8":[1,7],"9":[3],"10":[3,1,1]},"meta":{"lastBranch":11,"lastFunction":5,"lastStatement":19,"seen":{"f:20:22:20:Infinity":0,"s:24:2:24:Infinity":0,"f:27:22:27:Infinity":1,"s:31:19:34:Infinity":1,"s:35:8:36:Infinity":2,"b:35:18:35:39:35:39:35:65:35:65:35:67":0,"f:36:5:36:10":2,"s:36:20:36:32":3,"s:37:22:37:Infinity":4,"b:40:2:68:Infinity:undefined:undefined:undefined:undefined":1,"s:40:2:68:Infinity":5,"b:40:6:40:27:40:27:40:59":2,"s:41:25:41:Infinity":6,"b:42:4:67:Infinity:undefined:undefined:undefined:undefined":3,"s:42:4:67:Infinity":7,"s:43:6:66:Infinity":8,"s:44:35:47:Infinity":9,"s:48:14:50:Infinity":10,"b:49:11:49:42:49:42:49:78:49:78:49:80":4,"b:51:8:63:Infinity:undefined:undefined:undefined:undefined":5,"s:51:8:63:Infinity":11,"s:52:10:62:Infinity":12,"s:70:24:70:Infinity":13,"b:70:44:70:61:70:61:70:Infinity":6,"s:71:36:78:Infinity":14,"b:77:22:77:33:77:33:77:Infinity":7,"s:80:2:87:Infinity":15,"f:81:17:81:22":3,"s:81:31:81:71":16,"b:86:17:86:30:86:30:86:Infinity":8,"f:90:22:90:Infinity":4,"b:92:36:92:Infinity":9,"s:94:19:97:Infinity":17,"s:98:2:98:Infinity":18,"b:98:10:98:32:98:32:98:53:98:53:98:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/riksmote/helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/riksmote/helpers.ts","statementMap":{"0":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"2":{"start":{"line":16,"column":14},"end":{"line":16,"column":null}},"3":{"start":{"line":17,"column":20},"end":{"line":17,"column":null}},"4":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"5":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"6":{"start":{"line":19,"column":64},"end":{"line":19,"column":null}},"7":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"previousRiksmote","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":33}},"loc":{"start":{"line":14,"column":60},"end":{"line":21,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"if","locations":[{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},{"start":{},"end":{}}],"line":16},"1":{"loc":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},{"start":{},"end":{}}],"line":19},"2":{"loc":{"start":{"line":19,"column":6},"end":{"line":19,"column":64}},"type":"binary-expr","locations":[{"start":{"line":19,"column":6},"end":{"line":19,"column":37}},{"start":{"line":19,"column":37},"end":{"line":19,"column":64}}],"line":19}},"s":{"0":5,"1":5,"2":0,"3":5,"4":5,"5":5,"6":0,"7":5},"f":{"0":5},"b":{"0":[0,5],"1":[0,5],"2":[5,5]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":8,"seen":{"f:14:16:14:33":0,"s:15:16:15:Infinity":0,"b:16:2:16:Infinity:undefined:undefined:undefined:undefined":0,"s:16:2:16:Infinity":1,"s:16:14:16:Infinity":2,"s:17:20:17:Infinity":3,"s:18:18:18:Infinity":4,"b:19:2:19:Infinity:undefined:undefined:undefined:undefined":1,"s:19:2:19:Infinity":5,"b:19:6:19:37:19:37:19:64":2,"s:19:64:19:Infinity":6,"s:20:2:20:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/jsonrpc.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/jsonrpc.ts","statementMap":{"0":{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},"1":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"2":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"3":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"4":{"start":{"line":60,"column":6},"end":{"line":60,"column":null}},"5":{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},"6":{"start":{"line":63,"column":6},"end":{"line":63,"column":null}},"7":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"9":{"start":{"line":66,"column":6},"end":{"line":66,"column":null}},"10":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"14":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"15":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"16":{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},"17":{"start":{"line":93,"column":6},"end":{"line":93,"column":null}},"18":{"start":{"line":96,"column":23},"end":{"line":96,"column":null}},"19":{"start":{"line":97,"column":22},"end":{"line":97,"column":null}},"20":{"start":{"line":97,"column":39},"end":{"line":97,"column":59}},"21":{"start":{"line":99,"column":4},"end":{"line":161,"column":null}},"22":{"start":{"line":100,"column":29},"end":{"line":100,"column":null}},"23":{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},"24":{"start":{"line":103,"column":8},"end":{"line":107,"column":null}},"25":{"start":{"line":104,"column":10},"end":{"line":104,"column":null}},"26":{"start":{"line":110,"column":22},"end":{"line":110,"column":null}},"27":{"start":{"line":112,"column":23},"end":{"line":117,"column":null}},"28":{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},"29":{"start":{"line":120,"column":24},"end":{"line":120,"column":null}},"30":{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},"31":{"start":{"line":121,"column":14},"end":{"line":121,"column":49}},"32":{"start":{"line":122,"column":8},"end":{"line":124,"column":null}},"33":{"start":{"line":127,"column":47},"end":{"line":127,"column":null}},"34":{"start":{"line":128,"column":27},"end":{"line":128,"column":null}},"35":{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},"36":{"start":{"line":131,"column":8},"end":{"line":131,"column":null}},"37":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"38":{"start":{"line":133,"column":8},"end":{"line":133,"column":null}},"39":{"start":{"line":134,"column":8},"end":{"line":134,"column":null}},"40":{"start":{"line":135,"column":8},"end":{"line":135,"column":null}},"41":{"start":{"line":136,"column":8},"end":{"line":136,"column":null}},"42":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"43":{"start":{"line":139,"column":8},"end":{"line":139,"column":null}},"44":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"45":{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},"46":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"47":{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},"48":{"start":{"line":148,"column":22},"end":{"line":148,"column":null}},"49":{"start":{"line":149,"column":8},"end":{"line":151,"column":null}},"50":{"start":{"line":152,"column":8},"end":{"line":152,"column":null}},"51":{"start":{"line":153,"column":8},"end":{"line":153,"column":null}},"52":{"start":{"line":154,"column":8},"end":{"line":154,"column":null}},"53":{"start":{"line":157,"column":6},"end":{"line":157,"column":null}},"54":{"start":{"line":158,"column":6},"end":{"line":158,"column":null}},"55":{"start":{"line":160,"column":6},"end":{"line":160,"column":null}},"56":{"start":{"line":169,"column":4},"end":{"line":169,"column":null}},"57":{"start":{"line":169,"column":36},"end":{"line":169,"column":59}},"58":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"59":{"start":{"line":177,"column":4},"end":{"line":177,"column":null}},"60":{"start":{"line":185,"column":4},"end":{"line":192,"column":null}},"61":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"62":{"start":{"line":197,"column":4},"end":{"line":197,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":55,"column":2},"end":{"line":55,"column":14}},"loc":{"start":{"line":55,"column":53},"end":{"line":73,"column":null}},"line":55},"1":{"name":"(anonymous_1)","decl":{"start":{"line":76,"column":2},"end":{"line":76,"column":26}},"loc":{"start":{"line":76,"column":26},"end":{"line":78,"column":null}},"line":76},"2":{"name":"(anonymous_2)","decl":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"loc":{"start":{"line":89,"column":38},"end":{"line":162,"column":null}},"line":89},"3":{"name":"(anonymous_3)","decl":{"start":{"line":97,"column":22},"end":{"line":97,"column":39}},"loc":{"start":{"line":97,"column":39},"end":{"line":97,"column":59}},"line":97},"4":{"name":"(anonymous_4)","decl":{"start":{"line":168,"column":8},"end":{"line":168,"column":14}},"loc":{"start":{"line":168,"column":41},"end":{"line":170,"column":null}},"line":168},"5":{"name":"(anonymous_5)","decl":{"start":{"line":169,"column":15},"end":{"line":169,"column":24}},"loc":{"start":{"line":169,"column":36},"end":{"line":169,"column":59}},"line":169},"6":{"name":"(anonymous_6)","decl":{"start":{"line":172,"column":2},"end":{"line":172,"column":19}},"loc":{"start":{"line":172,"column":50},"end":{"line":174,"column":null}},"line":172},"7":{"name":"(anonymous_7)","decl":{"start":{"line":176,"column":8},"end":{"line":176,"column":43}},"loc":{"start":{"line":176,"column":43},"end":{"line":178,"column":null}},"line":176},"8":{"name":"(anonymous_8)","decl":{"start":{"line":184,"column":2},"end":{"line":184,"column":23}},"loc":{"start":{"line":184,"column":23},"end":{"line":193,"column":null}},"line":184},"9":{"name":"(anonymous_9)","decl":{"start":{"line":195,"column":2},"end":{"line":195,"column":21}},"loc":{"start":{"line":195,"column":21},"end":{"line":198,"column":null}},"line":195}},"branchMap":{"0":{"loc":{"start":{"line":55,"column":14},"end":{"line":55,"column":53}},"type":"default-arg","locations":[{"start":{"line":55,"column":49},"end":{"line":55,"column":53}}],"line":55},"1":{"loc":{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},{"start":{"line":62,"column":11},"end":{"line":68,"column":null}}],"line":56},"2":{"loc":{"start":{"line":63,"column":21},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":21},"end":{"line":63,"column":39}},{"start":{"line":63,"column":39},"end":{"line":63,"column":59}},{"start":{"line":63,"column":59},"end":{"line":63,"column":null}}],"line":63},"3":{"loc":{"start":{"line":64,"column":21},"end":{"line":64,"column":57}},"type":"binary-expr","locations":[{"start":{"line":64,"column":21},"end":{"line":64,"column":39}},{"start":{"line":64,"column":39},"end":{"line":64,"column":57}}],"line":64},"4":{"loc":{"start":{"line":65,"column":24},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":24},"end":{"line":65,"column":45}},{"start":{"line":65,"column":45},"end":{"line":65,"column":null}}],"line":65},"5":{"loc":{"start":{"line":66,"column":27},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":27},"end":{"line":66,"column":45}},{"start":{"line":66,"column":45},"end":{"line":66,"column":null}}],"line":66},"6":{"loc":{"start":{"line":67,"column":23},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":23},"end":{"line":67,"column":43}},{"start":{"line":67,"column":43},"end":{"line":67,"column":null}}],"line":67},"7":{"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"type":"default-arg","locations":[{"start":{"line":86,"column":38},"end":{"line":86,"column":null}}],"line":86},"8":{"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"type":"default-arg","locations":[{"start":{"line":87,"column":17},"end":{"line":87,"column":null}}],"line":87},"9":{"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"type":"default-arg","locations":[{"start":{"line":88,"column":18},"end":{"line":88,"column":null}}],"line":88},"10":{"loc":{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":92},"11":{"loc":{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":102},"12":{"loc":{"start":{"line":102,"column":10},"end":{"line":102,"column":45}},"type":"binary-expr","locations":[{"start":{"line":102,"column":10},"end":{"line":102,"column":28}},{"start":{"line":102,"column":28},"end":{"line":102,"column":45}}],"line":102},"13":{"loc":{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":119},"14":{"loc":{"start":{"line":123,"column":72},"end":{"line":123,"column":null}},"type":"cond-expr","locations":[{"start":{"line":123,"column":84},"end":{"line":123,"column":104}},{"start":{"line":123,"column":104},"end":{"line":123,"column":null}}],"line":123},"15":{"loc":{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":130},"16":{"loc":{"start":{"line":130,"column":10},"end":{"line":130,"column":66}},"type":"binary-expr","locations":[{"start":{"line":130,"column":10},"end":{"line":130,"column":50}},{"start":{"line":130,"column":50},"end":{"line":130,"column":66}}],"line":130},"17":{"loc":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":138},"18":{"loc":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":22},"end":{"line":142,"column":48}},{"start":{"line":142,"column":48},"end":{"line":142,"column":null}}],"line":142},"19":{"loc":{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},"type":"if","locations":[{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},{"start":{},"end":{}}],"line":147},"20":{"loc":{"start":{"line":147,"column":10},"end":{"line":147,"column":76}},"type":"binary-expr","locations":[{"start":{"line":147,"column":10},"end":{"line":147,"column":46}},{"start":{"line":147,"column":46},"end":{"line":147,"column":76}}],"line":147},"21":{"loc":{"start":{"line":189,"column":8},"end":{"line":191,"column":null}},"type":"cond-expr","locations":[{"start":{"line":190,"column":12},"end":{"line":190,"column":null}},{"start":{"line":191,"column":12},"end":{"line":191,"column":null}}],"line":189}},"s":{"0":133,"1":2,"2":2,"3":2,"4":2,"5":2,"6":131,"7":131,"8":131,"9":131,"10":131,"11":133,"12":133,"13":133,"14":1,"15":133,"16":133,"17":115,"18":125,"19":125,"20":0,"21":125,"22":125,"23":125,"24":1,"25":1,"26":125,"27":125,"28":111,"29":4,"30":4,"31":4,"32":4,"33":107,"34":107,"35":107,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":107,"43":3,"44":104,"45":133,"46":21,"47":21,"48":10,"49":10,"50":10,"51":10,"52":10,"53":11,"54":11,"55":125,"56":1,"57":1,"58":0,"59":1,"60":15,"61":3,"62":3},"f":{"0":133,"1":1,"2":133,"3":0,"4":1,"5":1,"6":0,"7":1,"8":15,"9":3},"b":{"0":[133],"1":[2,131],"2":[131,125,124],"3":[131,130],"4":[131,130],"5":[131,128],"6":[131,130],"7":[133],"8":[133],"9":[133],"10":[115,18],"11":[1,124],"12":[125,1],"13":[4,107],"14":[1,3],"15":[0,107],"16":[107,0],"17":[3,104],"18":[104,12],"19":[10,11],"20":[21,19],"21":[8,7]},"meta":{"lastBranch":22,"lastFunction":10,"lastStatement":63,"seen":{"f:55:2:55:14":0,"b:55:49:55:53":0,"b:56:4:68:Infinity:62:11:68:Infinity":1,"s:56:4:68:Infinity":0,"s:57:6:57:Infinity":1,"s:58:6:58:Infinity":2,"s:59:6:59:Infinity":3,"s:60:6:60:Infinity":4,"s:61:6:61:Infinity":5,"s:63:6:63:Infinity":6,"b:63:21:63:39:63:39:63:59:63:59:63:Infinity":2,"s:64:6:64:Infinity":7,"b:64:21:64:39:64:39:64:57":3,"s:65:6:65:Infinity":8,"b:65:24:65:45:65:45:65:Infinity":4,"s:66:6:66:Infinity":9,"b:66:27:66:45:66:45:66:Infinity":5,"s:67:6:67:Infinity":10,"b:67:23:67:43:67:43:67:Infinity":6,"s:70:4:70:Infinity":11,"s:71:4:71:Infinity":12,"s:72:4:72:Infinity":13,"f:76:2:76:26":1,"s:77:4:77:Infinity":14,"f:84:8:84:Infinity":2,"b:86:38:86:Infinity":7,"b:87:17:87:Infinity":8,"b:88:18:88:Infinity":9,"s:90:4:90:Infinity":15,"b:92:4:94:Infinity:undefined:undefined:undefined:undefined":10,"s:92:4:94:Infinity":16,"s:93:6:93:Infinity":17,"s:96:23:96:Infinity":18,"s:97:22:97:Infinity":19,"f:97:22:97:39":3,"s:97:39:97:59":20,"s:99:4:161:Infinity":21,"s:100:29:100:Infinity":22,"b:102:6:108:Infinity:undefined:undefined:undefined:undefined":11,"s:102:6:108:Infinity":23,"b:102:10:102:28:102:28:102:45":12,"s:103:8:107:Infinity":24,"s:104:10:104:Infinity":25,"s:110:22:110:Infinity":26,"s:112:23:117:Infinity":27,"b:119:6:125:Infinity:undefined:undefined:undefined:undefined":13,"s:119:6:125:Infinity":28,"s:120:24:120:Infinity":29,"s:121:8:121:Infinity":30,"s:121:14:121:49":31,"s:122:8:124:Infinity":32,"b:123:84:123:104:123:104:123:Infinity":14,"s:127:47:127:Infinity":33,"s:128:27:128:Infinity":34,"b:130:6:137:Infinity:undefined:undefined:undefined:undefined":15,"s:130:6:137:Infinity":35,"b:130:10:130:50:130:50:130:66":16,"s:131:8:131:Infinity":36,"s:132:14:132:Infinity":37,"s:133:8:133:Infinity":38,"s:134:8:134:Infinity":39,"s:135:8:135:Infinity":40,"s:136:8:136:Infinity":41,"b:138:6:140:Infinity:undefined:undefined:undefined:undefined":17,"s:138:6:140:Infinity":42,"s:139:8:139:Infinity":43,"s:142:22:142:Infinity":44,"b:142:22:142:48:142:48:142:Infinity":18,"s:143:6:143:Infinity":45,"s:145:18:145:Infinity":46,"b:147:6:155:Infinity:undefined:undefined:undefined:undefined":19,"s:147:6:155:Infinity":47,"b:147:10:147:46:147:46:147:76":20,"s:148:22:148:Infinity":48,"s:149:8:151:Infinity":49,"s:152:8:152:Infinity":50,"s:153:8:153:Infinity":51,"s:154:8:154:Infinity":52,"s:157:6:157:Infinity":53,"s:158:6:158:Infinity":54,"s:160:6:160:Infinity":55,"f:168:8:168:14":4,"s:169:4:169:Infinity":56,"f:169:15:169:24":5,"s:169:36:169:59":57,"f:172:2:172:19":6,"s:173:4:173:Infinity":58,"f:176:8:176:43":7,"s:177:4:177:Infinity":59,"f:184:2:184:23":8,"s:185:4:192:Infinity":60,"b:190:12:190:Infinity:191:12:191:Infinity":21,"f:195:2:195:21":9,"s:196:4:196:Infinity":61,"s:197:4:197:Infinity":62}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/error-envelope.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/error-envelope.ts","statementMap":{"0":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"1":{"start":{"line":40,"column":23},"end":{"line":40,"column":null}},"2":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"6":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"8":{"start":{"line":61,"column":16},"end":{"line":61,"column":null}},"9":{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},"10":{"start":{"line":64,"column":4},"end":{"line":67,"column":null}},"11":{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},"12":{"start":{"line":74,"column":4},"end":{"line":75,"column":null}},"13":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}}},"fnMap":{"0":{"name":"classifyJsonRpcError","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":37}},"loc":{"start":{"line":39,"column":85},"end":{"line":50,"column":null}},"line":39},"1":{"name":"formatRequestFailure","decl":{"start":{"line":59,"column":16},"end":{"line":59,"column":37}},"loc":{"start":{"line":59,"column":74},"end":{"line":81,"column":null}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"1":{"loc":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":19},"end":{"line":42,"column":45}},{"start":{"line":42,"column":45},"end":{"line":42,"column":null}}],"line":42},"2":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":51}},{"start":{"line":44,"column":51},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"4":{"loc":{"start":{"line":60,"column":20},"end":{"line":60,"column":37}},"type":"binary-expr","locations":[{"start":{"line":60,"column":20},"end":{"line":60,"column":35}},{"start":{"line":60,"column":35},"end":{"line":60,"column":37}}],"line":60},"5":{"loc":{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},{"start":{"line":69,"column":9},"end":{"line":79,"column":null}}],"line":63},"6":{"loc":{"start":{"line":63,"column":6},"end":{"line":63,"column":65}},"type":"binary-expr","locations":[{"start":{"line":63,"column":6},"end":{"line":63,"column":35}},{"start":{"line":63,"column":35},"end":{"line":63,"column":65}}],"line":63},"7":{"loc":{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":69},"8":{"loc":{"start":{"line":70,"column":4},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},{"start":{"line":72,"column":4},"end":{"line":72,"column":null}}],"line":70}},"s":{"0":107,"1":104,"2":3,"3":107,"4":107,"5":0,"6":3,"7":11,"8":11,"9":11,"10":0,"11":11,"12":2,"13":11},"f":{"0":107,"1":11},"b":{"0":[104,3],"1":[3,0],"2":[107,3],"3":[0,107],"4":[11,0],"5":[0,11],"6":[11,11],"7":[2,9],"8":[11,9,9]},"meta":{"lastBranch":9,"lastFunction":2,"lastStatement":14,"seen":{"f:39:16:39:37":0,"b:40:2:40:Infinity:undefined:undefined:undefined:undefined":0,"s:40:2:40:Infinity":0,"s:40:23:40:Infinity":1,"s:42:19:42:Infinity":2,"b:42:19:42:45:42:45:42:Infinity":1,"s:44:4:44:Infinity":3,"b:44:4:44:51:44:51:44:Infinity":2,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":3,"s:46:2:48:Infinity":4,"s:47:4:47:Infinity":5,"s:49:2:49:Infinity":6,"f:59:16:59:37":1,"s:60:8:60:Infinity":7,"b:60:20:60:35:60:35:60:37":4,"s:61:16:61:Infinity":8,"b:63:2:79:Infinity:69:9:79:Infinity":5,"s:63:2:79:Infinity":9,"b:63:6:63:35:63:35:63:65":6,"s:64:4:67:Infinity":10,"b:69:9:79:Infinity:undefined:undefined:undefined:undefined":7,"s:69:9:79:Infinity":11,"b:70:4:70:Infinity:71:4:71:Infinity:72:4:72:Infinity":8,"s:74:4:75:Infinity":12,"s:80:2:80:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/request-builder.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/request-builder.ts","statementMap":{"0":{"start":{"line":18,"column":16},"end":{"line":18,"column":null}},"1":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":35,"column":null}},"5":{"start":{"line":45,"column":2},"end":{"line":50,"column":null}},"6":{"start":{"line":63,"column":42},"end":{"line":67,"column":null}},"7":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"8":{"start":{"line":68,"column":17},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"10":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"nextJsonRpcId","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":40}},"loc":{"start":{"line":21,"column":40},"end":{"line":23,"column":null}},"line":21},"1":{"name":"_resetJsonRpcIdForTests","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":40}},"loc":{"start":{"line":26,"column":57},"end":{"line":28,"column":null}},"line":26},"2":{"name":"assertValidToolName","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":36}},"loc":{"start":{"line":31,"column":56},"end":{"line":37,"column":null}},"line":31},"3":{"name":"buildJsonRpcRequest","decl":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"loc":{"start":{"line":44,"column":18},"end":{"line":51,"column":null}},"line":44},"4":{"name":"buildRequestHeaders","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":null}},"loc":{"start":{"line":62,"column":26},"end":{"line":71,"column":null}},"line":62}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":40},"end":{"line":26,"column":57}},"type":"default-arg","locations":[{"start":{"line":26,"column":48},"end":{"line":26,"column":57}}],"line":26},"1":{"loc":{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":32},"2":{"loc":{"start":{"line":32,"column":6},"end":{"line":32,"column":75}},"type":"binary-expr","locations":[{"start":{"line":32,"column":6},"end":{"line":32,"column":15}},{"start":{"line":32,"column":15},"end":{"line":32,"column":43}},{"start":{"line":32,"column":43},"end":{"line":32,"column":75}}],"line":32},"3":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"default-arg","locations":[{"start":{"line":43,"column":15},"end":{"line":43,"column":null}}],"line":43},"4":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"5":{"loc":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":69}},"s":{"0":32,"1":126,"2":0,"3":133,"4":8,"5":125,"6":125,"7":125,"8":1,"9":125,"10":0,"11":125},"f":{"0":126,"1":0,"2":133,"3":125,"4":125},"b":{"0":[0],"1":[8,125],"2":[133,130,129],"3":[125],"4":[1,124],"5":[0,125]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":12,"seen":{"s:18:16:18:Infinity":0,"f:21:16:21:40":0,"s:22:2:22:Infinity":1,"f:26:16:26:40":1,"b:26:48:26:57":0,"s:27:2:27:Infinity":2,"f:31:16:31:36":2,"b:32:2:36:Infinity:undefined:undefined:undefined:undefined":1,"s:32:2:36:Infinity":3,"b:32:6:32:15:32:15:32:43:32:43:32:75":2,"s:33:4:35:Infinity":4,"f:40:16:40:Infinity":3,"b:43:15:43:Infinity":3,"s:45:2:50:Infinity":5,"f:58:16:58:Infinity":4,"s:63:42:67:Infinity":6,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":4,"s:68:2:68:Infinity":7,"s:68:17:68:Infinity":8,"b:69:2:69:Infinity:undefined:undefined:undefined:undefined":5,"s:69:2:69:Infinity":9,"s:69:17:69:Infinity":10,"s:70:2:70:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/response-parser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/response-parser.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":35,"column":22},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},"3":{"start":{"line":37,"column":17},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"7":{"start":{"line":66,"column":59},"end":{"line":66,"column":null}},"8":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},"9":{"start":{"line":67,"column":30},"end":{"line":67,"column":null}},"10":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"11":{"start":{"line":68,"column":48},"end":{"line":68,"column":null}},"12":{"start":{"line":70,"column":34},"end":{"line":74,"column":null}},"13":{"start":{"line":75,"column":19},"end":{"line":75,"column":null}},"14":{"start":{"line":76,"column":23},"end":{"line":76,"column":null}},"15":{"start":{"line":77,"column":24},"end":{"line":80,"column":null}},"16":{"start":{"line":78,"column":24},"end":{"line":78,"column":null}},"17":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"18":{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},"19":{"start":{"line":82,"column":4},"end":{"line":84,"column":null}},"20":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"21":{"start":{"line":88,"column":2},"end":{"line":95,"column":null}},"22":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"23":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"24":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"25":{"start":{"line":109,"column":18},"end":{"line":109,"column":null}},"26":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"27":{"start":{"line":110,"column":52},"end":{"line":110,"column":null}},"28":{"start":{"line":112,"column":2},"end":{"line":130,"column":null}},"29":{"start":{"line":113,"column":19},"end":{"line":113,"column":null}},"30":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"31":{"start":{"line":114,"column":32},"end":{"line":114,"column":null}},"32":{"start":{"line":116,"column":23},"end":{"line":116,"column":null}},"33":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"34":{"start":{"line":117,"column":21},"end":{"line":117,"column":null}},"35":{"start":{"line":119,"column":27},"end":{"line":119,"column":null}},"36":{"start":{"line":120,"column":24},"end":{"line":120,"column":null}},"37":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"38":{"start":{"line":121,"column":22},"end":{"line":121,"column":null}},"39":{"start":{"line":123,"column":4},"end":{"line":127,"column":null}},"40":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"41":{"start":{"line":126,"column":6},"end":{"line":126,"column":null}},"42":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}}},"fnMap":{"0":{"name":"getResponseContentType","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":39}},"loc":{"start":{"line":20,"column":11},"end":{"line":24,"column":null}},"line":20},"1":{"name":"parseJsonRpcEnvelope","decl":{"start":{"line":30,"column":22},"end":{"line":30,"column":43}},"loc":{"start":{"line":34,"column":29},"end":{"line":41,"column":null}},"line":34},"2":{"name":"readGatewayPayload","decl":{"start":{"line":63,"column":22},"end":{"line":63,"column":null}},"loc":{"start":{"line":65,"column":43},"end":{"line":96,"column":null}},"line":65},"3":{"name":"(anonymous_3)","decl":{"start":{"line":77,"column":37},"end":{"line":77,"column":43}},"loc":{"start":{"line":77,"column":52},"end":{"line":80,"column":3}},"line":77},"4":{"name":"resolveResultContent","decl":{"start":{"line":106,"column":22},"end":{"line":106,"column":null}},"loc":{"start":{"line":108,"column":36},"end":{"line":131,"column":null}},"line":108}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":9},"end":{"line":23,"column":null}},"type":"cond-expr","locations":[{"start":{"line":22,"column":7},"end":{"line":22,"column":null}},{"start":{"line":23,"column":6},"end":{"line":23,"column":null}}],"line":21},"1":{"loc":{"start":{"line":21,"column":9},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":9},"end":{"line":21,"column":29}},{"start":{"line":21,"column":29},"end":{"line":21,"column":null}}],"line":21},"2":{"loc":{"start":{"line":22,"column":7},"end":{"line":22,"column":null}},"type":"binary-expr","locations":[{"start":{"line":22,"column":7},"end":{"line":22,"column":47}},{"start":{"line":22,"column":47},"end":{"line":22,"column":null}}],"line":22},"3":{"loc":{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":36},"4":{"loc":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":66},"5":{"loc":{"start":{"line":66,"column":6},"end":{"line":66,"column":59}},"type":"binary-expr","locations":[{"start":{"line":66,"column":6},"end":{"line":66,"column":37}},{"start":{"line":66,"column":37},"end":{"line":66,"column":59}}],"line":66},"6":{"loc":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"7":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"8":{"loc":{"start":{"line":78,"column":24},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":53},"end":{"line":78,"column":60}},{"start":{"line":78,"column":60},"end":{"line":78,"column":null}}],"line":78},"9":{"loc":{"start":{"line":79,"column":11},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":11},"end":{"line":79,"column":32}},{"start":{"line":79,"column":32},"end":{"line":79,"column":null}}],"line":79},"10":{"loc":{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":81},"11":{"loc":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},{"start":{},"end":{}}],"line":110},"12":{"loc":{"start":{"line":110,"column":6},"end":{"line":110,"column":52}},"type":"binary-expr","locations":[{"start":{"line":110,"column":6},"end":{"line":110,"column":33}},{"start":{"line":110,"column":33},"end":{"line":110,"column":52}}],"line":110},"13":{"loc":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"14":{"loc":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":117},"15":{"loc":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":121}},"s":{"0":107,"1":107,"2":107,"3":0,"4":0,"5":107,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":104,"26":104,"27":103,"28":1,"29":1,"30":1,"31":1,"32":0,"33":0,"34":0,"35":0,"36":0,"37":104,"38":0,"39":0,"40":0,"41":0,"42":0},"f":{"0":107,"1":107,"2":0,"3":0,"4":104},"b":{"0":[107,0],"1":[107,107],"2":[107,95],"3":[0,107],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[103,1],"12":[104,1],"13":[1,0],"14":[0,0],"15":[0,104]},"meta":{"lastBranch":16,"lastFunction":5,"lastStatement":43,"seen":{"f:18:16:18:39":0,"s:21:2:23:Infinity":0,"b:22:7:22:Infinity:23:6:23:Infinity":0,"b:21:9:21:29:21:29:21:Infinity":1,"b:22:7:22:47:22:47:22:Infinity":2,"f:30:22:30:43":1,"s:35:22:35:Infinity":1,"b:36:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:36:2:39:Infinity":2,"s:37:17:37:Infinity":3,"s:38:4:38:Infinity":4,"s:40:2:40:Infinity":5,"f:63:22:63:Infinity":2,"b:66:2:66:Infinity:undefined:undefined:undefined:undefined":4,"s:66:2:66:Infinity":6,"b:66:6:66:37:66:37:66:59":5,"s:66:59:66:Infinity":7,"b:67:2:67:Infinity:undefined:undefined:undefined:undefined":6,"s:67:2:67:Infinity":8,"s:67:30:67:Infinity":9,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":7,"s:68:2:68:Infinity":10,"s:68:48:68:Infinity":11,"s:70:34:74:Infinity":12,"s:75:19:75:Infinity":13,"s:76:23:76:Infinity":14,"s:77:24:80:Infinity":15,"f:77:37:77:43":3,"s:78:24:78:Infinity":16,"b:78:53:78:60:78:60:78:Infinity":8,"s:79:4:79:Infinity":17,"b:79:11:79:32:79:32:79:Infinity":9,"b:81:2:86:Infinity:undefined:undefined:undefined:undefined":10,"s:81:2:86:Infinity":18,"s:82:4:84:Infinity":19,"s:85:4:85:Infinity":20,"s:88:2:95:Infinity":21,"s:89:4:89:Infinity":22,"s:91:4:93:Infinity":23,"s:94:4:94:Infinity":24,"f:106:22:106:Infinity":4,"s:109:18:109:Infinity":25,"b:110:2:110:Infinity:undefined:undefined:undefined:undefined":11,"s:110:2:110:Infinity":26,"b:110:6:110:33:110:33:110:52":12,"s:110:52:110:Infinity":27,"s:112:2:130:Infinity":28,"s:113:19:113:Infinity":29,"b:114:4:114:Infinity:undefined:undefined:undefined:undefined":13,"s:114:4:114:Infinity":30,"s:114:32:114:Infinity":31,"s:116:23:116:Infinity":32,"b:117:4:117:Infinity:undefined:undefined:undefined:undefined":14,"s:117:4:117:Infinity":33,"s:117:21:117:Infinity":34,"s:119:27:119:Infinity":35,"s:120:24:120:Infinity":36,"b:121:4:121:Infinity:undefined:undefined:undefined:undefined":15,"s:121:4:121:Infinity":37,"s:121:22:121:Infinity":38,"s:123:4:127:Infinity":39,"s:124:6:124:Infinity":40,"s:126:6:126:Infinity":41,"s:129:4:129:Infinity":42}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/session.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/session.ts","statementMap":{"0":{"start":{"line":21,"column":16},"end":{"line":21,"column":null}},"1":{"start":{"line":22,"column":2},"end":{"line":26,"column":null}},"2":{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},"3":{"start":{"line":24,"column":6},"end":{"line":24,"column":null}},"4":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"5":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"6":{"start":{"line":47,"column":39},"end":{"line":47,"column":null}},"7":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":50,"column":37},"end":{"line":50,"column":57}},"10":{"start":{"line":52,"column":2},"end":{"line":104,"column":null}},"11":{"start":{"line":53,"column":44},"end":{"line":57,"column":null}},"12":{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},"13":{"start":{"line":58,"column":23},"end":{"line":58,"column":null}},"14":{"start":{"line":60,"column":21},"end":{"line":74,"column":null}},"15":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"16":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"17":{"start":{"line":81,"column":6},"end":{"line":83,"column":null}},"18":{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},"19":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"20":{"start":{"line":87,"column":6},"end":{"line":87,"column":null}},"21":{"start":{"line":90,"column":4},"end":{"line":101,"column":null}},"22":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}}},"fnMap":{"0":{"name":"parseSSEResponse","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":33}},"loc":{"start":{"line":20,"column":64},"end":{"line":28,"column":null}},"line":20},"1":{"name":"initializeSession","decl":{"start":{"line":46,"column":22},"end":{"line":46,"column":40}},"loc":{"start":{"line":46,"column":80},"end":{"line":105,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":50,"column":20},"end":{"line":50,"column":37}},"loc":{"start":{"line":50,"column":37},"end":{"line":50,"column":57}},"line":50}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":23},"1":{"loc":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":47,"column":6},"end":{"line":47,"column":39}},"type":"binary-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":39}}],"line":47},"3":{"loc":{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"4":{"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76},"5":{"loc":{"start":{"line":81,"column":6},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":82,"column":10},"end":{"line":82,"column":null}},{"start":{"line":83,"column":10},"end":{"line":83,"column":null}}],"line":81},"6":{"loc":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":6},"end":{"line":81,"column":26}},{"start":{"line":81,"column":26},"end":{"line":81,"column":null}}],"line":81},"7":{"loc":{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":85},"8":{"loc":{"start":{"line":94,"column":12},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":28},"end":{"line":94,"column":66}},{"start":{"line":94,"column":66},"end":{"line":94,"column":null}}],"line":94}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":1,"8":1,"9":0,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":0,"17":1,"18":1,"19":0,"20":0,"21":1,"22":1},"f":{"0":0,"1":1,"2":0},"b":{"0":[0,0],"1":[0,1],"2":[1,1],"3":[1,0],"4":[0,1],"5":[1,0],"6":[1,1],"7":[0,1],"8":[0,1]},"meta":{"lastBranch":9,"lastFunction":3,"lastStatement":23,"seen":{"f:20:16:20:33":0,"s:21:16:21:Infinity":0,"s:22:2:26:Infinity":1,"b:23:4:25:Infinity:undefined:undefined:undefined:undefined":0,"s:23:4:25:Infinity":2,"s:24:6:24:Infinity":3,"s:27:2:27:Infinity":4,"f:46:22:46:40":1,"b:47:2:47:Infinity:undefined:undefined:undefined:undefined":1,"s:47:2:47:Infinity":5,"b:47:6:47:23:47:23:47:39":2,"s:47:39:47:Infinity":6,"s:49:21:49:Infinity":7,"s:50:20:50:Infinity":8,"f:50:20:50:37":2,"s:50:37:50:57":9,"s:52:2:104:Infinity":10,"s:53:44:57:Infinity":11,"b:58:4:58:Infinity:undefined:undefined:undefined:undefined":3,"s:58:4:58:Infinity":12,"s:58:23:58:Infinity":13,"s:60:21:74:Infinity":14,"b:76:4:78:Infinity:undefined:undefined:undefined:undefined":4,"s:76:4:78:Infinity":15,"s:77:6:77:Infinity":16,"s:81:6:83:Infinity":17,"b:82:10:82:Infinity:83:10:83:Infinity":5,"b:81:6:81:26:81:26:81:Infinity":6,"b:85:4:88:Infinity:undefined:undefined:undefined:undefined":7,"s:85:4:88:Infinity":18,"s:86:6:86:Infinity":19,"s:87:6:87:Infinity":20,"s:90:4:101:Infinity":21,"b:94:28:94:66:94:66:94:Infinity":8,"s:103:4:103:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/retry.ts","statementMap":{"0":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"1":{"start":{"line":40,"column":8},"end":{"line":40,"column":null}},"2":{"start":{"line":41,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"calculateRetryDelay","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":36}},"loc":{"start":{"line":25,"column":64},"end":{"line":27,"column":null}},"line":25},"1":{"name":"isRetryableNetworkError","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":40}},"loc":{"start":{"line":39,"column":61},"end":{"line":48,"column":null}},"line":39}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":20},"end":{"line":40,"column":37}},"type":"binary-expr","locations":[{"start":{"line":40,"column":20},"end":{"line":40,"column":35}},{"start":{"line":40,"column":35},"end":{"line":40,"column":37}}],"line":40},"1":{"loc":{"start":{"line":42,"column":4},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}}],"line":42}},"s":{"0":16,"1":28,"2":28},"f":{"0":16,"1":28},"b":{"0":[28,0],"1":[28,27,16,14,13]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":3,"seen":{"f:25:16:25:36":0,"s:26:2:26:Infinity":0,"f:39:16:39:40":1,"s:40:8:40:Infinity":1,"b:40:20:40:35:40:35:40:37":0,"s:41:2:46:Infinity":2,"b:42:4:42:Infinity:43:4:43:Infinity:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/timeout.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/timeout.ts","statementMap":{"0":{"start":{"line":13,"column":45},"end":{"line":13,"column":null}},"1":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"2":{"start":{"line":26,"column":18},"end":{"line":26,"column":null}},"3":{"start":{"line":26,"column":35},"end":{"line":26,"column":55}},"4":{"start":{"line":27,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":28,"column":21},"end":{"line":31,"column":null}},"6":{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"8":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"9":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"11":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"12":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"fetchExternalUrlText","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":24,"column":26},"end":{"line":45,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":26,"column":18},"end":{"line":26,"column":35}},"loc":{"start":{"line":26,"column":35},"end":{"line":26,"column":55}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"default-arg","locations":[{"start":{"line":23,"column":22},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":32}},"s":{"0":34,"1":7,"2":7,"3":2,"4":7,"5":7,"6":4,"7":1,"8":1,"9":3,"10":4,"11":4,"12":7},"f":{"0":7,"1":2},"b":{"0":[7],"1":[1,3]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":13,"seen":{"s:13:45:13:Infinity":0,"f:21:22:21:Infinity":0,"b:23:22:23:Infinity":0,"s:25:21:25:Infinity":1,"s:26:18:26:Infinity":2,"f:26:18:26:35":1,"s:26:35:26:55":3,"s:27:2:44:Infinity":4,"s:28:21:31:Infinity":5,"b:32:4:35:Infinity:undefined:undefined:undefined:undefined":1,"s:32:4:35:Infinity":6,"s:33:6:33:Infinity":7,"s:34:6:34:Infinity":8,"s:38:4:38:Infinity":9,"s:40:4:40:Infinity":10,"s:41:4:41:Infinity":11,"s:43:4:43:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/full-text-threshold.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/full-text-threshold.ts","statementMap":{"0":{"start":{"line":7,"column":36},"end":{"line":7,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":34},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:7:36:7:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/optimize-images.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/optimize-images.ts","statementMap":{"0":{"start":{"line":1,"column":9},"end":{"line":1,"column":null}},"1":{"start":{"line":1,"column":22},"end":{"line":1,"column":null}},"2":{"start":{"line":7,"column":17},"end":{"line":7,"column":null}},"3":{"start":{"line":8,"column":17},"end":{"line":8,"column":null}},"4":{"start":{"line":30,"column":61},"end":{"line":73,"column":null}},"5":{"start":{"line":76,"column":19},"end":{"line":76,"column":null}},"6":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"7":{"start":{"line":81,"column":2},"end":{"line":88,"column":null}},"8":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"9":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"10":{"start":{"line":87,"column":6},"end":{"line":87,"column":null}},"11":{"start":{"line":92,"column":16},"end":{"line":92,"column":null}},"12":{"start":{"line":93,"column":17},"end":{"line":93,"column":null}},"13":{"start":{"line":94,"column":19},"end":{"line":96,"column":null}},"14":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}},"15":{"start":{"line":101,"column":16},"end":{"line":101,"column":null}},"16":{"start":{"line":102,"column":17},"end":{"line":102,"column":null}},"17":{"start":{"line":103,"column":19},"end":{"line":111,"column":null}},"18":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"19":{"start":{"line":116,"column":2},"end":{"line":116,"column":null}},"20":{"start":{"line":117,"column":2},"end":{"line":131,"column":null}},"21":{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},"22":{"start":{"line":119,"column":6},"end":{"line":123,"column":null}},"23":{"start":{"line":120,"column":8},"end":{"line":122,"column":null}},"24":{"start":{"line":121,"column":10},"end":{"line":121,"column":null}},"25":{"start":{"line":125,"column":6},"end":{"line":129,"column":null}},"26":{"start":{"line":126,"column":8},"end":{"line":128,"column":null}},"27":{"start":{"line":127,"column":10},"end":{"line":127,"column":null}},"28":{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},"29":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"30":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}}},"fnMap":{"0":{"name":"variantName","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":28}},"loc":{"start":{"line":75,"column":89},"end":{"line":78,"column":null}},"line":75},"1":{"name":"encode","decl":{"start":{"line":80,"column":15},"end":{"line":80,"column":22}},"loc":{"start":{"line":80,"column":75},"end":{"line":89,"column":null}},"line":80},"2":{"name":"writeWidthVariant","decl":{"start":{"line":91,"column":15},"end":{"line":91,"column":33}},"loc":{"start":{"line":91,"column":108},"end":{"line":98,"column":null}},"line":91},"3":{"name":"writeSquareVariant","decl":{"start":{"line":100,"column":15},"end":{"line":100,"column":34}},"loc":{"start":{"line":100,"column":109},"end":{"line":113,"column":null}},"line":100},"4":{"name":"optimizeImages","decl":{"start":{"line":115,"column":22},"end":{"line":115,"column":54}},"loc":{"start":{"line":115,"column":54},"end":{"line":132,"column":null}},"line":115}},"branchMap":{"0":{"loc":{"start":{"line":81,"column":2},"end":{"line":88,"column":null}},"type":"switch","locations":[{"start":{"line":82,"column":4},"end":{"line":83,"column":null}},{"start":{"line":84,"column":4},"end":{"line":85,"column":null}},{"start":{"line":86,"column":4},"end":{"line":87,"column":null}}],"line":81},"1":{"loc":{"start":{"line":95,"column":26},"end":{"line":95,"column":47}},"type":"binary-expr","locations":[{"start":{"line":95,"column":26},"end":{"line":95,"column":37}},{"start":{"line":95,"column":37},"end":{"line":95,"column":47}}],"line":95},"2":{"loc":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"type":"binary-expr","locations":[{"start":{"line":108,"column":18},"end":{"line":108,"column":36}},{"start":{"line":108,"column":36},"end":{"line":108,"column":null}}],"line":108},"3":{"loc":{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},{"start":{"line":124,"column":11},"end":{"line":130,"column":null}}],"line":118},"4":{"loc":{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":134},"5":{"loc":{"start":{"line":134,"column":4},"end":{"line":134,"column":80}},"type":"binary-expr","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":23}},{"start":{"line":134,"column":23},"end":{"line":134,"column":80}}],"line":134}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":44,"6":44,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":1,"29":0,"30":0},"f":{"0":44,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0,0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,1],"5":[1,1]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":31,"seen":{"s:1:9:1:Infinity":0,"s:1:22:1:Infinity":1,"s:7:17:7:Infinity":2,"s:8:17:8:Infinity":3,"s:30:61:73:Infinity":4,"f:75:16:75:28":0,"s:76:19:76:Infinity":5,"s:77:2:77:Infinity":6,"f:80:15:80:22":1,"b:82:4:83:Infinity:84:4:85:Infinity:86:4:87:Infinity":0,"s:81:2:88:Infinity":7,"s:83:6:83:Infinity":8,"s:85:6:85:Infinity":9,"s:87:6:87:Infinity":10,"f:91:15:91:33":2,"s:92:16:92:Infinity":11,"s:93:17:93:Infinity":12,"s:94:19:96:Infinity":13,"b:95:26:95:37:95:37:95:47":1,"s:97:2:97:Infinity":14,"f:100:15:100:34":3,"s:101:16:101:Infinity":15,"s:102:17:102:Infinity":16,"s:103:19:111:Infinity":17,"b:108:18:108:36:108:36:108:Infinity":2,"s:112:2:112:Infinity":18,"f:115:22:115:54":4,"s:116:2:116:Infinity":19,"s:117:2:131:Infinity":20,"b:118:4:130:Infinity:124:11:130:Infinity":3,"s:118:4:130:Infinity":21,"s:119:6:123:Infinity":22,"s:120:8:122:Infinity":23,"s:121:10:121:Infinity":24,"s:125:6:129:Infinity":25,"s:126:8:128:Infinity":26,"s:127:10:127:Infinity":27,"b:134:0:137:Infinity:undefined:undefined:undefined:undefined":4,"s:134:0:137:Infinity":28,"b:134:4:134:23:134:23:134:80":5,"s:135:2:135:Infinity":29,"s:136:2:136:Infinity":30}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/index.ts","statementMap":{"0":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"1":{"start":{"line":60,"column":14},"end":{"line":60,"column":null}},"2":{"start":{"line":61,"column":16},"end":{"line":61,"column":null}},"3":{"start":{"line":62,"column":42},"end":{"line":62,"column":null}},"4":{"start":{"line":63,"column":69},"end":{"line":63,"column":null}},"5":{"start":{"line":64,"column":56},"end":{"line":64,"column":null}},"6":{"start":{"line":65,"column":53},"end":{"line":65,"column":null}},"7":{"start":{"line":66,"column":29},"end":{"line":66,"column":null}},"8":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"10":{"start":{"line":70,"column":17},"end":{"line":70,"column":null}},"11":{"start":{"line":71,"column":16},"end":{"line":71,"column":null}},"12":{"start":{"line":73,"column":2},"end":{"line":105,"column":null}},"13":{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},"14":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"15":{"start":{"line":76,"column":6},"end":{"line":76,"column":null}},"16":{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},"17":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"18":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"19":{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},"20":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"21":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"22":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"23":{"start":{"line":90,"column":6},"end":{"line":92,"column":null}},"24":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"25":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"26":{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},"27":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"28":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"29":{"start":{"line":98,"column":28},"end":{"line":98,"column":null}},"30":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"31":{"start":{"line":99,"column":30},"end":{"line":99,"column":null}},"32":{"start":{"line":100,"column":6},"end":{"line":100,"column":null}},"33":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"34":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"35":{"start":{"line":107,"column":42},"end":{"line":111,"column":null}},"36":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"37":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"38":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"39":{"start":{"line":122,"column":2},"end":{"line":131,"column":null}}},"fnMap":{"0":{"name":"drainMcpRetryQueue","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":null}},"loc":{"start":{"line":58,"column":32},"end":{"line":132,"column":null}},"line":58}},"branchMap":{"0":{"loc":{"start":{"line":52,"column":2},"end":{"line":57,"column":null}},"type":"default-arg","locations":[{"start":{"line":57,"column":6},"end":{"line":57,"column":null}}],"line":52},"1":{"loc":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"type":"binary-expr","locations":[{"start":{"line":59,"column":20},"end":{"line":59,"column":41}},{"start":{"line":59,"column":41},"end":{"line":59,"column":null}}],"line":59},"2":{"loc":{"start":{"line":60,"column":14},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":14},"end":{"line":60,"column":29}},{"start":{"line":60,"column":29},"end":{"line":60,"column":null}}],"line":60},"3":{"loc":{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":74},"4":{"loc":{"start":{"line":74,"column":8},"end":{"line":74,"column":79}},"type":"binary-expr","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":27}},{"start":{"line":74,"column":27},"end":{"line":74,"column":44}},{"start":{"line":74,"column":44},"end":{"line":74,"column":79}}],"line":74},"5":{"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":78},"6":{"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":82},"7":{"loc":{"start":{"line":82,"column":8},"end":{"line":82,"column":63}},"type":"binary-expr","locations":[{"start":{"line":82,"column":8},"end":{"line":82,"column":30}},{"start":{"line":82,"column":30},"end":{"line":82,"column":63}}],"line":82},"8":{"loc":{"start":{"line":90,"column":6},"end":{"line":92,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":10},"end":{"line":91,"column":null}},{"start":{"line":92,"column":10},"end":{"line":92,"column":null}}],"line":90},"9":{"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":94},"10":{"loc":{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},{"start":{},"end":{}}],"line":96},"11":{"loc":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":98},"12":{"loc":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":99},"13":{"loc":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"type":"binary-expr","locations":[{"start":{"line":117,"column":18},"end":{"line":117,"column":44}},{"start":{"line":117,"column":44},"end":{"line":117,"column":61}},{"start":{"line":117,"column":61},"end":{"line":117,"column":76}},{"start":{"line":117,"column":76},"end":{"line":117,"column":null}}],"line":117},"14":{"loc":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":118}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":3,"13":3,"14":0,"15":0,"16":3,"17":0,"18":0,"19":3,"20":0,"21":0,"22":3,"23":3,"24":0,"25":0,"26":3,"27":2,"28":2,"29":2,"30":2,"31":0,"32":2,"33":1,"34":1,"35":3,"36":3,"37":3,"38":2,"39":3},"f":{"0":3},"b":{"0":[3],"1":[3,0],"2":[3,3],"3":[0,3],"4":[3,0,0],"5":[0,3],"6":[0,3],"7":[3,0],"8":[3,0],"9":[3,-3],"10":[2,1],"11":[2,0],"12":[0,2],"13":[3,1,1,1],"14":[2,1]},"meta":{"lastBranch":15,"lastFunction":1,"lastStatement":40,"seen":{"f:50:22:50:Infinity":0,"b:57:6:57:Infinity":0,"s:59:20:59:Infinity":0,"b:59:20:59:41:59:41:59:Infinity":1,"s:60:14:60:Infinity":1,"b:60:14:60:29:60:29:60:Infinity":2,"s:61:16:61:Infinity":2,"s:62:42:62:Infinity":3,"s:63:69:63:Infinity":4,"s:64:56:64:Infinity":5,"s:65:53:65:Infinity":6,"s:66:29:66:Infinity":7,"s:68:18:68:Infinity":8,"s:69:17:69:Infinity":9,"s:70:17:70:Infinity":10,"s:71:16:71:Infinity":11,"s:73:2:105:Infinity":12,"b:74:4:77:Infinity:undefined:undefined:undefined:undefined":3,"s:74:4:77:Infinity":13,"b:74:8:74:27:74:27:74:44:74:44:74:79":4,"s:75:6:75:Infinity":14,"s:76:6:76:Infinity":15,"b:78:4:81:Infinity:undefined:undefined:undefined:undefined":5,"s:78:4:81:Infinity":16,"s:79:6:79:Infinity":17,"s:80:6:80:Infinity":18,"b:82:4:85:Infinity:undefined:undefined:undefined:undefined":6,"s:82:4:85:Infinity":19,"b:82:8:82:30:82:30:82:63":7,"s:83:6:83:Infinity":20,"s:84:6:84:Infinity":21,"s:87:4:87:Infinity":22,"s:90:6:92:Infinity":23,"b:91:10:91:Infinity:92:10:92:Infinity":8,"b:94:4:94:Infinity:undefined:undefined:undefined:undefined":9,"s:94:4:94:Infinity":24,"s:94:28:94:Infinity":25,"b:96:4:101:Infinity:undefined:undefined:undefined:undefined":10,"s:96:4:101:Infinity":26,"s:97:6:97:Infinity":27,"b:98:6:98:Infinity:undefined:undefined:undefined:undefined":11,"s:98:6:98:Infinity":28,"s:98:28:98:Infinity":29,"b:99:6:99:Infinity:undefined:undefined:undefined:undefined":12,"s:99:6:99:Infinity":30,"s:99:30:99:Infinity":31,"s:100:6:100:Infinity":32,"s:103:4:103:Infinity":33,"s:104:4:104:Infinity":34,"s:107:42:111:Infinity":35,"s:117:18:117:Infinity":36,"b:117:18:117:44:117:44:117:61:117:61:117:76:117:76:117:Infinity":13,"b:118:2:120:Infinity:undefined:undefined:undefined:undefined":14,"s:118:2:120:Infinity":37,"s:119:4:119:Infinity":38,"s:122:2:131:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/classifier.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/classifier.ts","statementMap":{"0":{"start":{"line":43,"column":24},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":2},"end":{"line":111,"column":null}},"2":{"start":{"line":45,"column":19},"end":{"line":52,"column":null}},"3":{"start":{"line":54,"column":52},"end":{"line":61,"column":null}},"4":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"5":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"6":{"start":{"line":67,"column":4},"end":{"line":77,"column":null}},"7":{"start":{"line":79,"column":23},"end":{"line":79,"column":null}},"8":{"start":{"line":80,"column":4},"end":{"line":83,"column":null}},"9":{"start":{"line":84,"column":4},"end":{"line":110,"column":null}},"10":{"start":{"line":119,"column":24},"end":{"line":119,"column":null}},"11":{"start":{"line":120,"column":23},"end":{"line":120,"column":null}},"12":{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},"13":{"start":{"line":122,"column":4},"end":{"line":131,"column":null}},"14":{"start":{"line":134,"column":2},"end":{"line":203,"column":null}},"15":{"start":{"line":135,"column":25},"end":{"line":137,"column":null}},"16":{"start":{"line":139,"column":52},"end":{"line":147,"column":null}},"17":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"18":{"start":{"line":150,"column":6},"end":{"line":156,"column":null}},"19":{"start":{"line":159,"column":4},"end":{"line":169,"column":null}},"20":{"start":{"line":171,"column":23},"end":{"line":171,"column":null}},"21":{"start":{"line":172,"column":4},"end":{"line":175,"column":null}},"22":{"start":{"line":176,"column":4},"end":{"line":202,"column":null}}},"fnMap":{"0":{"name":"drainDocumentFulltextEntry","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":25},"end":{"line":112,"column":null}},"line":42},"1":{"name":"drainVoteringarSearchEntry","decl":{"start":{"line":114,"column":22},"end":{"line":114,"column":null}},"loc":{"start":{"line":118,"column":25},"end":{"line":204,"column":null}},"line":118}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":24},"end":{"line":49,"column":80}},{"start":{"line":49,"column":80},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":16},"end":{"line":74,"column":32}},{"start":{"line":74,"column":32},"end":{"line":74,"column":null}}],"line":74},"3":{"loc":{"start":{"line":79,"column":23},"end":{"line":79,"column":null}},"type":"cond-expr","locations":[{"start":{"line":79,"column":51},"end":{"line":79,"column":70}},{"start":{"line":79,"column":70},"end":{"line":79,"column":null}}],"line":79},"4":{"loc":{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":121},"5":{"loc":{"start":{"line":121,"column":6},"end":{"line":121,"column":65}},"type":"binary-expr","locations":[{"start":{"line":121,"column":6},"end":{"line":121,"column":42}},{"start":{"line":121,"column":42},"end":{"line":121,"column":65}}],"line":121},"6":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":32},"end":{"line":146,"column":66}},{"start":{"line":146,"column":66},"end":{"line":146,"column":null}}],"line":146},"7":{"loc":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},{"start":{},"end":{}}],"line":149},"8":{"loc":{"start":{"line":153,"column":20},"end":{"line":155,"column":null}},"type":"cond-expr","locations":[{"start":{"line":154,"column":13},"end":{"line":154,"column":null}},{"start":{"line":155,"column":12},"end":{"line":155,"column":null}}],"line":153},"9":{"loc":{"start":{"line":166,"column":16},"end":{"line":166,"column":null}},"type":"binary-expr","locations":[{"start":{"line":166,"column":16},"end":{"line":166,"column":48}},{"start":{"line":166,"column":48},"end":{"line":166,"column":null}}],"line":166},"10":{"loc":{"start":{"line":171,"column":23},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":171,"column":51},"end":{"line":171,"column":70}},{"start":{"line":171,"column":70},"end":{"line":171,"column":null}}],"line":171}},"s":{"0":3,"1":3,"2":3,"3":2,"4":2,"5":2,"6":0,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0},"f":{"0":3,"1":0},"b":{"0":[3,0],"1":[2,0],"2":[0,0],"3":[1,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0]},"meta":{"lastBranch":11,"lastFunction":2,"lastStatement":23,"seen":{"f:38:22:38:Infinity":0,"s:43:24:43:Infinity":0,"s:44:2:111:Infinity":1,"s:45:19:52:Infinity":2,"b:49:24:49:80:49:80:49:Infinity":0,"s:54:52:61:Infinity":3,"b:63:4:65:Infinity:undefined:undefined:undefined:undefined":1,"s:63:4:65:Infinity":4,"s:64:6:64:Infinity":5,"s:67:4:77:Infinity":6,"b:74:16:74:32:74:32:74:Infinity":2,"s:79:23:79:Infinity":7,"b:79:51:79:70:79:70:79:Infinity":3,"s:80:4:83:Infinity":8,"s:84:4:110:Infinity":9,"f:114:22:114:Infinity":1,"s:119:24:119:Infinity":10,"s:120:23:120:Infinity":11,"b:121:2:132:Infinity:undefined:undefined:undefined:undefined":4,"s:121:2:132:Infinity":12,"b:121:6:121:42:121:42:121:65":5,"s:122:4:131:Infinity":13,"s:134:2:203:Infinity":14,"s:135:25:137:Infinity":15,"s:139:52:147:Infinity":16,"b:146:32:146:66:146:66:146:Infinity":6,"b:149:4:157:Infinity:undefined:undefined:undefined:undefined":7,"s:149:4:157:Infinity":17,"s:150:6:156:Infinity":18,"b:154:13:154:Infinity:155:12:155:Infinity":8,"s:159:4:169:Infinity":19,"b:166:16:166:48:166:48:166:Infinity":9,"s:171:23:171:Infinity":20,"b:171:51:171:70:171:70:171:Infinity":10,"s:172:4:175:Infinity":21,"s:176:4:202:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/persistence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/persistence.ts","statementMap":{"0":{"start":{"line":17,"column":18},"end":{"line":17,"column":null}},"1":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"2":{"start":{"line":20,"column":38},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":44},"end":{"line":25,"column":null}},"4":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"6":{"start":{"line":77,"column":33},"end":{"line":77,"column":null}},"7":{"start":{"line":78,"column":2},"end":{"line":87,"column":null}},"8":{"start":{"line":79,"column":19},"end":{"line":79,"column":null}},"9":{"start":{"line":80,"column":4},"end":{"line":84,"column":null}},"10":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"11":{"start":{"line":94,"column":2},"end":{"line":94,"column":null}},"12":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}}},"fnMap":{"0":{"name":"emptyQueue","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"loc":{"start":{"line":66,"column":21},"end":{"line":72,"column":null}},"line":66},"1":{"name":"loadMcpRetryQueue","decl":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"loc":{"start":{"line":76,"column":21},"end":{"line":88,"column":null}},"line":76},"2":{"name":"saveMcpRetryQueue","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"loc":{"start":{"line":93,"column":8},"end":{"line":96,"column":null}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"default-arg","locations":[{"start":{"line":65,"column":21},"end":{"line":65,"column":null}}],"line":65},"1":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"default-arg","locations":[{"start":{"line":75,"column":22},"end":{"line":75,"column":null}}],"line":75},"2":{"loc":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":77},"3":{"loc":{"start":{"line":81,"column":14},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":14},"end":{"line":81,"column":31}},{"start":{"line":81,"column":31},"end":{"line":81,"column":null}}],"line":81},"4":{"loc":{"start":{"line":82,"column":17},"end":{"line":82,"column":null}},"type":"binary-expr","locations":[{"start":{"line":82,"column":17},"end":{"line":82,"column":37}},{"start":{"line":82,"column":37},"end":{"line":82,"column":null}}],"line":82},"5":{"loc":{"start":{"line":83,"column":15},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":47},"end":{"line":83,"column":88}},{"start":{"line":83,"column":88},"end":{"line":83,"column":null}}],"line":83},"6":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"default-arg","locations":[{"start":{"line":92,"column":22},"end":{"line":92,"column":null}}],"line":92}},"s":{"0":3,"1":3,"2":3,"3":3,"4":4,"5":7,"6":4,"7":3,"8":3,"9":3,"10":0,"11":5,"12":5},"f":{"0":4,"1":7,"2":5},"b":{"0":[4],"1":[7],"2":[4,3],"3":[3,0],"4":[7,0],"5":[3,0],"6":[5]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":13,"seen":{"s:17:18:17:Infinity":0,"s:18:18:18:Infinity":1,"s:20:38:20:Infinity":2,"s:21:44:25:Infinity":3,"f:64:16:64:Infinity":0,"b:65:21:65:Infinity":0,"s:67:2:71:Infinity":4,"f:74:16:74:Infinity":1,"b:75:22:75:Infinity":1,"b:77:2:77:Infinity:undefined:undefined:undefined:undefined":2,"s:77:2:77:Infinity":5,"s:77:33:77:Infinity":6,"s:78:2:87:Infinity":7,"s:79:19:79:Infinity":8,"s:80:4:84:Infinity":9,"b:81:14:81:31:81:31:81:Infinity":3,"b:82:17:82:37:82:37:82:Infinity":4,"b:83:47:83:88:83:88:83:Infinity":5,"s:86:4:86:Infinity":10,"f:90:16:90:Infinity":2,"b:92:22:92:Infinity":6,"s:94:2:94:Infinity":11,"s:95:2:95:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/retry-policy.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/retry-policy.ts","statementMap":{"0":{"start":{"line":25,"column":28},"end":{"line":25,"column":null}},"1":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"2":{"start":{"line":39,"column":20},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":60,"column":16},"end":{"line":60,"column":null}},"5":{"start":{"line":61,"column":18},"end":{"line":61,"column":null}},"6":{"start":{"line":63,"column":2},"end":{"line":65,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"8":{"start":{"line":67,"column":2},"end":{"line":79,"column":null}},"9":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"10":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":78,"column":null}},"12":{"start":{"line":81,"column":37},"end":{"line":85,"column":null}},"13":{"start":{"line":84,"column":50},"end":{"line":84,"column":90}},"14":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"15":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}}},"fnMap":{"0":{"name":"createRetryQueueEntry","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":38}},"loc":{"start":{"line":37,"column":23},"end":{"line":54,"column":null}},"line":37},"1":{"name":"enqueueRetryEntries","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":59,"column":21},"end":{"line":88,"column":null}},"line":59},"2":{"name":"(anonymous_2)","decl":{"start":{"line":84,"column":35},"end":{"line":84,"column":41}},"loc":{"start":{"line":84,"column":50},"end":{"line":84,"column":90}},"line":84}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":22},"end":{"line":38,"column":45}},{"start":{"line":38,"column":45},"end":{"line":38,"column":null}}],"line":38},"1":{"loc":{"start":{"line":40,"column":40},"end":{"line":40,"column":88}},"type":"binary-expr","locations":[{"start":{"line":40,"column":40},"end":{"line":40,"column":65}},{"start":{"line":40,"column":65},"end":{"line":40,"column":88}}],"line":40},"2":{"loc":{"start":{"line":46,"column":13},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":32}},{"start":{"line":46,"column":32},"end":{"line":46,"column":null}}],"line":46},"3":{"loc":{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":25},"end":{"line":52,"column":54}},{"start":{"line":52,"column":54},"end":{"line":52,"column":null}}],"line":52},"4":{"loc":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"type":"default-arg","locations":[{"start":{"line":58,"column":22},"end":{"line":58,"column":null}}],"line":58},"5":{"loc":{"start":{"line":70,"column":21},"end":{"line":78,"column":13}},"type":"cond-expr","locations":[{"start":{"line":71,"column":8},"end":{"line":77,"column":null}},{"start":{"line":78,"column":8},"end":{"line":78,"column":13}}],"line":70}},"s":{"0":3,"1":5,"2":5,"3":5,"4":3,"5":3,"6":3,"7":0,"8":3,"9":5,"10":5,"11":5,"12":3,"13":1,"14":3,"15":3},"f":{"0":5,"1":3,"2":1},"b":{"0":[5,5],"1":[5,5],"2":[5,5],"3":[0,5],"4":[3],"5":[1,4]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":16,"seen":{"s:25:28:25:Infinity":0,"f:27:16:27:38":0,"s:38:22:38:Infinity":1,"b:38:22:38:45:38:45:38:Infinity":0,"s:39:20:41:Infinity":2,"b:40:40:40:65:40:65:40:88":1,"s:42:2:53:Infinity":3,"b:46:13:46:32:46:32:46:Infinity":2,"b:52:25:52:54:52:54:52:Infinity":3,"f:56:16:56:Infinity":1,"b:58:22:58:Infinity":4,"s:60:16:60:Infinity":4,"s:61:18:61:Infinity":5,"s:63:2:65:Infinity":6,"s:64:4:64:Infinity":7,"s:67:2:79:Infinity":8,"s:68:16:68:Infinity":9,"s:69:21:69:Infinity":10,"s:70:4:78:Infinity":11,"b:71:8:77:Infinity:78:8:78:13":5,"s:81:37:85:Infinity":12,"f:84:35:84:41":2,"s:84:50:84:90":13,"s:86:2:86:Infinity":14,"s:87:2:87:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/imf.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/imf.ts","statementMap":{"0":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"1":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"2":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"3":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"4":{"start":{"line":50,"column":2},"end":{"line":54,"column":null}},"5":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":2},"end":{"line":68,"column":null}},"7":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"persistIMFData","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"loc":{"start":{"line":44,"column":10},"end":{"line":71,"column":null}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":43,"column":null}},"type":"default-arg","locations":[{"start":{"line":43,"column":6},"end":{"line":43,"column":null}}],"line":39},"1":{"loc":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":19},"end":{"line":45,"column":39}},{"start":{"line":45,"column":39},"end":{"line":45,"column":null}}],"line":45},"2":{"loc":{"start":{"line":64,"column":10},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":64,"column":29},"end":{"line":64,"column":62}},{"start":{"line":64,"column":62},"end":{"line":64,"column":null}}],"line":64},"3":{"loc":{"start":{"line":65,"column":10},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":38},"end":{"line":65,"column":89}},{"start":{"line":65,"column":89},"end":{"line":65,"column":null}}],"line":65}},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5},"f":{"0":5},"b":{"0":[5],"1":[5,0],"2":[2,3],"3":[2,3]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":8,"seen":{"f:35:16:35:Infinity":0,"b:43:6:43:Infinity":0,"s:45:19:45:Infinity":0,"b:45:19:45:39:45:39:45:Infinity":1,"s:46:14:46:Infinity":1,"s:47:2:47:Infinity":2,"s:49:19:49:Infinity":3,"s:50:2:54:Infinity":4,"s:56:23:56:Infinity":5,"s:57:2:68:Infinity":6,"b:64:29:64:62:64:62:64:Infinity":2,"b:65:38:65:89:65:89:65:Infinity":3,"s:70:2:70:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/documents.ts","statementMap":{"0":{"start":{"line":51,"column":58},"end":{"line":59,"column":null}},"1":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"2":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"3":{"start":{"line":63,"column":16},"end":{"line":63,"column":null}},"4":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"5":{"start":{"line":66,"column":38},"end":{"line":74,"column":null}},"6":{"start":{"line":76,"column":2},"end":{"line":123,"column":null}},"7":{"start":{"line":77,"column":17},"end":{"line":77,"column":null}},"8":{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},"9":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"10":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"11":{"start":{"line":83,"column":42},"end":{"line":88,"column":null}},"12":{"start":{"line":90,"column":20},"end":{"line":90,"column":null}},"13":{"start":{"line":91,"column":4},"end":{"line":122,"column":null}},"14":{"start":{"line":91,"column":17},"end":{"line":91,"column":20}},"15":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"16":{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},"17":{"start":{"line":94,"column":8},"end":{"line":94,"column":null}},"18":{"start":{"line":95,"column":8},"end":{"line":95,"column":null}},"19":{"start":{"line":98,"column":18},"end":{"line":98,"column":null}},"20":{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},"21":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"22":{"start":{"line":101,"column":8},"end":{"line":101,"column":null}},"23":{"start":{"line":101,"column":50},"end":{"line":101,"column":null}},"24":{"start":{"line":102,"column":8},"end":{"line":102,"column":null}},"25":{"start":{"line":104,"column":6},"end":{"line":104,"column":null}},"26":{"start":{"line":105,"column":23},"end":{"line":105,"column":null}},"27":{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},"28":{"start":{"line":108,"column":25},"end":{"line":110,"column":null}},"29":{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},"30":{"start":{"line":112,"column":30},"end":{"line":112,"column":null}},"31":{"start":{"line":113,"column":10},"end":{"line":116,"column":null}},"32":{"start":{"line":120,"column":6},"end":{"line":120,"column":null}},"33":{"start":{"line":121,"column":6},"end":{"line":121,"column":null}},"34":{"start":{"line":125,"column":2},"end":{"line":125,"column":null}},"35":{"start":{"line":137,"column":20},"end":{"line":137,"column":null}},"36":{"start":{"line":138,"column":16},"end":{"line":138,"column":null}},"37":{"start":{"line":139,"column":16},"end":{"line":139,"column":null}},"38":{"start":{"line":141,"column":2},"end":{"line":163,"column":null}},"39":{"start":{"line":141,"column":15},"end":{"line":141,"column":18}},"40":{"start":{"line":142,"column":18},"end":{"line":142,"column":null}},"41":{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},"42":{"start":{"line":143,"column":18},"end":{"line":143,"column":29}},"43":{"start":{"line":143,"column":29},"end":{"line":143,"column":39}},"44":{"start":{"line":145,"column":19},"end":{"line":145,"column":null}},"45":{"start":{"line":146,"column":20},"end":{"line":150,"column":null}},"46":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"47":{"start":{"line":153,"column":21},"end":{"line":153,"column":null}},"48":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"49":{"start":{"line":156,"column":4},"end":{"line":161,"column":null}},"50":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"51":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"52":{"start":{"line":177,"column":20},"end":{"line":177,"column":null}},"53":{"start":{"line":178,"column":16},"end":{"line":178,"column":null}},"54":{"start":{"line":179,"column":16},"end":{"line":179,"column":null}},"55":{"start":{"line":181,"column":2},"end":{"line":197,"column":null}},"56":{"start":{"line":181,"column":15},"end":{"line":181,"column":18}},"57":{"start":{"line":182,"column":15},"end":{"line":182,"column":null}},"58":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"59":{"start":{"line":183,"column":15},"end":{"line":183,"column":26}},"60":{"start":{"line":183,"column":26},"end":{"line":183,"column":36}},"61":{"start":{"line":185,"column":19},"end":{"line":185,"column":null}},"62":{"start":{"line":186,"column":16},"end":{"line":187,"column":null}},"63":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"64":{"start":{"line":190,"column":4},"end":{"line":195,"column":null}},"65":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"66":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}}},"fnMap":{"0":{"name":"persistDownloadedData","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"loc":{"start":{"line":50,"column":21},"end":{"line":126,"column":null}},"line":50},"1":{"name":"persistEvents","decl":{"start":{"line":132,"column":16},"end":{"line":132,"column":null}},"loc":{"start":{"line":136,"column":21},"end":{"line":166,"column":null}},"line":136},"2":{"name":"persistMPs","decl":{"start":{"line":172,"column":16},"end":{"line":172,"column":null}},"loc":{"start":{"line":176,"column":21},"end":{"line":200,"column":null}},"line":176}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"type":"default-arg","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"2":{"loc":{"start":{"line":78,"column":8},"end":{"line":78,"column":36}},"type":"binary-expr","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":17}},{"start":{"line":78,"column":17},"end":{"line":78,"column":36}}],"line":78},"3":{"loc":{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":93},"4":{"loc":{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":99},"5":{"loc":{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},{"start":{},"end":{}}],"line":107},"6":{"loc":{"start":{"line":107,"column":10},"end":{"line":107,"column":44}},"type":"binary-expr","locations":[{"start":{"line":107,"column":10},"end":{"line":107,"column":33}},{"start":{"line":107,"column":33},"end":{"line":107,"column":44}}],"line":107},"7":{"loc":{"start":{"line":108,"column":25},"end":{"line":110,"column":null}},"type":"cond-expr","locations":[{"start":{"line":109,"column":12},"end":{"line":109,"column":null}},{"start":{"line":110,"column":12},"end":{"line":110,"column":null}}],"line":108},"8":{"loc":{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":111},"9":{"loc":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"type":"default-arg","locations":[{"start":{"line":135,"column":21},"end":{"line":135,"column":null}}],"line":135},"10":{"loc":{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":143},"11":{"loc":{"start":{"line":146,"column":20},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":9},"end":{"line":147,"column":null}},{"start":{"line":148,"column":8},"end":{"line":150,"column":null}}],"line":146},"12":{"loc":{"start":{"line":148,"column":8},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":149,"column":11},"end":{"line":149,"column":null}},{"start":{"line":150,"column":10},"end":{"line":150,"column":null}}],"line":148},"13":{"loc":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":50},"end":{"line":152,"column":60}},{"start":{"line":152,"column":60},"end":{"line":152,"column":null}}],"line":152},"14":{"loc":{"start":{"line":175,"column":2},"end":{"line":175,"column":null}},"type":"default-arg","locations":[{"start":{"line":175,"column":21},"end":{"line":175,"column":null}}],"line":175},"15":{"loc":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},{"start":{},"end":{}}],"line":183},"16":{"loc":{"start":{"line":186,"column":16},"end":{"line":187,"column":null}},"type":"binary-expr","locations":[{"start":{"line":186,"column":16},"end":{"line":186,"column":63}},{"start":{"line":186,"column":63},"end":{"line":186,"column":null}},{"start":{"line":187,"column":9},"end":{"line":187,"column":null}}],"line":186},"17":{"loc":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":22},"end":{"line":188,"column":43}},{"start":{"line":188,"column":43},"end":{"line":188,"column":null}}],"line":188}},"s":{"0":19,"1":19,"2":19,"3":19,"4":19,"5":19,"6":19,"7":133,"8":133,"9":104,"10":29,"11":29,"12":29,"13":29,"14":29,"15":32,"16":32,"17":1,"18":1,"19":31,"20":31,"21":2,"22":2,"23":1,"24":2,"25":31,"26":31,"27":31,"28":4,"29":4,"30":4,"31":4,"32":31,"33":31,"34":19,"35":10,"36":10,"37":10,"38":10,"39":10,"40":11,"41":11,"42":1,"43":1,"44":10,"45":10,"46":11,"47":11,"48":11,"49":11,"50":11,"51":10,"52":9,"53":9,"54":9,"55":9,"56":9,"57":59,"58":59,"59":1,"60":1,"61":58,"62":58,"63":59,"64":59,"65":59,"66":9},"f":{"0":19,"1":10,"2":9},"b":{"0":[19],"1":[104,29],"2":[133,133],"3":[1,31],"4":[2,29],"5":[4,27],"6":[31,4],"7":[4,0],"8":[4,0],"9":[10],"10":[1,10],"11":[7,3],"12":[2,1],"13":[9,1],"14":[9],"15":[1,58],"16":[58,57,1],"17":[59,0]},"meta":{"lastBranch":18,"lastFunction":3,"lastStatement":67,"seen":{"f:45:16:45:Infinity":0,"b:49:21:49:Infinity":0,"s:51:58:59:Infinity":0,"s:60:18:60:Infinity":1,"s:61:20:61:Infinity":2,"s:63:16:63:Infinity":3,"s:64:16:64:Infinity":4,"s:66:38:74:Infinity":5,"s:76:2:123:Infinity":6,"s:77:17:77:Infinity":7,"b:78:4:80:Infinity:undefined:undefined:undefined:undefined":1,"s:78:4:80:Infinity":8,"b:78:8:78:17:78:17:78:36":2,"s:79:6:79:Infinity":9,"s:82:20:82:Infinity":10,"s:83:42:88:Infinity":11,"s:90:20:90:Infinity":12,"s:91:4:122:Infinity":13,"s:91:17:91:20":14,"s:92:18:92:Infinity":15,"b:93:6:96:Infinity:undefined:undefined:undefined:undefined":3,"s:93:6:96:Infinity":16,"s:94:8:94:Infinity":17,"s:95:8:95:Infinity":18,"s:98:18:98:Infinity":19,"b:99:6:103:Infinity:undefined:undefined:undefined:undefined":4,"s:99:6:103:Infinity":20,"s:100:21:100:Infinity":21,"s:101:8:101:Infinity":22,"s:101:50:101:Infinity":23,"s:102:8:102:Infinity":24,"s:104:6:104:Infinity":25,"s:105:23:105:Infinity":26,"b:107:6:118:Infinity:undefined:undefined:undefined:undefined":5,"s:107:6:118:Infinity":27,"b:107:10:107:33:107:33:107:44":6,"s:108:25:110:Infinity":28,"b:109:12:109:Infinity:110:12:110:Infinity":7,"b:111:8:117:Infinity:undefined:undefined:undefined:undefined":8,"s:111:8:117:Infinity":29,"s:112:30:112:Infinity":30,"s:113:10:116:Infinity":31,"s:120:6:120:Infinity":32,"s:121:6:121:Infinity":33,"s:125:2:125:Infinity":34,"f:132:16:132:Infinity":1,"b:135:21:135:Infinity":9,"s:137:20:137:Infinity":35,"s:138:16:138:Infinity":36,"s:139:16:139:Infinity":37,"s:141:2:163:Infinity":38,"s:141:15:141:18":39,"s:142:18:142:Infinity":40,"b:143:4:143:Infinity:undefined:undefined:undefined:undefined":10,"s:143:4:143:Infinity":41,"s:143:18:143:29":42,"s:143:29:143:39":43,"s:145:19:145:Infinity":44,"s:146:20:150:Infinity":45,"b:147:9:147:Infinity:148:8:150:Infinity":11,"b:149:11:149:Infinity:150:10:150:Infinity":12,"s:152:22:152:Infinity":46,"b:152:50:152:60:152:60:152:Infinity":13,"s:153:21:153:Infinity":47,"s:155:20:155:Infinity":48,"s:156:4:161:Infinity":49,"s:162:4:162:Infinity":50,"s:165:2:165:Infinity":51,"f:172:16:172:Infinity":2,"b:175:21:175:Infinity":14,"s:177:20:177:Infinity":52,"s:178:16:178:Infinity":53,"s:179:16:179:Infinity":54,"s:181:2:197:Infinity":55,"s:181:15:181:18":56,"s:182:15:182:Infinity":57,"b:183:4:183:Infinity:undefined:undefined:undefined:undefined":15,"s:183:4:183:Infinity":58,"s:183:15:183:26":59,"s:183:26:183:36":60,"s:185:19:185:Infinity":61,"s:186:16:187:Infinity":62,"b:186:16:186:63:186:63:186:Infinity:187:9:187:Infinity":16,"s:188:22:188:Infinity":63,"b:188:22:188:43:188:43:188:Infinity":17,"s:190:4:195:Infinity":64,"s:196:4:196:Infinity":65,"s:199:2:199:Infinity":66}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/mcp-response.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/mcp-response.ts","statementMap":{"0":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"2":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"3":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"4":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"5":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":54,"column":null}},"7":{"start":{"line":56,"column":27},"end":{"line":57,"column":null}},"8":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"9":{"start":{"line":60,"column":78},"end":{"line":66,"column":null}},"10":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"11":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}}},"fnMap":{"0":{"name":"persistMCPResponse","decl":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"loc":{"start":{"line":42,"column":10},"end":{"line":74,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"default-arg","locations":[{"start":{"line":40,"column":21},"end":{"line":40,"column":null}}],"line":40},"1":{"loc":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":20},"end":{"line":43,"column":41}},{"start":{"line":43,"column":41},"end":{"line":43,"column":null}}],"line":43},"2":{"loc":{"start":{"line":56,"column":27},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":27},"end":{"line":56,"column":null}},{"start":{"line":57,"column":8},"end":{"line":57,"column":null}}],"line":56},"3":{"loc":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":45},"end":{"line":57,"column":62}},{"start":{"line":57,"column":62},"end":{"line":57,"column":null}}],"line":57}},"s":{"0":17,"1":17,"2":17,"3":17,"4":17,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":17},"f":{"0":17},"b":{"0":[17],"1":[17,1],"2":[17,16],"3":[2,14]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":12,"seen":{"f:36:16:36:Infinity":0,"b:40:21:40:Infinity":0,"s:43:20:43:Infinity":0,"b:43:20:43:41:43:41:43:Infinity":1,"s:44:21:44:Infinity":1,"s:45:19:45:Infinity":2,"s:46:14:46:Infinity":3,"s:47:2:47:Infinity":4,"s:49:19:49:Infinity":5,"s:50:2:54:Infinity":6,"s:56:27:57:Infinity":7,"b:56:27:56:Infinity:57:8:57:Infinity":2,"b:57:45:57:62:57:62:57:Infinity":3,"s:59:23:59:Infinity":8,"s:60:78:66:Infinity":9,"s:67:2:71:Infinity":10,"s:73:2:73:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/scb.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/scb.ts","statementMap":{"0":{"start":{"line":30,"column":14},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"2":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"5":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"6":{"start":{"line":42,"column":2},"end":{"line":51,"column":null}},"7":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"persistSCBData","decl":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"loc":{"start":{"line":29,"column":10},"end":{"line":54,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":21},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":48,"column":10},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":18},"end":{"line":48,"column":30}},{"start":{"line":48,"column":30},"end":{"line":48,"column":null}}],"line":48}},"s":{"0":7,"1":7,"2":7,"3":7,"4":7,"5":7,"6":7,"7":7},"f":{"0":7},"b":{"0":[7],"1":[3,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":8,"seen":{"f:24:16:24:Infinity":0,"b:28:21:28:Infinity":0,"s:30:14:30:Infinity":0,"s:31:2:31:Infinity":1,"s:33:20:33:Infinity":2,"s:34:19:34:Infinity":3,"s:35:2:39:Infinity":4,"s:41:23:41:Infinity":5,"s:42:2:51:Infinity":6,"b:48:18:48:30:48:30:48:Infinity":1,"s:53:2:53:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/meta-sidecar.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/meta-sidecar.ts","statementMap":{"0":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"1":{"start":{"line":29,"column":25},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":25},"end":{"line":31,"column":null}},"3":{"start":{"line":34,"column":27},"end":{"line":34,"column":null}},"4":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"5":{"start":{"line":100,"column":17},"end":{"line":100,"column":null}},"6":{"start":{"line":101,"column":21},"end":{"line":108,"column":null}},"7":{"start":{"line":109,"column":13},"end":{"line":111,"column":null}},"8":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"9":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"10":{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},"11":{"start":{"line":136,"column":4},"end":{"line":138,"column":null}},"12":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"13":{"start":{"line":141,"column":22},"end":{"line":141,"column":null}},"14":{"start":{"line":142,"column":2},"end":{"line":146,"column":null}},"15":{"start":{"line":147,"column":23},"end":{"line":147,"column":null}},"16":{"start":{"line":148,"column":2},"end":{"line":152,"column":null}},"17":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}}},"fnMap":{"0":{"name":"ensureDir","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":26}},"loc":{"start":{"line":91,"column":45},"end":{"line":93,"column":null}},"line":91},"1":{"name":"resolveDocId","decl":{"start":{"line":99,"column":16},"end":{"line":99,"column":29}},"loc":{"start":{"line":99,"column":70},"end":{"line":113,"column":null}},"line":99},"2":{"name":"(anonymous_2)","decl":{"start":{"line":109,"column":24},"end":{"line":109,"column":null}},"loc":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"line":110},"3":{"name":"writeDocumentAndMeta","decl":{"start":{"line":129,"column":16},"end":{"line":129,"column":null}},"loc":{"start":{"line":134,"column":8},"end":{"line":153,"column":null}},"line":134},"4":{"name":"getDataRoot","decl":{"start":{"line":159,"column":16},"end":{"line":159,"column":38}},"loc":{"start":{"line":159,"column":38},"end":{"line":161,"column":null}},"line":159}},"branchMap":{"0":{"loc":{"start":{"line":109,"column":13},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":109,"column":13},"end":{"line":111,"column":15}},{"start":{"line":111,"column":15},"end":{"line":111,"column":null}}],"line":109},"1":{"loc":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"type":"binary-expr","locations":[{"start":{"line":110,"column":24},"end":{"line":110,"column":49}},{"start":{"line":110,"column":49},"end":{"line":110,"column":null}}],"line":110},"2":{"loc":{"start":{"line":112,"column":9},"end":{"line":112,"column":null}},"type":"binary-expr","locations":[{"start":{"line":112,"column":9},"end":{"line":112,"column":30}},{"start":{"line":112,"column":30},"end":{"line":112,"column":null}}],"line":112},"3":{"loc":{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":135}},"s":{"0":25,"1":25,"2":25,"3":25,"4":154,"5":49,"6":49,"7":49,"8":85,"9":49,"10":110,"11":1,"12":109,"13":109,"14":109,"15":109,"16":109,"17":3},"f":{"0":154,"1":49,"2":85,"3":110,"4":3},"b":{"0":[49,1],"1":[85,49],"2":[49,0],"3":[1,109]},"meta":{"lastBranch":4,"lastFunction":5,"lastStatement":18,"seen":{"s:27:18:27:Infinity":0,"s:29:25:29:Infinity":1,"s:31:25:31:Infinity":2,"s:34:27:34:Infinity":3,"f:91:16:91:26":0,"s:92:2:92:Infinity":4,"f:99:16:99:29":1,"s:100:17:100:Infinity":5,"s:101:21:108:Infinity":6,"s:109:13:111:Infinity":7,"b:109:13:111:15:111:15:111:Infinity":0,"f:109:24:109:Infinity":2,"s:110:24:110:Infinity":8,"b:110:24:110:49:110:49:110:Infinity":1,"s:112:2:112:Infinity":9,"b:112:9:112:30:112:30:112:Infinity":2,"f:129:16:129:Infinity":3,"b:135:2:139:Infinity:undefined:undefined:undefined:undefined":3,"s:135:2:139:Infinity":10,"s:136:4:138:Infinity":11,"s:140:2:140:Infinity":12,"s:141:22:141:Infinity":13,"s:142:2:146:Infinity":14,"s:147:23:147:Infinity":15,"s:148:2:152:Infinity":16,"f:159:16:159:38":4,"s:160:2:160:Infinity":17}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/riksbank.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/riksbank.ts","statementMap":{"0":{"start":{"line":32,"column":14},"end":{"line":32,"column":null}},"1":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"2":{"start":{"line":35,"column":20},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":2},"end":{"line":41,"column":null}},"5":{"start":{"line":43,"column":23},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":20},"end":{"line":48,"column":null}},"7":{"start":{"line":49,"column":23},"end":{"line":49,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":59,"column":null}},"9":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}}},"fnMap":{"0":{"name":"persistRiksbankData","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"loc":{"start":{"line":31,"column":10},"end":{"line":62,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"default-arg","locations":[{"start":{"line":30,"column":21},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":43,"column":23},"end":{"line":45,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":7},"end":{"line":44,"column":null}},{"start":{"line":45,"column":6},"end":{"line":45,"column":null}}],"line":43},"2":{"loc":{"start":{"line":43,"column":23},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":23},"end":{"line":43,"column":55}},{"start":{"line":43,"column":55},"end":{"line":43,"column":76}},{"start":{"line":43,"column":76},"end":{"line":43,"column":null}}],"line":43},"3":{"loc":{"start":{"line":46,"column":20},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},{"start":{"line":48,"column":6},"end":{"line":48,"column":null}}],"line":46},"4":{"loc":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":20},"end":{"line":46,"column":56}},{"start":{"line":46,"column":56},"end":{"line":46,"column":null}}],"line":46},"5":{"loc":{"start":{"line":56,"column":10},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":56,"column":22},"end":{"line":56,"column":43}},{"start":{"line":56,"column":43},"end":{"line":56,"column":null}}],"line":56}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3},"f":{"0":3},"b":{"0":[3],"1":[2,1],"2":[3,3,3],"3":[2,1],"4":[3,2],"5":[2,1]},"meta":{"lastBranch":6,"lastFunction":1,"lastStatement":10,"seen":{"f:27:16:27:Infinity":0,"b:30:21:30:Infinity":0,"s:32:14:32:Infinity":0,"s:33:2:33:Infinity":1,"s:35:20:35:Infinity":2,"s:36:19:36:Infinity":3,"s:37:2:41:Infinity":4,"s:43:23:45:Infinity":5,"b:44:7:44:Infinity:45:6:45:Infinity":1,"b:43:23:43:55:43:55:43:76:43:76:43:Infinity":2,"s:46:20:48:Infinity":6,"b:47:6:47:Infinity:48:6:48:Infinity":3,"b:46:20:46:56:46:56:46:Infinity":4,"s:49:23:49:Infinity":7,"s:50:2:59:Infinity":8,"b:56:22:56:43:56:43:56:Infinity":5,"s:61:2:61:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/sanitize.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/sanitize.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":32,"column":13},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"3":{"start":{"line":33,"column":26},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}}},"fnMap":{"0":{"name":"sanitizeDokId","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":53},"end":{"line":24,"column":null}},"line":17},"1":{"name":"sanitizePathSegment","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":36}},"loc":{"start":{"line":31,"column":61},"end":{"line":39,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"1":{"loc":{"start":{"line":38,"column":9},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":9},"end":{"line":38,"column":17}},{"start":{"line":38,"column":17},"end":{"line":38,"column":null}}],"line":38}},"s":{"0":188,"1":34,"2":34,"3":1,"4":34,"5":34},"f":{"0":188,"1":34},"b":{"0":[1,33],"1":[34,0]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":6,"seen":{"f:17:16:17:30":0,"s:18:2:23:Infinity":0,"f:31:16:31:36":1,"s:32:13:32:Infinity":1,"b:33:2:33:Infinity:undefined:undefined:undefined:undefined":0,"s:33:2:33:Infinity":2,"s:33:26:33:Infinity":3,"s:34:2:37:Infinity":4,"s:38:2:38:Infinity":5,"b:38:9:38:17:38:17:38:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/strip-metadata.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/strip-metadata.ts","statementMap":{"0":{"start":{"line":19,"column":40},"end":{"line":23,"column":null}},"1":{"start":{"line":33,"column":17},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":47},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},"5":{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},"6":{"start":{"line":37,"column":19},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"8":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}}},"fnMap":{"0":{"name":"stripInMemoryCoverageMetadata","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":46}},"loc":{"start":{"line":32,"column":77},"end":{"line":42,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":36},"1":{"loc":{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"2":{"loc":{"start":{"line":41,"column":10},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":41,"column":10},"end":{"line":41,"column":20}},{"start":{"line":41,"column":20},"end":{"line":41,"column":null}}],"line":41}},"s":{"0":25,"1":109,"2":109,"3":109,"4":327,"5":21,"6":7,"7":21,"8":109},"f":{"0":109},"b":{"0":[21,306],"1":[7,14],"2":[109,102]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":9,"seen":{"s:19:40:23:Infinity":0,"f:32:16:32:46":0,"s:33:17:33:Infinity":1,"s:34:47:34:Infinity":2,"s:35:2:40:Infinity":3,"b:36:4:39:Infinity:undefined:undefined:undefined:undefined":0,"s:36:4:39:Infinity":4,"b:37:6:37:Infinity:undefined:undefined:undefined:undefined":1,"s:37:6:37:Infinity":5,"s:37:19:37:Infinity":6,"s:38:6:38:Infinity":7,"s:41:2:41:Infinity":8,"b:41:10:41:20:41:20:41:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/statskontoret.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/statskontoret.ts","statementMap":{"0":{"start":{"line":36,"column":14},"end":{"line":36,"column":null}},"1":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":39,"column":28},"end":{"line":39,"column":null}},"3":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"4":{"start":{"line":41,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":47,"column":23},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":57,"column":null}},"7":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}}},"fnMap":{"0":{"name":"persistStatskontoretData","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"loc":{"start":{"line":35,"column":10},"end":{"line":60,"column":null}},"line":35}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"default-arg","locations":[{"start":{"line":34,"column":21},"end":{"line":34,"column":null}}],"line":34}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4},"f":{"0":4},"b":{"0":[4]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":8,"seen":{"f:30:16:30:Infinity":0,"b:34:21:34:Infinity":0,"s:36:14:36:Infinity":0,"s:37:2:37:Infinity":1,"s:39:28:39:Infinity":2,"s:40:19:40:Infinity":3,"s:41:2:45:Infinity":4,"s:47:23:47:Infinity":5,"s:48:2:57:Infinity":6,"s:59:2:59:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/world-bank.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/world-bank.ts","statementMap":{"0":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"2":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"4":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"5":{"start":{"line":42,"column":2},"end":{"line":51,"column":null}},"6":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"persistWorldBankData","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":null}},"loc":{"start":{"line":30,"column":10},"end":{"line":54,"column":null}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"default-arg","locations":[{"start":{"line":29,"column":21},"end":{"line":29,"column":null}}],"line":29}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":9,"6":9},"f":{"0":9},"b":{"0":[9]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:25:16:25:Infinity":0,"b:29:21:29:Infinity":0,"s:31:14:31:Infinity":0,"s:32:2:32:Infinity":1,"s:34:19:34:Infinity":2,"s:35:2:39:Infinity":3,"s:41:23:41:Infinity":4,"s:42:2:51:Infinity":5,"s:53:2:53:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/catalog.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/catalog.ts","statementMap":{"0":{"start":{"line":23,"column":20},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":20},"end":{"line":24,"column":null}},"2":{"start":{"line":46,"column":15},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"6":{"start":{"line":62,"column":27},"end":{"line":62,"column":null}},"7":{"start":{"line":63,"column":34},"end":{"line":63,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":78,"column":null}},"9":{"start":{"line":64,"column":56},"end":{"line":64,"column":74}},"10":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"11":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"12":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"13":{"start":{"line":67,"column":24},"end":{"line":67,"column":null}},"14":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"15":{"start":{"line":68,"column":37},"end":{"line":68,"column":null}},"16":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"17":{"start":{"line":70,"column":4},"end":{"line":77,"column":null}},"18":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"buildGithubUrl","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":31}},"loc":{"start":{"line":45,"column":80},"end":{"line":49,"column":null}},"line":45},"1":{"name":"collectCatalog","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":61,"column":18},"end":{"line":80,"column":null}},"line":61},"2":{"name":"(anonymous_2)","decl":{"start":{"line":64,"column":41},"end":{"line":64,"column":47}},"loc":{"start":{"line":64,"column":56},"end":{"line":64,"column":74}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":15},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":33},"end":{"line":46,"column":47}},{"start":{"line":46,"column":47},"end":{"line":46,"column":null}}],"line":46},"1":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":62},"2":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"3":{"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"4":{"loc":{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":12},"end":{"line":73,"column":27}},{"start":{"line":73,"column":27},"end":{"line":73,"column":null}}],"line":73},"5":{"loc":{"start":{"line":73,"column":27},"end":{"line":73,"column":null}},"type":"cond-expr","locations":[{"start":{"line":73,"column":52},"end":{"line":73,"column":59}},{"start":{"line":73,"column":59},"end":{"line":73,"column":null}}],"line":73},"6":{"loc":{"start":{"line":74,"column":19},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":19},"end":{"line":74,"column":40}},{"start":{"line":74,"column":40},"end":{"line":74,"column":null}}],"line":74}},"s":{"0":2,"1":2,"2":438252,"3":438252,"4":438252,"5":62,"6":0,"7":62,"8":62,"9":7130,"10":1953,"11":1953,"12":1953,"13":31,"14":1922,"15":0,"16":1922,"17":1922,"18":62},"f":{"0":438252,"1":62,"2":7130},"b":{"0":[424798,13454],"1":[0,62],"2":[31,1922],"3":[0,1922],"4":[1922,248],"5":[31,217],"6":[1953,248]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":19,"seen":{"s:23:20:23:Infinity":0,"s:24:20:24:Infinity":1,"f:45:16:45:31":0,"s:46:15:46:Infinity":2,"b:46:33:46:47:46:47:46:Infinity":0,"s:47:18:47:Infinity":3,"s:48:2:48:Infinity":4,"f:56:16:56:Infinity":1,"b:62:2:62:Infinity:undefined:undefined:undefined:undefined":1,"s:62:2:62:Infinity":5,"s:62:27:62:Infinity":6,"s:63:34:63:Infinity":7,"s:64:2:78:Infinity":8,"f:64:41:64:47":2,"s:64:56:64:74":9,"s:65:17:65:Infinity":10,"s:66:17:66:Infinity":11,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":2,"s:67:4:67:Infinity":12,"s:67:24:67:Infinity":13,"b:68:4:68:Infinity:undefined:undefined:undefined:undefined":3,"s:68:4:68:Infinity":14,"s:68:37:68:Infinity":15,"s:69:17:69:Infinity":16,"s:70:4:77:Infinity":17,"b:73:12:73:27:73:27:73:Infinity":4,"b:73:52:73:59:73:59:73:Infinity":5,"b:74:19:74:40:74:40:74:Infinity":6,"s:79:2:79:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/daily-streams.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/daily-streams.ts","statementMap":{"0":{"start":{"line":23,"column":19},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":18},"end":{"line":24,"column":null}},"2":{"start":{"line":26,"column":17},"end":{"line":26,"column":null}},"3":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"4":{"start":{"line":51,"column":10},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":2},"end":{"line":59,"column":null}},"6":{"start":{"line":53,"column":17},"end":{"line":53,"column":null}},"7":{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},"8":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"9":{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},"10":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"11":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"12":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"13":{"start":{"line":65,"column":33},"end":{"line":65,"column":null}},"14":{"start":{"line":66,"column":31},"end":{"line":66,"column":null}},"15":{"start":{"line":67,"column":8},"end":{"line":81,"column":null}},"16":{"start":{"line":68,"column":4},"end":{"line":80,"column":null}},"17":{"start":{"line":68,"column":80},"end":{"line":68,"column":108}},"18":{"start":{"line":69,"column":19},"end":{"line":69,"column":null}},"19":{"start":{"line":70,"column":18},"end":{"line":70,"column":null}},"20":{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},"21":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"22":{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},"23":{"start":{"line":74,"column":8},"end":{"line":78,"column":null}},"24":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"25":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"26":{"start":{"line":83,"column":28},"end":{"line":83,"column":56}},"27":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"28":{"start":{"line":87,"column":33},"end":{"line":87,"column":null}},"29":{"start":{"line":88,"column":27},"end":{"line":88,"column":null}},"30":{"start":{"line":89,"column":22},"end":{"line":92,"column":null}},"31":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"32":{"start":{"line":91,"column":16},"end":{"line":91,"column":22}},"33":{"start":{"line":92,"column":20},"end":{"line":92,"column":38}},"34":{"start":{"line":94,"column":2},"end":{"line":120,"column":null}},"35":{"start":{"line":95,"column":20},"end":{"line":95,"column":null}},"36":{"start":{"line":96,"column":24},"end":{"line":99,"column":null}},"37":{"start":{"line":97,"column":21},"end":{"line":97,"column":36}},"38":{"start":{"line":98,"column":18},"end":{"line":98,"column":24}},"39":{"start":{"line":99,"column":22},"end":{"line":99,"column":40}},"40":{"start":{"line":101,"column":35},"end":{"line":110,"column":null}},"41":{"start":{"line":102,"column":24},"end":{"line":102,"column":null}},"42":{"start":{"line":103,"column":24},"end":{"line":103,"column":null}},"43":{"start":{"line":104,"column":6},"end":{"line":109,"column":null}},"44":{"start":{"line":112,"column":27},"end":{"line":112,"column":null}},"45":{"start":{"line":112,"column":52},"end":{"line":112,"column":73}},"46":{"start":{"line":114,"column":4},"end":{"line":119,"column":null}},"47":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"countArtifactsRecursive","decl":{"start":{"line":50,"column":16},"end":{"line":50,"column":40}},"loc":{"start":{"line":50,"column":61},"end":{"line":61,"column":null}},"line":50},"1":{"name":"collectStreamArtifacts","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":39}},"loc":{"start":{"line":64,"column":103},"end":{"line":84,"column":null}},"line":64},"2":{"name":"(anonymous_2)","decl":{"start":{"line":67,"column":8},"end":{"line":67,"column":16}},"loc":{"start":{"line":67,"column":55},"end":{"line":81,"column":null}},"line":67},"3":{"name":"(anonymous_3)","decl":{"start":{"line":68,"column":65},"end":{"line":68,"column":71}},"loc":{"start":{"line":68,"column":80},"end":{"line":68,"column":108}},"line":68},"4":{"name":"(anonymous_4)","decl":{"start":{"line":83,"column":13},"end":{"line":83,"column":19}},"loc":{"start":{"line":83,"column":28},"end":{"line":83,"column":56}},"line":83},"5":{"name":"collectDailyDays","decl":{"start":{"line":86,"column":16},"end":{"line":86,"column":47}},"loc":{"start":{"line":86,"column":47},"end":{"line":123,"column":null}},"line":86},"6":{"name":"(anonymous_6)","decl":{"start":{"line":90,"column":5},"end":{"line":90,"column":13}},"loc":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"line":90},"7":{"name":"(anonymous_7)","decl":{"start":{"line":91,"column":5},"end":{"line":91,"column":10}},"loc":{"start":{"line":91,"column":16},"end":{"line":91,"column":22}},"line":91},"8":{"name":"(anonymous_8)","decl":{"start":{"line":92,"column":5},"end":{"line":92,"column":11}},"loc":{"start":{"line":92,"column":20},"end":{"line":92,"column":38}},"line":92},"9":{"name":"(anonymous_9)","decl":{"start":{"line":97,"column":7},"end":{"line":97,"column":15}},"loc":{"start":{"line":97,"column":21},"end":{"line":97,"column":36}},"line":97},"10":{"name":"(anonymous_10)","decl":{"start":{"line":98,"column":7},"end":{"line":98,"column":12}},"loc":{"start":{"line":98,"column":18},"end":{"line":98,"column":24}},"line":98},"11":{"name":"(anonymous_11)","decl":{"start":{"line":99,"column":7},"end":{"line":99,"column":13}},"loc":{"start":{"line":99,"column":22},"end":{"line":99,"column":40}},"line":99},"12":{"name":"(anonymous_12)","decl":{"start":{"line":101,"column":47},"end":{"line":101,"column":52}},"loc":{"start":{"line":101,"column":61},"end":{"line":110,"column":5}},"line":101},"13":{"name":"(anonymous_13)","decl":{"start":{"line":112,"column":35},"end":{"line":112,"column":43}},"loc":{"start":{"line":112,"column":52},"end":{"line":112,"column":73}},"line":112}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},{"start":{"line":56,"column":11},"end":{"line":58,"column":null}}],"line":54},"1":{"loc":{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":56},"2":{"loc":{"start":{"line":56,"column":15},"end":{"line":56,"column":59}},"type":"binary-expr","locations":[{"start":{"line":56,"column":15},"end":{"line":56,"column":29}},{"start":{"line":56,"column":29},"end":{"line":56,"column":59}}],"line":56},"3":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"4":{"loc":{"start":{"line":70,"column":18},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":28},"end":{"line":70,"column":53}},{"start":{"line":70,"column":53},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},{"start":{"line":73,"column":13},"end":{"line":79,"column":null}}],"line":71},"6":{"loc":{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":73},"7":{"loc":{"start":{"line":73,"column":17},"end":{"line":73,"column":61}},"type":"binary-expr","locations":[{"start":{"line":73,"column":17},"end":{"line":73,"column":31}},{"start":{"line":73,"column":31},"end":{"line":73,"column":61}}],"line":73},"8":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"9":{"loc":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"type":"binary-expr","locations":[{"start":{"line":90,"column":19},"end":{"line":90,"column":38}},{"start":{"line":90,"column":38},"end":{"line":90,"column":72}}],"line":90},"10":{"loc":{"start":{"line":107,"column":23},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":107,"column":23},"end":{"line":107,"column":43}},{"start":{"line":107,"column":43},"end":{"line":107,"column":null}}],"line":107}},"s":{"0":2,"1":2,"2":2,"3":2,"4":4,"5":4,"6":7,"7":7,"8":1,"9":6,"10":5,"11":4,"12":11474,"13":1,"14":11473,"15":11473,"16":21549,"17":1270880,"18":432985,"19":432985,"20":432985,"21":10076,"22":422909,"23":422876,"24":11473,"25":11473,"26":411682,"27":32,"28":1,"29":31,"30":31,"31":2046,"32":1984,"33":1953,"34":31,"35":1984,"36":1984,"37":13950,"38":11470,"39":12183,"40":1984,"41":11470,"42":11470,"43":11470,"44":1984,"45":11470,"46":1984,"47":31},"f":{"0":4,"1":11474,"2":21549,"3":1270880,"4":411682,"5":32,"6":2046,"7":1984,"8":1953,"9":13950,"10":11470,"11":12183,"12":11470,"13":11470},"b":{"0":[1,6],"1":[5,1],"2":[6,6],"3":[1,11473],"4":[128341,304644],"5":[10076,422909],"6":[422876,33],"7":[422909,422909],"8":[1,31],"9":[2046,1984],"10":[11470,0]},"meta":{"lastBranch":11,"lastFunction":14,"lastStatement":48,"seen":{"s:23:19:23:Infinity":0,"s:24:18:24:Infinity":1,"s:26:17:26:Infinity":2,"s:27:18:27:Infinity":3,"f:50:16:50:40":0,"s:51:10:51:Infinity":4,"s:52:2:59:Infinity":5,"s:53:17:53:Infinity":6,"b:54:4:58:Infinity:56:11:58:Infinity":0,"s:54:4:58:Infinity":7,"s:55:6:55:Infinity":8,"b:56:11:58:Infinity:undefined:undefined:undefined:undefined":1,"s:56:11:58:Infinity":9,"b:56:15:56:29:56:29:56:59":2,"s:57:6:57:Infinity":10,"s:60:2:60:Infinity":11,"f:64:16:64:39":1,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:2:65:Infinity":12,"s:65:33:65:Infinity":13,"s:66:31:66:Infinity":14,"s:67:8:81:Infinity":15,"f:67:8:67:16":2,"s:68:4:80:Infinity":16,"f:68:65:68:71":3,"s:68:80:68:108":17,"s:69:19:69:Infinity":18,"s:70:18:70:Infinity":19,"b:70:28:70:53:70:53:70:Infinity":4,"b:71:6:79:Infinity:73:13:79:Infinity":5,"s:71:6:79:Infinity":20,"s:72:8:72:Infinity":21,"b:73:13:79:Infinity:undefined:undefined:undefined:undefined":6,"s:73:13:79:Infinity":22,"b:73:17:73:31:73:31:73:61":7,"s:74:8:78:Infinity":23,"s:82:2:82:Infinity":24,"s:83:2:83:Infinity":25,"f:83:13:83:19":4,"s:83:28:83:56":26,"f:86:16:86:47":5,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":8,"s:87:2:87:Infinity":27,"s:87:33:87:Infinity":28,"s:88:27:88:Infinity":29,"s:89:22:92:Infinity":30,"f:90:5:90:13":6,"s:90:19:90:72":31,"b:90:19:90:38:90:38:90:72":9,"f:91:5:91:10":7,"s:91:16:91:22":32,"f:92:5:92:11":8,"s:92:20:92:38":33,"s:94:2:120:Infinity":34,"s:95:20:95:Infinity":35,"s:96:24:99:Infinity":36,"f:97:7:97:15":9,"s:97:21:97:36":37,"f:98:7:98:12":10,"s:98:18:98:24":38,"f:99:7:99:13":11,"s:99:22:99:40":39,"s:101:35:110:Infinity":40,"f:101:47:101:52":12,"s:102:24:102:Infinity":41,"s:103:24:103:Infinity":42,"s:104:6:109:Infinity":43,"b:107:23:107:43:107:43:107:Infinity":10,"s:112:27:112:Infinity":44,"f:112:35:112:43":13,"s:112:52:112:73":45,"s:114:4:119:Infinity":46,"s:122:2:122:Infinity":47}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/artifact-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/artifact-i18n.ts","statementMap":{"0":{"start":{"line":26,"column":60},"end":{"line":182,"column":null}},"1":{"start":{"line":188,"column":53},"end":{"line":220,"column":null}},"2":{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},"3":{"start":{"line":231,"column":19},"end":{"line":231,"column":null}},"4":{"start":{"line":232,"column":18},"end":{"line":232,"column":null}},"5":{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},"6":{"start":{"line":233,"column":16},"end":{"line":233,"column":null}},"7":{"start":{"line":234,"column":2},"end":{"line":236,"column":null}},"8":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"9":{"start":{"line":235,"column":22},"end":{"line":235,"column":null}},"10":{"start":{"line":237,"column":2},"end":{"line":237,"column":null}},"11":{"start":{"line":242,"column":19},"end":{"line":242,"column":null}},"12":{"start":{"line":243,"column":18},"end":{"line":243,"column":null}},"13":{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},"14":{"start":{"line":244,"column":30},"end":{"line":244,"column":null}},"15":{"start":{"line":245,"column":18},"end":{"line":245,"column":null}},"16":{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},"17":{"start":{"line":246,"column":30},"end":{"line":246,"column":null}},"18":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"19":{"start":{"line":247,"column":30},"end":{"line":247,"column":null}},"20":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"21":{"start":{"line":248,"column":70},"end":{"line":248,"column":null}},"22":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"23":{"start":{"line":249,"column":37},"end":{"line":249,"column":null}},"24":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"25":{"start":{"line":254,"column":81},"end":{"line":265,"column":null}},"26":{"start":{"line":272,"column":2},"end":{"line":276,"column":null}},"27":{"start":{"line":276,"column":29},"end":{"line":276,"column":44}},"28":{"start":{"line":281,"column":14},"end":{"line":281,"column":null}},"29":{"start":{"line":282,"column":2},"end":{"line":284,"column":null}},"30":{"start":{"line":299,"column":14},"end":{"line":299,"column":null}},"31":{"start":{"line":300,"column":14},"end":{"line":300,"column":null}},"32":{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},"33":{"start":{"line":301,"column":11},"end":{"line":301,"column":null}},"34":{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},"35":{"start":{"line":303,"column":20},"end":{"line":303,"column":null}},"36":{"start":{"line":304,"column":18},"end":{"line":304,"column":null}},"37":{"start":{"line":305,"column":20},"end":{"line":305,"column":null}},"38":{"start":{"line":306,"column":4},"end":{"line":306,"column":null}},"39":{"start":{"line":308,"column":2},"end":{"line":308,"column":null}}},"fnMap":{"0":{"name":"aliasLookupKey","decl":{"start":{"line":230,"column":9},"end":{"line":230,"column":27}},"loc":{"start":{"line":230,"column":73},"end":{"line":238,"column":null}},"line":230},"1":{"name":"artifactIcon","decl":{"start":{"line":241,"column":16},"end":{"line":241,"column":29}},"loc":{"start":{"line":241,"column":51},"end":{"line":251,"column":null}},"line":241},"2":{"name":"prettifyMarkdownTitle","decl":{"start":{"line":271,"column":16},"end":{"line":271,"column":38}},"loc":{"start":{"line":271,"column":60},"end":{"line":277,"column":null}},"line":271},"3":{"name":"(anonymous_3)","decl":{"start":{"line":276,"column":13},"end":{"line":276,"column":23}},"loc":{"start":{"line":276,"column":29},"end":{"line":276,"column":44}},"line":276},"4":{"name":"artifactTitle","decl":{"start":{"line":280,"column":16},"end":{"line":280,"column":30}},"loc":{"start":{"line":280,"column":68},"end":{"line":285,"column":null}},"line":280},"5":{"name":"localisedCatalogDescription","decl":{"start":{"line":293,"column":16},"end":{"line":293,"column":null}},"loc":{"start":{"line":298,"column":10},"end":{"line":309,"column":null}},"line":298}},"branchMap":{"0":{"loc":{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},"type":"if","locations":[{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},{"start":{},"end":{}}],"line":231},"1":{"loc":{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},"type":"if","locations":[{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},{"start":{},"end":{}}],"line":233},"2":{"loc":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"type":"if","locations":[{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},{"start":{},"end":{}}],"line":235},"3":{"loc":{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":244},"4":{"loc":{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},"type":"if","locations":[{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},{"start":{},"end":{}}],"line":246},"5":{"loc":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"type":"if","locations":[{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},{"start":{},"end":{}}],"line":247},"6":{"loc":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},{"start":{},"end":{}}],"line":248},"7":{"loc":{"start":{"line":248,"column":6},"end":{"line":248,"column":70}},"type":"binary-expr","locations":[{"start":{"line":248,"column":6},"end":{"line":248,"column":39}},{"start":{"line":248,"column":39},"end":{"line":248,"column":70}}],"line":248},"8":{"loc":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"type":"if","locations":[{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},{"start":{},"end":{}}],"line":249},"9":{"loc":{"start":{"line":282,"column":9},"end":{"line":284,"column":null}},"type":"binary-expr","locations":[{"start":{"line":282,"column":9},"end":{"line":282,"column":null}},{"start":{"line":283,"column":9},"end":{"line":283,"column":null}},{"start":{"line":284,"column":9},"end":{"line":284,"column":null}}],"line":282},"10":{"loc":{"start":{"line":299,"column":14},"end":{"line":299,"column":null}},"type":"cond-expr","locations":[{"start":{"line":299,"column":44},"end":{"line":299,"column":68}},{"start":{"line":299,"column":68},"end":{"line":299,"column":null}}],"line":299},"11":{"loc":{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},"type":"if","locations":[{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},{"start":{},"end":{}}],"line":301},"12":{"loc":{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},"type":"if","locations":[{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},{"start":{},"end":{}}],"line":302},"13":{"loc":{"start":{"line":303,"column":20},"end":{"line":303,"column":null}},"type":"binary-expr","locations":[{"start":{"line":303,"column":20},"end":{"line":303,"column":56}},{"start":{"line":303,"column":56},"end":{"line":303,"column":null}}],"line":303},"14":{"loc":{"start":{"line":305,"column":20},"end":{"line":305,"column":null}},"type":"binary-expr","locations":[{"start":{"line":305,"column":20},"end":{"line":305,"column":57}},{"start":{"line":305,"column":57},"end":{"line":305,"column":null}}],"line":305}},"s":{"0":14,"1":14,"2":412473,"3":193713,"4":218760,"5":218760,"6":218275,"7":485,"8":485,"9":485,"10":0,"11":205,"12":205,"13":205,"14":200,"15":5,"16":5,"17":0,"18":5,"19":0,"20":5,"21":0,"22":5,"23":0,"24":5,"25":14,"26":220438,"27":482412,"28":412263,"29":412263,"30":1860,"31":1860,"32":1860,"33":720,"34":1140,"35":1050,"36":1050,"37":1050,"38":1050,"39":90},"f":{"0":412473,"1":205,"2":220438,"3":482412,"4":412263,"5":1860},"b":{"0":[193713,218760],"1":[218275,485],"2":[485,0],"3":[200,5],"4":[0,5],"5":[0,5],"6":[0,5],"7":[5,0],"8":[0,5],"9":[412263,218265,218265],"10":[660,1200],"11":[720,1140],"12":[1050,90],"13":[1050,0],"14":[1050,0]},"meta":{"lastBranch":15,"lastFunction":6,"lastStatement":40,"seen":{"s:26:60:182:Infinity":0,"s:188:53:220:Infinity":1,"f:230:9:230:27":0,"b:231:2:231:Infinity:undefined:undefined:undefined:undefined":0,"s:231:2:231:Infinity":2,"s:231:19:231:Infinity":3,"s:232:18:232:Infinity":4,"b:233:2:233:Infinity:undefined:undefined:undefined:undefined":1,"s:233:2:233:Infinity":5,"s:233:16:233:Infinity":6,"s:234:2:236:Infinity":7,"b:235:4:235:Infinity:undefined:undefined:undefined:undefined":2,"s:235:4:235:Infinity":8,"s:235:22:235:Infinity":9,"s:237:2:237:Infinity":10,"f:241:16:241:29":1,"s:242:19:242:Infinity":11,"s:243:18:243:Infinity":12,"b:244:2:244:Infinity:undefined:undefined:undefined:undefined":3,"s:244:2:244:Infinity":13,"s:244:30:244:Infinity":14,"s:245:18:245:Infinity":15,"b:246:2:246:Infinity:undefined:undefined:undefined:undefined":4,"s:246:2:246:Infinity":16,"s:246:30:246:Infinity":17,"b:247:2:247:Infinity:undefined:undefined:undefined:undefined":5,"s:247:2:247:Infinity":18,"s:247:30:247:Infinity":19,"b:248:2:248:Infinity:undefined:undefined:undefined:undefined":6,"s:248:2:248:Infinity":20,"b:248:6:248:39:248:39:248:70":7,"s:248:70:248:Infinity":21,"b:249:2:249:Infinity:undefined:undefined:undefined:undefined":8,"s:249:2:249:Infinity":22,"s:249:37:249:Infinity":23,"s:250:2:250:Infinity":24,"s:254:81:265:Infinity":25,"f:271:16:271:38":2,"s:272:2:276:Infinity":26,"f:276:13:276:23":3,"s:276:29:276:44":27,"f:280:16:280:30":4,"s:281:14:281:Infinity":28,"s:282:2:284:Infinity":29,"b:282:9:282:Infinity:283:9:283:Infinity:284:9:284:Infinity":9,"f:293:16:293:Infinity":5,"s:299:14:299:Infinity":30,"b:299:44:299:68:299:68:299:Infinity":10,"s:300:14:300:Infinity":31,"b:301:2:301:Infinity:undefined:undefined:undefined:undefined":11,"s:301:2:301:Infinity":32,"s:301:11:301:Infinity":33,"b:302:2:307:Infinity:undefined:undefined:undefined:undefined":12,"s:302:2:307:Infinity":34,"s:303:20:303:Infinity":35,"b:303:20:303:56:303:56:303:Infinity":13,"s:304:18:304:Infinity":36,"s:305:20:305:Infinity":37,"b:305:20:305:57:305:57:305:Infinity":14,"s:306:4:306:Infinity":38,"s:308:2:308:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/methodology-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/methodology-i18n.ts","statementMap":{"0":{"start":{"line":20,"column":87},"end":{"line":40,"column":null}},"1":{"start":{"line":43,"column":62},"end":{"line":348,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":14,"1":14},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:20:87:40:Infinity":0,"s:43:62:348:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/page-translations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/page-translations.ts","statementMap":{"0":{"start":{"line":63,"column":65},"end":{"line":540,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":2},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:63:65:540:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/stream-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/stream-i18n.ts","statementMap":{"0":{"start":{"line":20,"column":82},"end":{"line":33,"column":null}},"1":{"start":{"line":43,"column":74},"end":{"line":109,"column":null}},"2":{"start":{"line":112,"column":74},"end":{"line":321,"column":null}},"3":{"start":{"line":324,"column":60},"end":{"line":339,"column":null}},"4":{"start":{"line":343,"column":66},"end":{"line":358,"column":null}},"5":{"start":{"line":371,"column":2},"end":{"line":373,"column":null}},"6":{"start":{"line":373,"column":29},"end":{"line":373,"column":44}},"7":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"8":{"start":{"line":382,"column":25},"end":{"line":382,"column":null}},"9":{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},"10":{"start":{"line":383,"column":28},"end":{"line":383,"column":null}},"11":{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},"12":{"start":{"line":384,"column":36},"end":{"line":384,"column":null}},"13":{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},"14":{"start":{"line":385,"column":35},"end":{"line":385,"column":null}},"15":{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},"16":{"start":{"line":386,"column":34},"end":{"line":386,"column":null}},"17":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"18":{"start":{"line":387,"column":35},"end":{"line":387,"column":null}},"19":{"start":{"line":388,"column":2},"end":{"line":388,"column":null}},"20":{"start":{"line":393,"column":14},"end":{"line":393,"column":null}},"21":{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},"22":{"start":{"line":394,"column":11},"end":{"line":394,"column":null}},"23":{"start":{"line":395,"column":16},"end":{"line":395,"column":null}},"24":{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},"25":{"start":{"line":397,"column":17},"end":{"line":397,"column":null}},"26":{"start":{"line":398,"column":4},"end":{"line":398,"column":null}},"27":{"start":{"line":400,"column":2},"end":{"line":400,"column":null}},"28":{"start":{"line":405,"column":14},"end":{"line":405,"column":null}},"29":{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},"30":{"start":{"line":406,"column":11},"end":{"line":406,"column":null}},"31":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"32":{"start":{"line":407,"column":36},"end":{"line":407,"column":null}},"33":{"start":{"line":408,"column":18},"end":{"line":408,"column":null}},"34":{"start":{"line":409,"column":2},"end":{"line":409,"column":null}}},"fnMap":{"0":{"name":"prettifyStream","decl":{"start":{"line":370,"column":16},"end":{"line":370,"column":31}},"loc":{"start":{"line":370,"column":53},"end":{"line":374,"column":null}},"line":370},"1":{"name":"(anonymous_1)","decl":{"start":{"line":373,"column":13},"end":{"line":373,"column":23}},"loc":{"start":{"line":373,"column":29},"end":{"line":373,"column":44}},"line":373},"2":{"name":"streamIcon","decl":{"start":{"line":381,"column":16},"end":{"line":381,"column":27}},"loc":{"start":{"line":381,"column":49},"end":{"line":389,"column":null}},"line":381},"3":{"name":"streamDisplayName","decl":{"start":{"line":392,"column":16},"end":{"line":392,"column":34}},"loc":{"start":{"line":392,"column":72},"end":{"line":401,"column":null}},"line":392},"4":{"name":"streamDescription","decl":{"start":{"line":404,"column":16},"end":{"line":404,"column":34}},"loc":{"start":{"line":404,"column":72},"end":{"line":410,"column":null}},"line":404}},"branchMap":{"0":{"loc":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"type":"if","locations":[{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},{"start":{},"end":{}}],"line":382},"1":{"loc":{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},"type":"if","locations":[{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},{"start":{},"end":{}}],"line":383},"2":{"loc":{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},"type":"if","locations":[{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},{"start":{},"end":{}}],"line":384},"3":{"loc":{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},"type":"if","locations":[{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},{"start":{},"end":{}}],"line":385},"4":{"loc":{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},"type":"if","locations":[{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},{"start":{},"end":{}}],"line":386},"5":{"loc":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"type":"if","locations":[{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},{"start":{},"end":{}}],"line":387},"6":{"loc":{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},"type":"if","locations":[{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},{"start":{},"end":{}}],"line":394},"7":{"loc":{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},"type":"if","locations":[{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},{"start":{},"end":{}}],"line":396},"8":{"loc":{"start":{"line":397,"column":17},"end":{"line":397,"column":null}},"type":"binary-expr","locations":[{"start":{"line":397,"column":17},"end":{"line":397,"column":62}},{"start":{"line":397,"column":62},"end":{"line":397,"column":null}}],"line":397},"9":{"loc":{"start":{"line":398,"column":14},"end":{"line":398,"column":92}},"type":"cond-expr","locations":[{"start":{"line":398,"column":30},"end":{"line":398,"column":43}},{"start":{"line":398,"column":43},"end":{"line":398,"column":92}}],"line":398},"10":{"loc":{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},"type":"if","locations":[{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},{"start":{},"end":{}}],"line":406},"11":{"loc":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"type":"if","locations":[{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},{"start":{},"end":{}}],"line":407},"12":{"loc":{"start":{"line":408,"column":18},"end":{"line":408,"column":null}},"type":"binary-expr","locations":[{"start":{"line":408,"column":18},"end":{"line":408,"column":52}},{"start":{"line":408,"column":52},"end":{"line":408,"column":null}}],"line":408}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":2673,"6":5528,"7":11102,"8":7801,"9":3301,"10":660,"11":2641,"12":1710,"13":931,"14":0,"15":931,"16":0,"17":931,"18":90,"19":841,"20":12031,"21":12031,"22":8460,"23":3571,"24":3571,"25":900,"26":900,"27":2671,"28":11268,"29":11268,"30":8628,"31":2640,"32":1710,"33":930,"34":11268},"f":{"0":2673,"1":5528,"2":11102,"3":12031,"4":11268},"b":{"0":[7801,3301],"1":[660,2641],"2":[1710,931],"3":[0,931],"4":[0,931],"5":[90,841],"6":[8460,3571],"7":[900,2671],"8":[900,0],"9":[90,810],"10":[8628,2640],"11":[1710,930],"12":[930,0]},"meta":{"lastBranch":13,"lastFunction":5,"lastStatement":35,"seen":{"s:20:82:33:Infinity":0,"s:43:74:109:Infinity":1,"s:112:74:321:Infinity":2,"s:324:60:339:Infinity":3,"s:343:66:358:Infinity":4,"f:370:16:370:31":0,"s:371:2:373:Infinity":5,"f:373:13:373:23":1,"s:373:29:373:44":6,"f:381:16:381:27":2,"b:382:2:382:Infinity:undefined:undefined:undefined:undefined":0,"s:382:2:382:Infinity":7,"s:382:25:382:Infinity":8,"b:383:2:383:Infinity:undefined:undefined:undefined:undefined":1,"s:383:2:383:Infinity":9,"s:383:28:383:Infinity":10,"b:384:2:384:Infinity:undefined:undefined:undefined:undefined":2,"s:384:2:384:Infinity":11,"s:384:36:384:Infinity":12,"b:385:2:385:Infinity:undefined:undefined:undefined:undefined":3,"s:385:2:385:Infinity":13,"s:385:35:385:Infinity":14,"b:386:2:386:Infinity:undefined:undefined:undefined:undefined":4,"s:386:2:386:Infinity":15,"s:386:34:386:Infinity":16,"b:387:2:387:Infinity:undefined:undefined:undefined:undefined":5,"s:387:2:387:Infinity":17,"s:387:35:387:Infinity":18,"s:388:2:388:Infinity":19,"f:392:16:392:34":3,"s:393:14:393:Infinity":20,"b:394:2:394:Infinity:undefined:undefined:undefined:undefined":6,"s:394:2:394:Infinity":21,"s:394:11:394:Infinity":22,"s:395:16:395:Infinity":23,"b:396:2:399:Infinity:undefined:undefined:undefined:undefined":7,"s:396:2:399:Infinity":24,"s:397:17:397:Infinity":25,"b:397:17:397:62:397:62:397:Infinity":8,"s:398:4:398:Infinity":26,"b:398:30:398:43:398:43:398:92":9,"s:400:2:400:Infinity":27,"f:404:16:404:34":4,"s:405:14:405:Infinity":28,"b:406:2:406:Infinity:undefined:undefined:undefined:undefined":10,"s:406:2:406:Infinity":29,"s:406:11:406:Infinity":30,"b:407:2:407:Infinity:undefined:undefined:undefined:undefined":11,"s:407:2:407:Infinity":31,"s:407:36:407:Infinity":32,"s:408:18:408:Infinity":33,"b:408:18:408:52:408:52:408:Infinity":12,"s:409:2:409:Infinity":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/daily-day.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/daily-day.ts","statementMap":{"0":{"start":{"line":37,"column":14},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"2":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"3":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"4":{"start":{"line":48,"column":33},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"6":{"start":{"line":49,"column":36},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"8":{"start":{"line":50,"column":29},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"10":{"start":{"line":51,"column":28},"end":{"line":51,"column":null}},"11":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"12":{"start":{"line":61,"column":22},"end":{"line":86,"column":null}},"13":{"start":{"line":62,"column":24},"end":{"line":62,"column":null}},"14":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"15":{"start":{"line":64,"column":26},"end":{"line":76,"column":null}},"16":{"start":{"line":73,"column":25},"end":{"line":73,"column":385}},"17":{"start":{"line":77,"column":4},"end":{"line":84,"column":null}},"18":{"start":{"line":88,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"artifactBaseName","decl":{"start":{"line":36,"column":16},"end":{"line":36,"column":33}},"loc":{"start":{"line":36,"column":55},"end":{"line":39,"column":null}},"line":36},"1":{"name":"artifactIcon","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":29}},"loc":{"start":{"line":46,"column":51},"end":{"line":53,"column":null}},"line":46},"2":{"name":"renderDailyDay","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":31}},"loc":{"start":{"line":60,"column":89},"end":{"line":101,"column":null}},"line":60},"3":{"name":"(anonymous_3)","decl":{"start":{"line":61,"column":34},"end":{"line":61,"column":39}},"loc":{"start":{"line":61,"column":45},"end":{"line":86,"column":3}},"line":61},"4":{"name":"(anonymous_4)","decl":{"start":{"line":73,"column":14},"end":{"line":73,"column":19}},"loc":{"start":{"line":73,"column":25},"end":{"line":73,"column":385}},"line":73}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":9},"end":{"line":38,"column":null}},"type":"cond-expr","locations":[{"start":{"line":38,"column":20},"end":{"line":38,"column":42}},{"start":{"line":38,"column":42},"end":{"line":38,"column":null}}],"line":38},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"3":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"4":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"5":{"loc":{"start":{"line":64,"column":26},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":8},"end":{"line":76,"column":null}},{"start":{"line":76,"column":8},"end":{"line":76,"column":null}}],"line":64}},"s":{"0":818470,"1":818470,"2":409237,"3":409237,"4":173012,"5":236225,"6":0,"7":236225,"8":48391,"9":187834,"10":0,"11":187834,"12":1920,"13":11100,"14":11100,"15":11100,"16":409230,"17":11100,"18":1920},"f":{"0":818470,"1":409237,"2":1920,"3":11100,"4":409230},"b":{"0":[247682,570788],"1":[173012,236225],"2":[0,236225],"3":[48391,187834],"4":[0,187834],"5":[11100,0]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":19,"seen":{"f:36:16:36:33":0,"s:37:14:37:Infinity":0,"s:38:2:38:Infinity":1,"b:38:20:38:42:38:42:38:Infinity":0,"f:46:16:46:29":1,"s:47:15:47:Infinity":2,"b:48:2:48:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:48:Infinity":3,"s:48:33:48:Infinity":4,"b:49:2:49:Infinity:undefined:undefined:undefined:undefined":2,"s:49:2:49:Infinity":5,"s:49:36:49:Infinity":6,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":3,"s:50:2:50:Infinity":7,"s:50:29:50:Infinity":8,"b:51:2:51:Infinity:undefined:undefined:undefined:undefined":4,"s:51:2:51:Infinity":9,"s:51:28:51:Infinity":10,"s:52:2:52:Infinity":11,"f:60:16:60:31":2,"s:61:22:86:Infinity":12,"f:61:34:61:39":3,"s:62:24:62:Infinity":13,"s:63:17:63:Infinity":14,"s:64:26:76:Infinity":15,"b:65:8:76:Infinity:76:8:76:Infinity":5,"f:73:14:73:19":4,"s:73:25:73:385":16,"s:77:4:84:Infinity":17,"s:88:2:98:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/template-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/template-i18n.ts","statementMap":{"0":{"start":{"line":22,"column":84},"end":{"line":58,"column":null}},"1":{"start":{"line":62,"column":59},"end":{"line":255,"column":null}},"2":{"start":{"line":259,"column":68},"end":{"line":274,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":14,"1":14,"2":14},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":3,"seen":{"s:22:84:58:Infinity":0,"s:62:59:255:Infinity":1,"s:259:68:274:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/style.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/style.ts","statementMap":{"0":{"start":{"line":18,"column":38},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:38:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/page.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/page.ts","statementMap":{"0":{"start":{"line":37,"column":17},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":20},"end":{"line":38,"column":null}},"2":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"3":{"start":{"line":41,"column":18},"end":{"line":41,"column":null}},"4":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":26},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":22},"end":{"line":46,"column":null}},"8":{"start":{"line":48,"column":39},"end":{"line":50,"column":null}},"9":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"10":{"start":{"line":63,"column":12},"end":{"line":63,"column":null}},"11":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"12":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"13":{"start":{"line":66,"column":20},"end":{"line":66,"column":null}},"14":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"15":{"start":{"line":69,"column":24},"end":{"line":69,"column":null}},"16":{"start":{"line":70,"column":20},"end":{"line":70,"column":null}},"17":{"start":{"line":71,"column":15},"end":{"line":71,"column":32}},"18":{"start":{"line":72,"column":25},"end":{"line":72,"column":null}},"19":{"start":{"line":72,"column":47},"end":{"line":72,"column":69}},"20":{"start":{"line":74,"column":17},"end":{"line":74,"column":null}},"21":{"start":{"line":75,"column":21},"end":{"line":75,"column":null}},"22":{"start":{"line":76,"column":20},"end":{"line":76,"column":null}},"23":{"start":{"line":78,"column":31},"end":{"line":78,"column":null}},"24":{"start":{"line":79,"column":28},"end":{"line":79,"column":null}},"25":{"start":{"line":80,"column":25},"end":{"line":80,"column":null}},"26":{"start":{"line":80,"column":47},"end":{"line":80,"column":73}},"27":{"start":{"line":81,"column":24},"end":{"line":81,"column":null}},"28":{"start":{"line":81,"column":45},"end":{"line":81,"column":71}},"29":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"30":{"start":{"line":84,"column":19},"end":{"line":84,"column":null}},"31":{"start":{"line":86,"column":27},"end":{"line":113,"column":null}},"32":{"start":{"line":115,"column":29},"end":{"line":124,"column":null}},"33":{"start":{"line":121,"column":47},"end":{"line":123,"column":6}},"34":{"start":{"line":126,"column":32},"end":{"line":135,"column":null}},"35":{"start":{"line":132,"column":50},"end":{"line":134,"column":6}},"36":{"start":{"line":136,"column":28},"end":{"line":145,"column":null}},"37":{"start":{"line":142,"column":48},"end":{"line":144,"column":6}},"38":{"start":{"line":147,"column":23},"end":{"line":154,"column":null}},"39":{"start":{"line":156,"column":25},"end":{"line":162,"column":null}},"40":{"start":{"line":163,"column":20},"end":{"line":172,"column":null}},"41":{"start":{"line":174,"column":28},"end":{"line":179,"column":null}},"42":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"43":{"start":{"line":180,"column":26},"end":{"line":180,"column":null}},"44":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"45":{"start":{"line":181,"column":29},"end":{"line":181,"column":null}},"46":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"47":{"start":{"line":182,"column":25},"end":{"line":182,"column":null}},"48":{"start":{"line":191,"column":21},"end":{"line":193,"column":null}},"49":{"start":{"line":192,"column":41},"end":{"line":192,"column":49}},"50":{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},"51":{"start":{"line":195,"column":4},"end":{"line":195,"column":null}},"52":{"start":{"line":195,"column":35},"end":{"line":195,"column":null}},"53":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"54":{"start":{"line":196,"column":33},"end":{"line":196,"column":null}},"55":{"start":{"line":198,"column":29},"end":{"line":198,"column":null}},"56":{"start":{"line":200,"column":19},"end":{"line":200,"column":null}},"57":{"start":{"line":202,"column":64},"end":{"line":202,"column":null}},"58":{"start":{"line":203,"column":2},"end":{"line":205,"column":null}},"59":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"60":{"start":{"line":207,"column":17},"end":{"line":228,"column":null}},"61":{"start":{"line":230,"column":15},"end":{"line":305,"column":null}},"62":{"start":{"line":302,"column":22},"end":{"line":305,"column":24}},"63":{"start":{"line":309,"column":2},"end":{"line":312,"column":null}}},"fnMap":{"0":{"name":"hreflangCodeOf","decl":{"start":{"line":53,"column":9},"end":{"line":53,"column":24}},"loc":{"start":{"line":53,"column":48},"end":{"line":55,"column":null}},"line":53},"1":{"name":"generatePoliticalIntelligenceHtml","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":50}},"loc":{"start":{"line":62,"column":74},"end":{"line":313,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":72,"column":30},"end":{"line":72,"column":38}},"loc":{"start":{"line":72,"column":47},"end":{"line":72,"column":69}},"line":72},"3":{"name":"(anonymous_3)","decl":{"start":{"line":80,"column":36},"end":{"line":80,"column":41}},"loc":{"start":{"line":80,"column":47},"end":{"line":80,"column":73}},"line":80},"4":{"name":"(anonymous_4)","decl":{"start":{"line":81,"column":34},"end":{"line":81,"column":39}},"loc":{"start":{"line":81,"column":45},"end":{"line":81,"column":71}},"line":81},"5":{"name":"(anonymous_5)","decl":{"start":{"line":121,"column":32},"end":{"line":121,"column":37}},"loc":{"start":{"line":121,"column":47},"end":{"line":123,"column":6}},"line":121},"6":{"name":"(anonymous_6)","decl":{"start":{"line":132,"column":35},"end":{"line":132,"column":40}},"loc":{"start":{"line":132,"column":50},"end":{"line":134,"column":6}},"line":132},"7":{"name":"(anonymous_7)","decl":{"start":{"line":142,"column":31},"end":{"line":142,"column":36}},"loc":{"start":{"line":142,"column":48},"end":{"line":144,"column":6}},"line":142},"8":{"name":"(anonymous_8)","decl":{"start":{"line":192,"column":30},"end":{"line":192,"column":35}},"loc":{"start":{"line":192,"column":41},"end":{"line":192,"column":49}},"line":192},"9":{"name":"(anonymous_9)","decl":{"start":{"line":302,"column":11},"end":{"line":302,"column":16}},"loc":{"start":{"line":302,"column":22},"end":{"line":305,"column":24}},"line":302}},"branchMap":{"0":{"loc":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":31},"end":{"line":65,"column":63}},{"start":{"line":65,"column":63},"end":{"line":65,"column":null}}],"line":65},"1":{"loc":{"start":{"line":66,"column":20},"end":{"line":66,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":47}},{"start":{"line":66,"column":47},"end":{"line":66,"column":null}}],"line":66},"2":{"loc":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":34},"end":{"line":67,"column":51}},{"start":{"line":67,"column":51},"end":{"line":67,"column":null}}],"line":67},"3":{"loc":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"type":"binary-expr","locations":[{"start":{"line":83,"column":21},"end":{"line":83,"column":38}},{"start":{"line":83,"column":38},"end":{"line":83,"column":null}}],"line":83},"4":{"loc":{"start":{"line":115,"column":29},"end":{"line":124,"column":null}},"type":"cond-expr","locations":[{"start":{"line":115,"column":53},"end":{"line":124,"column":6}},{"start":{"line":124,"column":6},"end":{"line":124,"column":null}}],"line":115},"5":{"loc":{"start":{"line":126,"column":32},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":126,"column":59},"end":{"line":135,"column":6}},{"start":{"line":135,"column":6},"end":{"line":135,"column":null}}],"line":126},"6":{"loc":{"start":{"line":136,"column":28},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":51},"end":{"line":145,"column":6}},{"start":{"line":145,"column":6},"end":{"line":145,"column":null}}],"line":136},"7":{"loc":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},{"start":{},"end":{}}],"line":180},"8":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"9":{"loc":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"10":{"loc":{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":194},"11":{"loc":{"start":{"line":204,"column":28},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":204,"column":41},"end":{"line":204,"column":73}},{"start":{"line":204,"column":73},"end":{"line":204,"column":null}}],"line":204},"12":{"loc":{"start":{"line":284,"column":2},"end":{"line":292,"column":null}},"type":"cond-expr","locations":[{"start":{"line":284,"column":25},"end":{"line":292,"column":null}},{"start":{"line":292,"column":26},"end":{"line":292,"column":null}}],"line":284}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":30,"10":30,"11":30,"12":30,"13":30,"14":30,"15":30,"16":30,"17":30,"18":30,"19":1920,"20":30,"21":30,"22":30,"23":30,"24":30,"25":30,"26":420,"27":30,"28":1500,"29":30,"30":30,"31":30,"32":30,"33":420,"34":30,"35":660,"36":30,"37":1200,"38":30,"39":30,"40":30,"41":30,"42":30,"43":30,"44":30,"45":30,"46":30,"47":30,"48":30,"49":232,"50":30,"51":3,"52":66,"53":3,"54":120,"55":30,"56":30,"57":30,"58":30,"59":420,"60":30,"61":30,"62":150,"63":30},"f":{"0":30,"1":30,"2":1920,"3":420,"4":1500,"5":420,"6":660,"7":1200,"8":232,"9":150},"b":{"0":[3,27],"1":[3,27],"2":[3,27],"3":[30,0],"4":[30,0],"5":[30,0],"6":[30,0],"7":[30,0],"8":[30,0],"9":[30,0],"10":[3,27],"11":[30,390],"12":[30,0]},"meta":{"lastBranch":13,"lastFunction":10,"lastStatement":64,"seen":{"s:37:17:37:Infinity":0,"s:38:20:38:Infinity":1,"s:40:19:40:Infinity":2,"s:41:18:41:Infinity":3,"s:43:17:43:Infinity":4,"s:44:21:44:Infinity":5,"s:45:26:45:Infinity":6,"s:46:22:46:Infinity":7,"s:48:39:50:Infinity":8,"f:53:9:53:24":0,"s:54:2:54:Infinity":9,"f:62:16:62:50":1,"s:63:12:63:Infinity":10,"s:64:20:64:Infinity":11,"s:65:19:65:Infinity":12,"b:65:31:65:63:65:63:65:Infinity":0,"s:66:20:66:Infinity":13,"b:66:32:66:47:66:47:66:Infinity":1,"s:67:22:67:Infinity":14,"b:67:34:67:51:67:51:67:Infinity":2,"s:69:24:69:Infinity":15,"s:70:20:70:Infinity":16,"s:71:15:71:32":17,"s:72:25:72:Infinity":18,"f:72:30:72:38":2,"s:72:47:72:69":19,"s:74:17:74:Infinity":20,"s:75:21:75:Infinity":21,"s:76:20:76:Infinity":22,"s:78:31:78:Infinity":23,"s:79:28:79:Infinity":24,"s:80:25:80:Infinity":25,"f:80:36:80:41":3,"s:80:47:80:73":26,"s:81:24:81:Infinity":27,"f:81:34:81:39":4,"s:81:45:81:71":28,"s:83:21:83:Infinity":29,"b:83:21:83:38:83:38:83:Infinity":3,"s:84:19:84:Infinity":30,"s:86:27:113:Infinity":31,"s:115:29:124:Infinity":32,"b:115:53:124:6:124:6:124:Infinity":4,"f:121:32:121:37":5,"s:121:47:123:6":33,"s:126:32:135:Infinity":34,"b:126:59:135:6:135:6:135:Infinity":5,"f:132:35:132:40":6,"s:132:50:134:6":35,"s:136:28:145:Infinity":36,"b:136:51:145:6:145:6:145:Infinity":6,"f:142:31:142:36":7,"s:142:48:144:6":37,"s:147:23:154:Infinity":38,"s:156:25:162:Infinity":39,"s:163:20:172:Infinity":40,"s:174:28:179:Infinity":41,"b:180:2:180:Infinity:undefined:undefined:undefined:undefined":7,"s:180:2:180:Infinity":42,"s:180:26:180:Infinity":43,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":8,"s:181:2:181:Infinity":44,"s:181:29:181:Infinity":45,"b:182:2:182:Infinity:undefined:undefined:undefined:undefined":9,"s:182:2:182:Infinity":46,"s:182:25:182:Infinity":47,"s:191:21:193:Infinity":48,"f:192:30:192:35":8,"s:192:41:192:49":49,"b:194:2:197:Infinity:undefined:undefined:undefined:undefined":10,"s:194:2:197:Infinity":50,"s:195:4:195:Infinity":51,"s:195:35:195:Infinity":52,"s:196:4:196:Infinity":53,"s:196:33:196:Infinity":54,"s:198:29:198:Infinity":55,"s:200:19:200:Infinity":56,"s:202:64:202:Infinity":57,"s:203:2:205:Infinity":58,"s:204:4:204:Infinity":59,"b:204:41:204:73:204:73:204:Infinity":11,"s:207:17:228:Infinity":60,"s:230:15:305:Infinity":61,"b:284:25:292:Infinity:292:26:292:Infinity":12,"f:302:11:302:16":9,"s:302:22:305:24":62,"s:309:2:312:Infinity":63}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/polling-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/polling-fetch.ts","statementMap":{"0":{"start":{"line":19,"column":27},"end":{"line":19,"column":null}},"1":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"2":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"3":{"start":{"line":65,"column":38},"end":{"line":65,"column":null}},"4":{"start":{"line":70,"column":42},"end":{"line":70,"column":null}},"5":{"start":{"line":71,"column":79},"end":{"line":81,"column":null}},"6":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"7":{"start":{"line":84,"column":16},"end":{"line":84,"column":null}},"8":{"start":{"line":85,"column":17},"end":{"line":85,"column":null}},"9":{"start":{"line":86,"column":15},"end":{"line":86,"column":null}},"10":{"start":{"line":87,"column":22},"end":{"line":87,"column":null}},"11":{"start":{"line":88,"column":16},"end":{"line":88,"column":null}},"12":{"start":{"line":89,"column":17},"end":{"line":89,"column":null}},"13":{"start":{"line":90,"column":23},"end":{"line":90,"column":null}},"14":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"15":{"start":{"line":97,"column":19},"end":{"line":100,"column":null}},"16":{"start":{"line":101,"column":2},"end":{"line":108,"column":null}},"17":{"start":{"line":102,"column":18},"end":{"line":102,"column":null}},"18":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"19":{"start":{"line":103,"column":21},"end":{"line":103,"column":null}},"20":{"start":{"line":104,"column":18},"end":{"line":104,"column":null}},"21":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"22":{"start":{"line":106,"column":6},"end":{"line":106,"column":null}},"23":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"24":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"25":{"start":{"line":125,"column":2},"end":{"line":135,"column":null}},"26":{"start":{"line":126,"column":17},"end":{"line":126,"column":null}},"27":{"start":{"line":127,"column":18},"end":{"line":127,"column":null}},"28":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"29":{"start":{"line":128,"column":15},"end":{"line":128,"column":null}},"30":{"start":{"line":129,"column":21},"end":{"line":129,"column":null}},"31":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"32":{"start":{"line":130,"column":59},"end":{"line":130,"column":null}},"33":{"start":{"line":131,"column":21},"end":{"line":131,"column":null}},"34":{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},"35":{"start":{"line":132,"column":32},"end":{"line":132,"column":null}},"36":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"37":{"start":{"line":133,"column":36},"end":{"line":133,"column":null}},"38":{"start":{"line":134,"column":4},"end":{"line":134,"column":null}},"39":{"start":{"line":136,"column":20},"end":{"line":136,"column":null}},"40":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"41":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"42":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"43":{"start":{"line":149,"column":21},"end":{"line":149,"column":null}},"44":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"45":{"start":{"line":151,"column":15},"end":{"line":151,"column":null}},"46":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"47":{"start":{"line":153,"column":21},"end":{"line":153,"column":null}},"48":{"start":{"line":154,"column":25},"end":{"line":154,"column":null}},"49":{"start":{"line":155,"column":26},"end":{"line":155,"column":null}},"50":{"start":{"line":156,"column":21},"end":{"line":156,"column":null}},"51":{"start":{"line":158,"column":54},"end":{"line":158,"column":null}},"52":{"start":{"line":159,"column":2},"end":{"line":164,"column":null}},"53":{"start":{"line":160,"column":18},"end":{"line":160,"column":null}},"54":{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},"55":{"start":{"line":162,"column":6},"end":{"line":162,"column":null}},"56":{"start":{"line":166,"column":27},"end":{"line":166,"column":null}},"57":{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},"58":{"start":{"line":168,"column":4},"end":{"line":178,"column":null}},"59":{"start":{"line":181,"column":2},"end":{"line":192,"column":null}},"60":{"start":{"line":196,"column":20},"end":{"line":196,"column":null}},"61":{"start":{"line":196,"column":43},"end":{"line":196,"column":63}},"62":{"start":{"line":197,"column":71},"end":{"line":197,"column":null}},"63":{"start":{"line":198,"column":2},"end":{"line":208,"column":null}},"64":{"start":{"line":199,"column":19},"end":{"line":201,"column":null}},"65":{"start":{"line":200,"column":21},"end":{"line":200,"column":44}},"66":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"67":{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},"68":{"start":{"line":202,"column":29},"end":{"line":202,"column":null}},"69":{"start":{"line":203,"column":16},"end":{"line":203,"column":null}},"70":{"start":{"line":203,"column":46},"end":{"line":203,"column":59}},"71":{"start":{"line":204,"column":4},"end":{"line":207,"column":null}},"72":{"start":{"line":209,"column":2},"end":{"line":212,"column":null}},"73":{"start":{"line":220,"column":21},"end":{"line":220,"column":null}},"74":{"start":{"line":221,"column":16},"end":{"line":221,"column":null}},"75":{"start":{"line":221,"column":33},"end":{"line":221,"column":53}},"76":{"start":{"line":222,"column":2},"end":{"line":236,"column":null}},"77":{"start":{"line":223,"column":21},"end":{"line":229,"column":null}},"78":{"start":{"line":232,"column":17},"end":{"line":232,"column":null}},"79":{"start":{"line":233,"column":4},"end":{"line":233,"column":null}},"80":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"81":{"start":{"line":240,"column":20},"end":{"line":240,"column":null}},"82":{"start":{"line":241,"column":18},"end":{"line":241,"column":null}},"83":{"start":{"line":242,"column":20},"end":{"line":242,"column":null}},"84":{"start":{"line":244,"column":16},"end":{"line":297,"column":null}},"85":{"start":{"line":246,"column":6},"end":{"line":295,"column":null}},"86":{"start":{"line":247,"column":41},"end":{"line":247,"column":null}},"87":{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},"88":{"start":{"line":249,"column":10},"end":{"line":256,"column":null}},"89":{"start":{"line":261,"column":28},"end":{"line":261,"column":null}},"90":{"start":{"line":262,"column":29},"end":{"line":262,"column":null}},"91":{"start":{"line":263,"column":32},"end":{"line":263,"column":null}},"92":{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},"93":{"start":{"line":265,"column":39},"end":{"line":265,"column":null}},"94":{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},"95":{"start":{"line":267,"column":12},"end":{"line":267,"column":null}},"96":{"start":{"line":268,"column":71},"end":{"line":268,"column":null}},"97":{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},"98":{"start":{"line":270,"column":14},"end":{"line":270,"column":null}},"99":{"start":{"line":271,"column":14},"end":{"line":271,"column":null}},"100":{"start":{"line":275,"column":19},"end":{"line":275,"column":null}},"101":{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},"102":{"start":{"line":277,"column":30},"end":{"line":277,"column":null}},"103":{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},"104":{"start":{"line":279,"column":71},"end":{"line":279,"column":null}},"105":{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},"106":{"start":{"line":281,"column":14},"end":{"line":281,"column":null}},"107":{"start":{"line":285,"column":8},"end":{"line":285,"column":null}},"108":{"start":{"line":287,"column":8},"end":{"line":294,"column":null}},"109":{"start":{"line":299,"column":2},"end":{"line":305,"column":null}},"110":{"start":{"line":309,"column":2},"end":{"line":309,"column":null}},"111":{"start":{"line":310,"column":2},"end":{"line":310,"column":null}},"112":{"start":{"line":311,"column":2},"end":{"line":311,"column":null}},"113":{"start":{"line":315,"column":15},"end":{"line":315,"column":null}},"114":{"start":{"line":316,"column":16},"end":{"line":316,"column":null}},"115":{"start":{"line":317,"column":2},"end":{"line":327,"column":null}},"116":{"start":{"line":317,"column":15},"end":{"line":317,"column":18}},"117":{"start":{"line":318,"column":18},"end":{"line":318,"column":null}},"118":{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},"119":{"start":{"line":320,"column":6},"end":{"line":320,"column":null}},"120":{"start":{"line":321,"column":6},"end":{"line":321,"column":null}},"121":{"start":{"line":322,"column":6},"end":{"line":322,"column":null}},"122":{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},"123":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"124":{"start":{"line":328,"column":2},"end":{"line":328,"column":null}},"125":{"start":{"line":332,"column":15},"end":{"line":332,"column":null}},"126":{"start":{"line":333,"column":18},"end":{"line":333,"column":null}},"127":{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},"128":{"start":{"line":335,"column":4},"end":{"line":335,"column":null}},"129":{"start":{"line":337,"column":2},"end":{"line":337,"column":null}},"130":{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},"131":{"start":{"line":341,"column":2},"end":{"line":344,"column":null}},"132":{"start":{"line":342,"column":4},"end":{"line":342,"column":null}},"133":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}}},"fnMap":{"0":{"name":"stripHtml","decl":{"start":{"line":92,"column":9},"end":{"line":92,"column":19}},"loc":{"start":{"line":92,"column":41},"end":{"line":94,"column":null}},"line":92},"1":{"name":"extractNumericPartyShare","decl":{"start":{"line":96,"column":9},"end":{"line":96,"column":34}},"loc":{"start":{"line":96,"column":90},"end":{"line":110,"column":null}},"line":96},"2":{"name":"isArchiveRootUrl","decl":{"start":{"line":112,"column":9},"end":{"line":112,"column":26}},"loc":{"start":{"line":112,"column":48},"end":{"line":119,"column":null}},"line":112},"3":{"name":"findFollowUpPollingUrl","decl":{"start":{"line":121,"column":9},"end":{"line":121,"column":32}},"loc":{"start":{"line":121,"column":80},"end":{"line":141,"column":null}},"line":121},"4":{"name":"extractPollingWaveFromHtml","decl":{"start":{"line":143,"column":16},"end":{"line":143,"column":null}},"loc":{"start":{"line":148,"column":15},"end":{"line":193,"column":null}},"line":148},"5":{"name":"buildPollingAggregate","decl":{"start":{"line":195,"column":16},"end":{"line":195,"column":38}},"loc":{"start":{"line":195,"column":98},"end":{"line":213,"column":null}},"line":195},"6":{"name":"(anonymous_6)","decl":{"start":{"line":196,"column":26},"end":{"line":196,"column":34}},"loc":{"start":{"line":196,"column":43},"end":{"line":196,"column":63}},"line":196},"7":{"name":"(anonymous_7)","decl":{"start":{"line":200,"column":7},"end":{"line":200,"column":12}},"loc":{"start":{"line":200,"column":21},"end":{"line":200,"column":44}},"line":200},"8":{"name":"(anonymous_8)","decl":{"start":{"line":201,"column":7},"end":{"line":201,"column":15}},"loc":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"line":201},"9":{"name":"(anonymous_9)","decl":{"start":{"line":203,"column":23},"end":{"line":203,"column":31}},"loc":{"start":{"line":203,"column":46},"end":{"line":203,"column":59}},"line":203},"10":{"name":"fetchWithTimeout","decl":{"start":{"line":215,"column":15},"end":{"line":215,"column":null}},"loc":{"start":{"line":219,"column":49},"end":{"line":237,"column":null}},"line":219},"11":{"name":"(anonymous_11)","decl":{"start":{"line":221,"column":16},"end":{"line":221,"column":33}},"loc":{"start":{"line":221,"column":33},"end":{"line":221,"column":53}},"line":221},"12":{"name":"fetchPollingContext","decl":{"start":{"line":239,"column":22},"end":{"line":239,"column":42}},"loc":{"start":{"line":239,"column":100},"end":{"line":306,"column":null}},"line":239},"13":{"name":"(anonymous_13)","decl":{"start":{"line":245,"column":18},"end":{"line":245,"column":25}},"loc":{"start":{"line":245,"column":60},"end":{"line":296,"column":5}},"line":245},"14":{"name":"persistPollingContext","decl":{"start":{"line":308,"column":16},"end":{"line":308,"column":38}},"loc":{"start":{"line":308,"column":108},"end":{"line":312,"column":null}},"line":308},"15":{"name":"parseArgs","decl":{"start":{"line":314,"column":9},"end":{"line":314,"column":19}},"loc":{"start":{"line":314,"column":82},"end":{"line":329,"column":null}},"line":314},"16":{"name":"main","decl":{"start":{"line":331,"column":15},"end":{"line":331,"column":37}},"loc":{"start":{"line":331,"column":37},"end":{"line":338,"column":null}},"line":331},"17":{"name":"(anonymous_17)","decl":{"start":{"line":341,"column":9},"end":{"line":341,"column":16}},"loc":{"start":{"line":341,"column":35},"end":{"line":344,"column":3}},"line":341}},"branchMap":{"0":{"loc":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":103},"1":{"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":105},"2":{"loc":{"start":{"line":127,"column":28},"end":{"line":127,"column":42}},"type":"binary-expr","locations":[{"start":{"line":127,"column":28},"end":{"line":127,"column":40}},{"start":{"line":127,"column":40},"end":{"line":127,"column":42}}],"line":127},"3":{"loc":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":128},"4":{"loc":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":130},"5":{"loc":{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":132},"6":{"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},{"start":{},"end":{}}],"line":133},"7":{"loc":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":137},"8":{"loc":{"start":{"line":137,"column":6},"end":{"line":137,"column":44}},"type":"binary-expr","locations":[{"start":{"line":137,"column":6},"end":{"line":137,"column":19}},{"start":{"line":137,"column":19},"end":{"line":137,"column":44}}],"line":137},"9":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":150,"column":34},"end":{"line":150,"column":61}},{"start":{"line":150,"column":61},"end":{"line":150,"column":null}}],"line":150},"10":{"loc":{"start":{"line":154,"column":25},"end":{"line":154,"column":null}},"type":"cond-expr","locations":[{"start":{"line":154,"column":38},"end":{"line":154,"column":76}},{"start":{"line":154,"column":76},"end":{"line":154,"column":null}}],"line":154},"11":{"loc":{"start":{"line":156,"column":21},"end":{"line":156,"column":null}},"type":"cond-expr","locations":[{"start":{"line":156,"column":44},"end":{"line":156,"column":86}},{"start":{"line":156,"column":86},"end":{"line":156,"column":null}}],"line":156},"12":{"loc":{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":161},"13":{"loc":{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":167},"14":{"loc":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"type":"binary-expr","locations":[{"start":{"line":201,"column":42},"end":{"line":201,"column":71}},{"start":{"line":201,"column":71},"end":{"line":201,"column":93}}],"line":201},"15":{"loc":{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},"type":"if","locations":[{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},{"start":{},"end":{}}],"line":202},"16":{"loc":{"start":{"line":239,"column":42},"end":{"line":239,"column":100}},"type":"default-arg","locations":[{"start":{"line":239,"column":71},"end":{"line":239,"column":100}}],"line":239},"17":{"loc":{"start":{"line":240,"column":20},"end":{"line":240,"column":null}},"type":"binary-expr","locations":[{"start":{"line":240,"column":20},"end":{"line":240,"column":40}},{"start":{"line":240,"column":40},"end":{"line":240,"column":null}}],"line":240},"18":{"loc":{"start":{"line":241,"column":18},"end":{"line":241,"column":null}},"type":"binary-expr","locations":[{"start":{"line":241,"column":18},"end":{"line":241,"column":36}},{"start":{"line":241,"column":36},"end":{"line":241,"column":null}}],"line":241},"19":{"loc":{"start":{"line":242,"column":20},"end":{"line":242,"column":null}},"type":"binary-expr","locations":[{"start":{"line":242,"column":20},"end":{"line":242,"column":38}},{"start":{"line":242,"column":38},"end":{"line":242,"column":null}}],"line":242},"20":{"loc":{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},{"start":{},"end":{}}],"line":248},"21":{"loc":{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},"type":"if","locations":[{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},{"start":{},"end":{}}],"line":264},"22":{"loc":{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},"type":"if","locations":[{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},{"start":{},"end":{}}],"line":266},"23":{"loc":{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},"type":"if","locations":[{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},{"start":{},"end":{}}],"line":269},"24":{"loc":{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},"type":"if","locations":[{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},{"start":{},"end":{}}],"line":276},"25":{"loc":{"start":{"line":276,"column":12},"end":{"line":276,"column":65}},"type":"binary-expr","locations":[{"start":{"line":276,"column":12},"end":{"line":276,"column":45}},{"start":{"line":276,"column":45},"end":{"line":276,"column":65}}],"line":276},"26":{"loc":{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},"type":"if","locations":[{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},{"start":{},"end":{}}],"line":278},"27":{"loc":{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":280},"28":{"loc":{"start":{"line":293,"column":17},"end":{"line":293,"column":null}},"type":"cond-expr","locations":[{"start":{"line":293,"column":42},"end":{"line":293,"column":58}},{"start":{"line":293,"column":58},"end":{"line":293,"column":null}}],"line":293},"29":{"loc":{"start":{"line":308,"column":63},"end":{"line":308,"column":108}},"type":"default-arg","locations":[{"start":{"line":308,"column":76},"end":{"line":308,"column":108}}],"line":308},"30":{"loc":{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},{"start":{},"end":{}}],"line":319},"31":{"loc":{"start":{"line":320,"column":15},"end":{"line":320,"column":null}},"type":"binary-expr","locations":[{"start":{"line":320,"column":15},"end":{"line":320,"column":30}},{"start":{"line":320,"column":30},"end":{"line":320,"column":null}}],"line":320},"32":{"loc":{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},"type":"if","locations":[{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},{"start":{},"end":{}}],"line":324},"33":{"loc":{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},{"start":{},"end":{}}],"line":334},"34":{"loc":{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},"type":"if","locations":[{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},{"start":{},"end":{}}],"line":340},"35":{"loc":{"start":{"line":340,"column":66},"end":{"line":340,"column":87}},"type":"binary-expr","locations":[{"start":{"line":340,"column":66},"end":{"line":340,"column":85}},{"start":{"line":340,"column":85},"end":{"line":340,"column":87}}],"line":340},"36":{"loc":{"start":{"line":342,"column":36},"end":{"line":342,"column":92}},"type":"cond-expr","locations":[{"start":{"line":342,"column":61},"end":{"line":342,"column":77}},{"start":{"line":342,"column":77},"end":{"line":342,"column":92}}],"line":342}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":6,"15":24,"16":24,"17":32,"18":32,"19":16,"20":16,"21":16,"22":16,"23":8,"24":3,"25":1,"26":1,"27":1,"28":1,"29":0,"30":1,"31":1,"32":0,"33":1,"34":1,"35":0,"36":1,"37":0,"38":1,"39":0,"40":1,"41":0,"42":0,"43":3,"44":3,"45":3,"46":3,"47":3,"48":3,"49":3,"50":3,"51":3,"52":3,"53":24,"54":24,"55":16,"56":3,"57":3,"58":3,"59":0,"60":3,"61":3,"62":3,"63":3,"64":24,"65":24,"66":24,"67":24,"68":8,"69":16,"70":16,"71":16,"72":3,"73":3,"74":3,"75":0,"76":3,"77":3,"78":3,"79":3,"80":3,"81":2,"82":2,"83":2,"84":2,"85":2,"86":2,"87":2,"88":0,"89":2,"90":2,"91":2,"92":2,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":2,"101":2,"102":0,"103":0,"104":0,"105":0,"106":0,"107":2,"108":0,"109":2,"110":1,"111":1,"112":1,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":1,"131":0,"132":0,"133":0},"f":{"0":6,"1":24,"2":3,"3":1,"4":3,"5":3,"6":3,"7":24,"8":24,"9":16,"10":3,"11":0,"12":2,"13":2,"14":1,"15":0,"16":0,"17":0},"b":{"0":[16,16],"1":[16,0],"2":[1,0],"3":[0,1],"4":[0,1],"5":[0,1],"6":[0,1],"7":[0,1],"8":[1,0],"9":[2,1],"10":[1,2],"11":[1,2],"12":[16,8],"13":[3,0],"14":[24,16],"15":[8,16],"16":[2],"17":[2,0],"18":[2,0],"19":[2,0],"20":[0,2],"21":[1,1],"22":[1,0],"23":[1,0],"24":[0,2],"25":[2,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[1],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,1],"35":[1,0],"36":[0,0]},"meta":{"lastBranch":37,"lastFunction":18,"lastStatement":134,"seen":{"s:19:27:19:Infinity":0,"s:63:18:63:Infinity":1,"s:64:18:64:Infinity":2,"s:65:38:65:Infinity":3,"s:70:42:70:Infinity":4,"s:71:79:81:Infinity":5,"s:83:21:83:Infinity":6,"s:84:16:84:Infinity":7,"s:85:17:85:Infinity":8,"s:86:15:86:Infinity":9,"s:87:22:87:Infinity":10,"s:88:16:88:Infinity":11,"s:89:17:89:Infinity":12,"s:90:23:90:Infinity":13,"f:92:9:92:19":0,"s:93:2:93:Infinity":14,"f:96:9:96:34":1,"s:97:19:100:Infinity":15,"s:101:2:108:Infinity":16,"s:102:18:102:Infinity":17,"b:103:4:103:Infinity:undefined:undefined:undefined:undefined":0,"s:103:4:103:Infinity":18,"s:103:21:103:Infinity":19,"s:104:18:104:Infinity":20,"b:105:4:107:Infinity:undefined:undefined:undefined:undefined":1,"s:105:4:107:Infinity":21,"s:106:6:106:Infinity":22,"s:109:2:109:Infinity":23,"f:112:9:112:26":2,"s:118:2:118:Infinity":24,"f:121:9:121:32":3,"s:125:2:135:Infinity":25,"s:126:17:126:Infinity":26,"s:127:18:127:Infinity":27,"b:127:28:127:40:127:40:127:42":2,"b:128:4:128:Infinity:undefined:undefined:undefined:undefined":3,"s:128:4:128:Infinity":28,"s:128:15:128:Infinity":29,"s:129:21:129:Infinity":30,"b:130:4:130:Infinity:undefined:undefined:undefined:undefined":4,"s:130:4:130:Infinity":31,"s:130:59:130:Infinity":32,"s:131:21:131:Infinity":33,"b:132:4:132:Infinity:undefined:undefined:undefined:undefined":5,"s:132:4:132:Infinity":34,"s:132:32:132:Infinity":35,"b:133:4:133:Infinity:undefined:undefined:undefined:undefined":6,"s:133:4:133:Infinity":36,"s:133:36:133:Infinity":37,"s:134:4:134:Infinity":38,"s:136:20:136:Infinity":39,"b:137:2:139:Infinity:undefined:undefined:undefined:undefined":7,"s:137:2:139:Infinity":40,"b:137:6:137:19:137:19:137:44":8,"s:138:4:138:Infinity":41,"s:140:2:140:Infinity":42,"f:143:16:143:Infinity":4,"s:149:21:149:Infinity":43,"s:150:16:150:Infinity":44,"b:150:34:150:61:150:61:150:Infinity":9,"s:151:15:151:Infinity":45,"s:152:22:152:Infinity":46,"s:153:21:153:Infinity":47,"s:154:25:154:Infinity":48,"b:154:38:154:76:154:76:154:Infinity":10,"s:155:26:155:Infinity":49,"s:156:21:156:Infinity":50,"b:156:44:156:86:156:86:156:Infinity":11,"s:158:54:158:Infinity":51,"s:159:2:164:Infinity":52,"s:160:18:160:Infinity":53,"b:161:4:163:Infinity:undefined:undefined:undefined:undefined":12,"s:161:4:163:Infinity":54,"s:162:6:162:Infinity":55,"s:166:27:166:Infinity":56,"b:167:2:179:Infinity:undefined:undefined:undefined:undefined":13,"s:167:2:179:Infinity":57,"s:168:4:178:Infinity":58,"s:181:2:192:Infinity":59,"f:195:16:195:38":5,"s:196:20:196:Infinity":60,"f:196:26:196:34":6,"s:196:43:196:63":61,"s:197:71:197:Infinity":62,"s:198:2:208:Infinity":63,"s:199:19:201:Infinity":64,"f:200:7:200:12":7,"s:200:21:200:44":65,"f:201:7:201:15":8,"s:201:42:201:93":66,"b:201:42:201:71:201:71:201:93":14,"b:202:4:202:Infinity:undefined:undefined:undefined:undefined":15,"s:202:4:202:Infinity":67,"s:202:29:202:Infinity":68,"s:203:16:203:Infinity":69,"f:203:23:203:31":9,"s:203:46:203:59":70,"s:204:4:207:Infinity":71,"s:209:2:212:Infinity":72,"f:215:15:215:Infinity":10,"s:220:21:220:Infinity":73,"s:221:16:221:Infinity":74,"f:221:16:221:33":11,"s:221:33:221:53":75,"s:222:2:236:Infinity":76,"s:223:21:229:Infinity":77,"s:232:17:232:Infinity":78,"s:233:4:233:Infinity":79,"s:235:4:235:Infinity":80,"f:239:22:239:42":12,"b:239:71:239:100":16,"s:240:20:240:Infinity":81,"b:240:20:240:40:240:40:240:Infinity":17,"s:241:18:241:Infinity":82,"b:241:18:241:36:241:36:241:Infinity":18,"s:242:20:242:Infinity":83,"b:242:20:242:38:242:38:242:Infinity":19,"s:244:16:297:Infinity":84,"f:245:18:245:25":13,"s:246:6:295:Infinity":85,"s:247:41:247:Infinity":86,"b:248:8:257:Infinity:undefined:undefined:undefined:undefined":20,"s:248:8:257:Infinity":87,"s:249:10:256:Infinity":88,"s:261:28:261:Infinity":89,"s:262:29:262:Infinity":90,"s:263:32:263:Infinity":91,"b:264:8:274:Infinity:undefined:undefined:undefined:undefined":21,"s:264:8:274:Infinity":92,"s:265:39:265:Infinity":93,"b:266:10:273:Infinity:undefined:undefined:undefined:undefined":22,"s:266:10:273:Infinity":94,"s:267:12:267:Infinity":95,"s:268:71:268:Infinity":96,"b:269:12:272:Infinity:undefined:undefined:undefined:undefined":23,"s:269:12:272:Infinity":97,"s:270:14:270:Infinity":98,"s:271:14:271:Infinity":99,"s:275:19:275:Infinity":100,"b:276:8:284:Infinity:undefined:undefined:undefined:undefined":24,"s:276:8:284:Infinity":101,"b:276:12:276:45:276:45:276:65":25,"s:277:30:277:Infinity":102,"b:278:10:283:Infinity:undefined:undefined:undefined:undefined":26,"s:278:10:283:Infinity":103,"s:279:71:279:Infinity":104,"b:280:12:282:Infinity:undefined:undefined:undefined:undefined":27,"s:280:12:282:Infinity":105,"s:281:14:281:Infinity":106,"s:285:8:285:Infinity":107,"s:287:8:294:Infinity":108,"b:293:42:293:58:293:58:293:Infinity":28,"s:299:2:305:Infinity":109,"f:308:16:308:38":14,"b:308:76:308:108":29,"s:309:2:309:Infinity":110,"s:310:2:310:Infinity":111,"s:311:2:311:Infinity":112,"f:314:9:314:19":15,"s:315:15:315:Infinity":113,"s:316:16:316:Infinity":114,"s:317:2:327:Infinity":115,"s:317:15:317:18":116,"s:318:18:318:Infinity":117,"b:319:4:323:Infinity:undefined:undefined:undefined:undefined":30,"s:319:4:323:Infinity":118,"s:320:6:320:Infinity":119,"b:320:15:320:30:320:30:320:Infinity":31,"s:321:6:321:Infinity":120,"s:322:6:322:Infinity":121,"b:324:4:326:Infinity:undefined:undefined:undefined:undefined":32,"s:324:4:326:Infinity":122,"s:325:6:325:Infinity":123,"s:328:2:328:Infinity":124,"f:331:15:331:37":16,"s:332:15:332:Infinity":125,"s:333:18:333:Infinity":126,"b:334:2:336:Infinity:undefined:undefined:undefined:undefined":33,"s:334:2:336:Infinity":127,"s:335:4:335:Infinity":128,"s:337:2:337:Infinity":129,"b:340:0:345:Infinity:undefined:undefined:undefined:undefined":34,"s:340:0:345:Infinity":130,"b:340:66:340:85:340:85:340:87":35,"s:341:2:344:Infinity":131,"f:341:9:341:16":17,"s:342:4:342:Infinity":132,"b:342:61:342:77:342:77:342:92":36,"s:343:4:343:Infinity":133}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/grid.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/grid.ts","statementMap":{"0":{"start":{"line":33,"column":2},"end":{"line":44,"column":null}},"1":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":4},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"renderCatalogGrid","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"loc":{"start":{"line":32,"column":10},"end":{"line":45,"column":null}},"line":32},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":17},"end":{"line":33,"column":22}},"loc":{"start":{"line":33,"column":28},"end":{"line":44,"column":3}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":18},"end":{"line":35,"column":49}},{"start":{"line":35,"column":49},"end":{"line":35,"column":null}}],"line":35}},"s":{"0":60,"1":1860,"2":1860,"3":1860},"f":{"0":60,"1":1860},"b":{"0":[1860,0]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":4,"seen":{"f:28:16:28:Infinity":0,"s:33:2:44:Infinity":0,"f:33:17:33:22":1,"s:34:17:34:Infinity":1,"s:35:18:35:Infinity":2,"b:35:18:35:49:35:49:35:Infinity":0,"s:36:4:42:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/postprocess-translated-brief.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/postprocess-translated-brief.ts","statementMap":{"0":{"start":{"line":36,"column":42},"end":{"line":39,"column":null}},"1":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"2":{"start":{"line":50,"column":19},"end":{"line":50,"column":null}},"3":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"4":{"start":{"line":51,"column":17},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":12},"end":{"line":52,"column":null}},"6":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"7":{"start":{"line":53,"column":10},"end":{"line":53,"column":null}},"8":{"start":{"line":54,"column":15},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"10":{"start":{"line":55,"column":29},"end":{"line":55,"column":null}},"11":{"start":{"line":59,"column":19},"end":{"line":59,"column":null}},"12":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"13":{"start":{"line":60,"column":56},"end":{"line":60,"column":null}},"14":{"start":{"line":61,"column":25},"end":{"line":61,"column":null}},"15":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"16":{"start":{"line":62,"column":35},"end":{"line":62,"column":null}},"17":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"18":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"19":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"20":{"start":{"line":98,"column":23},"end":{"line":98,"column":null}},"21":{"start":{"line":101,"column":26},"end":{"line":101,"column":null}},"22":{"start":{"line":104,"column":24},"end":{"line":104,"column":null}},"23":{"start":{"line":107,"column":25},"end":{"line":107,"column":null}},"24":{"start":{"line":126,"column":15},"end":{"line":126,"column":null}},"25":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"26":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"27":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"28":{"start":{"line":131,"column":2},"end":{"line":131,"column":null}},"29":{"start":{"line":141,"column":22},"end":{"line":141,"column":null}},"30":{"start":{"line":142,"column":2},"end":{"line":197,"column":null}},"31":{"start":{"line":142,"column":15},"end":{"line":142,"column":18}},"32":{"start":{"line":143,"column":15},"end":{"line":143,"column":null}},"33":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"34":{"start":{"line":145,"column":6},"end":{"line":145,"column":null}},"35":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"36":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"37":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"38":{"start":{"line":149,"column":31},"end":{"line":149,"column":null}},"39":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"40":{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},"41":{"start":{"line":159,"column":6},"end":{"line":159,"column":null}},"42":{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},"43":{"start":{"line":163,"column":19},"end":{"line":163,"column":null}},"44":{"start":{"line":164,"column":6},"end":{"line":164,"column":null}},"45":{"start":{"line":167,"column":19},"end":{"line":167,"column":null}},"46":{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},"47":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"48":{"start":{"line":172,"column":17},"end":{"line":172,"column":null}},"49":{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},"50":{"start":{"line":175,"column":30},"end":{"line":175,"column":null}},"51":{"start":{"line":176,"column":6},"end":{"line":189,"column":null}},"52":{"start":{"line":176,"column":19},"end":{"line":176,"column":26}},"53":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"54":{"start":{"line":178,"column":22},"end":{"line":178,"column":null}},"55":{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},"56":{"start":{"line":180,"column":10},"end":{"line":180,"column":null}},"57":{"start":{"line":181,"column":10},"end":{"line":186,"column":null}},"58":{"start":{"line":188,"column":8},"end":{"line":188,"column":null}},"59":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"60":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"61":{"start":{"line":198,"column":2},"end":{"line":198,"column":null}},"62":{"start":{"line":206,"column":16},"end":{"line":206,"column":null}},"63":{"start":{"line":207,"column":16},"end":{"line":207,"column":null}},"64":{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},"65":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"66":{"start":{"line":213,"column":25},"end":{"line":213,"column":null}},"67":{"start":{"line":214,"column":18},"end":{"line":214,"column":null}},"68":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"69":{"start":{"line":219,"column":4},"end":{"line":219,"column":null}},"70":{"start":{"line":227,"column":17},"end":{"line":227,"column":null}},"71":{"start":{"line":228,"column":16},"end":{"line":228,"column":null}},"72":{"start":{"line":229,"column":19},"end":{"line":229,"column":null}},"73":{"start":{"line":231,"column":2},"end":{"line":236,"column":null}},"74":{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},"75":{"start":{"line":252,"column":4},"end":{"line":252,"column":null}},"76":{"start":{"line":254,"column":17},"end":{"line":254,"column":null}},"77":{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},"78":{"start":{"line":256,"column":4},"end":{"line":256,"column":null}},"79":{"start":{"line":259,"column":2},"end":{"line":263,"column":null}},"80":{"start":{"line":260,"column":4},"end":{"line":260,"column":null}},"81":{"start":{"line":262,"column":4},"end":{"line":262,"column":null}},"82":{"start":{"line":264,"column":55},"end":{"line":268,"column":null}},"83":{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},"84":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"85":{"start":{"line":272,"column":2},"end":{"line":276,"column":null}},"86":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"87":{"start":{"line":275,"column":4},"end":{"line":275,"column":null}},"88":{"start":{"line":277,"column":2},"end":{"line":277,"column":null}},"89":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"90":{"start":{"line":282,"column":58},"end":{"line":282,"column":null}},"91":{"start":{"line":283,"column":2},"end":{"line":288,"column":null}},"92":{"start":{"line":284,"column":4},"end":{"line":285,"column":null}},"93":{"start":{"line":287,"column":4},"end":{"line":287,"column":null}},"94":{"start":{"line":292,"column":15},"end":{"line":292,"column":null}},"95":{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},"96":{"start":{"line":294,"column":4},"end":{"line":294,"column":null}},"97":{"start":{"line":295,"column":4},"end":{"line":295,"column":null}},"98":{"start":{"line":297,"column":19},"end":{"line":297,"column":null}},"99":{"start":{"line":298,"column":17},"end":{"line":298,"column":null}},"100":{"start":{"line":299,"column":2},"end":{"line":314,"column":null}},"101":{"start":{"line":300,"column":19},"end":{"line":300,"column":null}},"102":{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},"103":{"start":{"line":302,"column":6},"end":{"line":302,"column":null}},"104":{"start":{"line":303,"column":6},"end":{"line":305,"column":null}},"105":{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},"106":{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},"107":{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},"108":{"start":{"line":309,"column":6},"end":{"line":309,"column":null}},"109":{"start":{"line":311,"column":6},"end":{"line":311,"column":null}},"110":{"start":{"line":312,"column":6},"end":{"line":312,"column":null}},"111":{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},"112":{"start":{"line":315,"column":16},"end":{"line":315,"column":null}},"113":{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},"114":{"start":{"line":316,"column":19},"end":{"line":316,"column":null}},"115":{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},"116":{"start":{"line":320,"column":2},"end":{"line":320,"column":null}}},"fnMap":{"0":{"name":"parseBriefPath","decl":{"start":{"line":48,"column":16},"end":{"line":48,"column":31}},"loc":{"start":{"line":48,"column":95},"end":{"line":64,"column":null}},"line":48},"1":{"name":"stripInnerTags","decl":{"start":{"line":121,"column":9},"end":{"line":121,"column":24}},"loc":{"start":{"line":121,"column":46},"end":{"line":132,"column":null}},"line":121},"2":{"name":"findBodyH1","decl":{"start":{"line":140,"column":9},"end":{"line":140,"column":20}},"loc":{"start":{"line":140,"column":62},"end":{"line":199,"column":null}},"line":140},"3":{"name":"postprocessBriefMarkdown","decl":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"loc":{"start":{"line":205,"column":95},"end":{"line":237,"column":null}},"line":205},"4":{"name":"postprocessBriefFile","decl":{"start":{"line":244,"column":16},"end":{"line":244,"column":37}},"loc":{"start":{"line":250,"column":2},"end":{"line":278,"column":null}},"line":250},"5":{"name":"isMainModule","decl":{"start":{"line":280,"column":9},"end":{"line":280,"column":33}},"loc":{"start":{"line":280,"column":33},"end":{"line":289,"column":null}},"line":280},"6":{"name":"main","decl":{"start":{"line":291,"column":9},"end":{"line":291,"column":22}},"loc":{"start":{"line":291,"column":22},"end":{"line":317,"column":null}},"line":291}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"3":{"loc":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":60},"4":{"loc":{"start":{"line":60,"column":6},"end":{"line":60,"column":56}},"type":"binary-expr","locations":[{"start":{"line":60,"column":6},"end":{"line":60,"column":22}},{"start":{"line":60,"column":22},"end":{"line":60,"column":56}}],"line":60},"5":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":62},"6":{"loc":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":144},"7":{"loc":{"start":{"line":144,"column":8},"end":{"line":144,"column":40}},"type":"binary-expr","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":19}},{"start":{"line":144,"column":19},"end":{"line":144,"column":40}}],"line":144},"8":{"loc":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},{"start":{},"end":{}}],"line":148},"9":{"loc":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":149},"10":{"loc":{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":153},"11":{"loc":{"start":{"line":154,"column":6},"end":{"line":157,"column":null}},"type":"binary-expr","locations":[{"start":{"line":154,"column":6},"end":{"line":154,"column":null}},{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},{"start":{"line":156,"column":6},"end":{"line":156,"column":null}},{"start":{"line":157,"column":6},"end":{"line":157,"column":null}}],"line":154},"12":{"loc":{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":162},"13":{"loc":{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},{"start":{},"end":{}}],"line":168},"14":{"loc":{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":173},"15":{"loc":{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":179},"16":{"loc":{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},"type":"if","locations":[{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},{"start":{},"end":{}}],"line":209},"17":{"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"18":{"loc":{"start":{"line":218,"column":6},"end":{"line":218,"column":46}},"type":"binary-expr","locations":[{"start":{"line":218,"column":6},"end":{"line":218,"column":18}},{"start":{"line":218,"column":18},"end":{"line":218,"column":46}}],"line":218},"19":{"loc":{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},"type":"if","locations":[{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},{"start":{},"end":{}}],"line":251},"20":{"loc":{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},"type":"if","locations":[{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},{"start":{},"end":{}}],"line":255},"21":{"loc":{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},"type":"if","locations":[{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},{"start":{},"end":{}}],"line":269},"22":{"loc":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":282},"23":{"loc":{"start":{"line":282,"column":6},"end":{"line":282,"column":58}},"type":"binary-expr","locations":[{"start":{"line":282,"column":6},"end":{"line":282,"column":40}},{"start":{"line":282,"column":40},"end":{"line":282,"column":58}}],"line":282},"24":{"loc":{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},"type":"if","locations":[{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},{"start":{},"end":{}}],"line":293},"25":{"loc":{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},{"start":{"line":306,"column":11},"end":{"line":313,"column":null}}],"line":301},"26":{"loc":{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},{"start":{"line":308,"column":11},"end":{"line":313,"column":null}}],"line":306},"27":{"loc":{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},{"start":{"line":310,"column":11},"end":{"line":313,"column":null}}],"line":308},"28":{"loc":{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":315},"29":{"loc":{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},"type":"if","locations":[{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},{"start":{},"end":{}}],"line":316},"30":{"loc":{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},{"start":{},"end":{}}],"line":319}},"s":{"0":1,"1":9,"2":9,"3":9,"4":0,"5":9,"6":9,"7":4,"8":5,"9":5,"10":1,"11":4,"12":4,"13":0,"14":4,"15":4,"16":0,"17":4,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":3,"25":3,"26":4,"27":4,"28":3,"29":17,"30":17,"31":17,"32":35,"33":35,"34":2,"35":2,"36":33,"37":5,"38":2,"39":5,"40":28,"41":11,"42":17,"43":12,"44":12,"45":5,"46":5,"47":2,"48":3,"49":3,"50":1,"51":1,"52":1,"53":2,"54":2,"55":2,"56":1,"57":1,"58":1,"59":0,"60":2,"61":0,"62":17,"63":17,"64":17,"65":2,"66":15,"67":15,"68":15,"69":3,"70":12,"71":12,"72":12,"73":12,"74":4,"75":1,"76":3,"77":3,"78":1,"79":2,"80":2,"81":0,"82":2,"83":2,"84":1,"85":1,"86":1,"87":0,"88":1,"89":1,"90":0,"91":1,"92":1,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"116":0},"f":{"0":9,"1":3,"2":17,"3":17,"4":4,"5":1,"6":0},"b":{"0":[0,9],"1":[4,5],"2":[1,4],"3":[0,4],"4":[4,4],"5":[0,4],"6":[2,33],"7":[35,17],"8":[5,28],"9":[2,3],"10":[11,17],"11":[28,22,21,18],"12":[12,5],"13":[2,3],"14":[1,2],"15":[1,1],"16":[2,15],"17":[3,12],"18":[15,14],"19":[1,3],"20":[1,2],"21":[1,1],"22":[0,1],"23":[1,1],"24":[0,0],"25":[0,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,1]},"meta":{"lastBranch":31,"lastFunction":7,"lastStatement":117,"seen":{"s:36:42:39:Infinity":0,"f:48:16:48:31":0,"s:49:16:49:Infinity":1,"s:50:19:50:Infinity":2,"b:51:2:51:Infinity:undefined:undefined:undefined:undefined":0,"s:51:2:51:Infinity":3,"s:51:17:51:Infinity":4,"s:52:12:52:Infinity":5,"b:53:2:53:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:53:Infinity":6,"s:53:10:53:Infinity":7,"s:54:15:54:Infinity":8,"b:55:2:55:Infinity:undefined:undefined:undefined:undefined":2,"s:55:2:55:Infinity":9,"s:55:29:55:Infinity":10,"s:59:19:59:Infinity":11,"b:60:2:60:Infinity:undefined:undefined:undefined:undefined":3,"s:60:2:60:Infinity":12,"b:60:6:60:22:60:22:60:56":4,"s:60:56:60:Infinity":13,"s:61:25:61:Infinity":14,"b:62:2:62:Infinity:undefined:undefined:undefined:undefined":5,"s:62:2:62:Infinity":15,"s:62:35:62:Infinity":16,"s:63:2:63:Infinity":17,"s:92:2:92:Infinity":18,"s:95:22:95:Infinity":19,"s:98:23:98:Infinity":20,"s:101:26:101:Infinity":21,"s:104:24:104:Infinity":22,"s:107:25:107:Infinity":23,"f:121:9:121:24":1,"s:126:15:126:Infinity":24,"s:127:2:130:Infinity":25,"s:128:4:128:Infinity":26,"s:129:4:129:Infinity":27,"s:131:2:131:Infinity":28,"f:140:9:140:20":2,"s:141:22:141:Infinity":29,"s:142:2:197:Infinity":30,"s:142:15:142:18":31,"s:143:15:143:Infinity":32,"b:144:4:147:Infinity:undefined:undefined:undefined:undefined":6,"s:144:4:147:Infinity":33,"b:144:8:144:19:144:19:144:40":7,"s:145:6:145:Infinity":34,"s:146:6:146:Infinity":35,"b:148:4:151:Infinity:undefined:undefined:undefined:undefined":8,"s:148:4:151:Infinity":36,"b:149:6:149:Infinity:undefined:undefined:undefined:undefined":9,"s:149:6:149:Infinity":37,"s:149:31:149:Infinity":38,"s:150:6:150:Infinity":39,"b:153:4:160:Infinity:undefined:undefined:undefined:undefined":10,"s:153:4:160:Infinity":40,"b:154:6:154:Infinity:155:6:155:Infinity:156:6:156:Infinity:157:6:157:Infinity":11,"s:159:6:159:Infinity":41,"b:162:4:165:Infinity:undefined:undefined:undefined:undefined":12,"s:162:4:165:Infinity":42,"s:163:19:163:Infinity":43,"s:164:6:164:Infinity":44,"s:167:19:167:Infinity":45,"b:168:4:170:Infinity:undefined:undefined:undefined:undefined":13,"s:168:4:170:Infinity":46,"s:169:6:169:Infinity":47,"s:172:17:172:Infinity":48,"b:173:4:193:Infinity:undefined:undefined:undefined:undefined":14,"s:173:4:193:Infinity":49,"s:175:30:175:Infinity":50,"s:176:6:189:Infinity":51,"s:176:19:176:26":52,"s:177:22:177:Infinity":53,"s:178:22:178:Infinity":54,"b:179:8:187:Infinity:undefined:undefined:undefined:undefined":15,"s:179:8:187:Infinity":55,"s:180:10:180:Infinity":56,"s:181:10:186:Infinity":57,"s:188:8:188:Infinity":58,"s:192:6:192:Infinity":59,"s:196:4:196:Infinity":60,"s:198:2:198:Infinity":61,"f:201:16:201:Infinity":3,"s:206:16:206:Infinity":62,"s:207:16:207:Infinity":63,"b:209:2:211:Infinity:undefined:undefined:undefined:undefined":16,"s:209:2:211:Infinity":64,"s:210:4:210:Infinity":65,"s:213:25:213:Infinity":66,"s:214:18:214:Infinity":67,"b:218:2:220:Infinity:undefined:undefined:undefined:undefined":17,"s:218:2:220:Infinity":68,"b:218:6:218:18:218:18:218:46":18,"s:219:4:219:Infinity":69,"s:227:17:227:Infinity":70,"s:228:16:228:Infinity":71,"s:229:19:229:Infinity":72,"s:231:2:236:Infinity":73,"f:244:16:244:37":4,"b:251:2:253:Infinity:undefined:undefined:undefined:undefined":19,"s:251:2:253:Infinity":74,"s:252:4:252:Infinity":75,"s:254:17:254:Infinity":76,"b:255:2:257:Infinity:undefined:undefined:undefined:undefined":20,"s:255:2:257:Infinity":77,"s:256:4:256:Infinity":78,"s:259:2:263:Infinity":79,"s:260:4:260:Infinity":80,"s:262:4:262:Infinity":81,"s:264:55:268:Infinity":82,"b:269:2:271:Infinity:undefined:undefined:undefined:undefined":21,"s:269:2:271:Infinity":83,"s:270:4:270:Infinity":84,"s:272:2:276:Infinity":85,"s:273:4:273:Infinity":86,"s:275:4:275:Infinity":87,"s:277:2:277:Infinity":88,"f:280:9:280:33":5,"b:282:2:282:Infinity:undefined:undefined:undefined:undefined":22,"s:282:2:282:Infinity":89,"b:282:6:282:40:282:40:282:58":23,"s:282:58:282:Infinity":90,"s:283:2:288:Infinity":91,"s:284:4:285:Infinity":92,"s:287:4:287:Infinity":93,"f:291:9:291:22":6,"s:292:15:292:Infinity":94,"b:293:2:296:Infinity:undefined:undefined:undefined:undefined":24,"s:293:2:296:Infinity":95,"s:294:4:294:Infinity":96,"s:295:4:295:Infinity":97,"s:297:19:297:Infinity":98,"s:298:17:298:Infinity":99,"s:299:2:314:Infinity":100,"s:300:19:300:Infinity":101,"b:301:4:313:Infinity:306:11:313:Infinity":25,"s:301:4:313:Infinity":102,"s:302:6:302:Infinity":103,"s:303:6:305:Infinity":104,"b:306:11:313:Infinity:308:11:313:Infinity":26,"s:306:11:313:Infinity":105,"s:307:6:307:Infinity":106,"b:308:11:313:Infinity:310:11:313:Infinity":27,"s:308:11:313:Infinity":107,"s:309:6:309:Infinity":108,"s:311:6:311:Infinity":109,"s:312:6:312:Infinity":110,"b:315:2:315:Infinity:undefined:undefined:undefined:undefined":28,"s:315:2:315:Infinity":111,"s:315:16:315:Infinity":112,"b:316:2:316:Infinity:undefined:undefined:undefined:undefined":29,"s:316:2:316:Infinity":113,"s:316:19:316:Infinity":114,"b:319:0:321:Infinity:undefined:undefined:undefined:undefined":30,"s:319:0:321:Infinity":115,"s:320:2:320:Infinity":116}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/cli.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/cli.ts","statementMap":{"0":{"start":{"line":22,"column":24},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":42,"column":null}},"2":{"start":{"line":23,"column":15},"end":{"line":23,"column":18}},"3":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"4":{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},"5":{"start":{"line":25,"column":26},"end":{"line":25,"column":null}},"6":{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},"7":{"start":{"line":26,"column":29},"end":{"line":26,"column":null}},"8":{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},"9":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"10":{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},"11":{"start":{"line":28,"column":32},"end":{"line":28,"column":null}},"12":{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},"13":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"14":{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},"15":{"start":{"line":30,"column":46},"end":{"line":30,"column":null}},"16":{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},"17":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"18":{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},"19":{"start":{"line":34,"column":8},"end":{"line":34,"column":null}},"20":{"start":{"line":36,"column":21},"end":{"line":36,"column":null}},"21":{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},"22":{"start":{"line":38,"column":8},"end":{"line":38,"column":null}},"23":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"24":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"25":{"start":{"line":47,"column":14},"end":{"line":47,"column":null}},"26":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"27":{"start":{"line":49,"column":15},"end":{"line":49,"column":null}},"28":{"start":{"line":49,"column":49},"end":{"line":49,"column":null}},"29":{"start":{"line":51,"column":2},"end":{"line":57,"column":null}},"30":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"31":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"32":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"33":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"34":{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},"35":{"start":{"line":65,"column":4},"end":{"line":67,"column":null}},"36":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"37":{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},"38":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"39":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"40":{"start":{"line":73,"column":6},"end":{"line":73,"column":null}},"41":{"start":{"line":75,"column":18},"end":{"line":75,"column":null}},"42":{"start":{"line":76,"column":21},"end":{"line":76,"column":null}},"43":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"44":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"45":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"46":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"47":{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},"48":{"start":{"line":82,"column":6},"end":{"line":82,"column":null}},"49":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"50":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"51":{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},"52":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"53":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"54":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"55":{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},"56":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"57":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"58":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"59":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"60":{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},"61":{"start":{"line":98,"column":6},"end":{"line":100,"column":null}},"62":{"start":{"line":101,"column":6},"end":{"line":101,"column":null}},"63":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"64":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"65":{"start":{"line":106,"column":4},"end":{"line":110,"column":null}},"66":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"67":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"68":{"start":{"line":116,"column":2},"end":{"line":122,"column":null}},"69":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"70":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"71":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"72":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"73":{"start":{"line":125,"column":2},"end":{"line":131,"column":null}},"74":{"start":{"line":126,"column":4},"end":{"line":126,"column":null}},"75":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"76":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"77":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"78":{"start":{"line":133,"column":37},"end":{"line":133,"column":null}},"79":{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},"80":{"start":{"line":134,"column":14},"end":{"line":134,"column":null}},"81":{"start":{"line":135,"column":17},"end":{"line":135,"column":null}},"82":{"start":{"line":136,"column":15},"end":{"line":136,"column":null}},"83":{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},"84":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"85":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"86":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},"87":{"start":{"line":143,"column":33},"end":{"line":143,"column":null}},"88":{"start":{"line":144,"column":21},"end":{"line":144,"column":null}},"89":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"90":{"start":{"line":147,"column":2},"end":{"line":150,"column":null}},"91":{"start":{"line":148,"column":50},"end":{"line":148,"column":69}},"92":{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},"93":{"start":{"line":153,"column":25},"end":{"line":153,"column":null}},"94":{"start":{"line":153,"column":56},"end":{"line":153,"column":64}},"95":{"start":{"line":154,"column":15},"end":{"line":154,"column":null}},"96":{"start":{"line":155,"column":19},"end":{"line":155,"column":null}},"97":{"start":{"line":156,"column":4},"end":{"line":156,"column":null}},"98":{"start":{"line":157,"column":4},"end":{"line":159,"column":null}}},"fnMap":{"0":{"name":"parseArgs","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":26}},"loc":{"start":{"line":21,"column":51},"end":{"line":44,"column":null}},"line":21},"1":{"name":"runMain","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":24}},"loc":{"start":{"line":46,"column":62},"end":{"line":161,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":49,"column":18},"end":{"line":49,"column":28}},"loc":{"start":{"line":49,"column":49},"end":{"line":49,"column":null}},"line":49},"3":{"name":"(anonymous_3)","decl":{"start":{"line":148,"column":36},"end":{"line":148,"column":44}},"loc":{"start":{"line":148,"column":50},"end":{"line":148,"column":69}},"line":148},"4":{"name":"(anonymous_4)","decl":{"start":{"line":153,"column":45},"end":{"line":153,"column":50}},"loc":{"start":{"line":153,"column":56},"end":{"line":153,"column":64}},"line":153}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},{"start":{"line":26,"column":9},"end":{"line":41,"column":null}}],"line":25},"1":{"loc":{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},{"start":{"line":27,"column":9},"end":{"line":41,"column":null}}],"line":26},"2":{"loc":{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},{"start":{"line":28,"column":9},"end":{"line":41,"column":null}}],"line":27},"3":{"loc":{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},{"start":{"line":29,"column":9},"end":{"line":41,"column":null}}],"line":28},"4":{"loc":{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},{"start":{"line":30,"column":9},"end":{"line":41,"column":null}}],"line":29},"5":{"loc":{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},{"start":{"line":31,"column":9},"end":{"line":41,"column":null}}],"line":30},"6":{"loc":{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":31},"7":{"loc":{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33},"8":{"loc":{"start":{"line":33,"column":10},"end":{"line":33,"column":40}},"type":"binary-expr","locations":[{"start":{"line":33,"column":10},"end":{"line":33,"column":18}},{"start":{"line":33,"column":18},"end":{"line":33,"column":40}}],"line":33},"9":{"loc":{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"10":{"loc":{"start":{"line":37,"column":10},"end":{"line":37,"column":82}},"type":"binary-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":42}},{"start":{"line":37,"column":42},"end":{"line":37,"column":70}},{"start":{"line":37,"column":70},"end":{"line":37,"column":82}}],"line":37},"11":{"loc":{"start":{"line":46,"column":40},"end":{"line":46,"column":62}},"type":"default-arg","locations":[{"start":{"line":46,"column":52},"end":{"line":46,"column":62}}],"line":46},"12":{"loc":{"start":{"line":47,"column":14},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":14},"end":{"line":47,"column":27}},{"start":{"line":47,"column":27},"end":{"line":47,"column":null}}],"line":47},"13":{"loc":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":14},"end":{"line":48,"column":27}},{"start":{"line":48,"column":27},"end":{"line":48,"column":null}}],"line":48},"14":{"loc":{"start":{"line":49,"column":15},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":15},"end":{"line":49,"column":28}},{"start":{"line":49,"column":18},"end":{"line":49,"column":null}}],"line":49},"15":{"loc":{"start":{"line":54,"column":40},"end":{"line":54,"column":74}},"type":"cond-expr","locations":[{"start":{"line":54,"column":61},"end":{"line":54,"column":73}},{"start":{"line":54,"column":73},"end":{"line":54,"column":74}}],"line":54},"16":{"loc":{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},{"start":{"line":86,"column":9},"end":{"line":113,"column":null}}],"line":64},"17":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":28}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":19}},{"start":{"line":64,"column":19},"end":{"line":64,"column":28}}],"line":64},"18":{"loc":{"start":{"line":65,"column":17},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":null}},{"start":{"line":67,"column":8},"end":{"line":67,"column":null}}],"line":65},"19":{"loc":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":43},"end":{"line":68,"column":53}},{"start":{"line":68,"column":53},"end":{"line":68,"column":null}}],"line":68},"20":{"loc":{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":70},"21":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":69},"end":{"line":77,"column":98}},{"start":{"line":77,"column":98},"end":{"line":77,"column":null}}],"line":77},"22":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":69}},"type":"binary-expr","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":38}},{"start":{"line":77,"column":38},"end":{"line":77,"column":69}}],"line":77},"23":{"loc":{"start":{"line":77,"column":69},"end":{"line":77,"column":98}},"type":"binary-expr","locations":[{"start":{"line":77,"column":69},"end":{"line":77,"column":92}},{"start":{"line":77,"column":92},"end":{"line":77,"column":98}}],"line":77},"24":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":70},"end":{"line":78,"column":99}},{"start":{"line":78,"column":99},"end":{"line":78,"column":null}}],"line":78},"25":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":70}},"type":"binary-expr","locations":[{"start":{"line":78,"column":22},"end":{"line":78,"column":39}},{"start":{"line":78,"column":39},"end":{"line":78,"column":70}}],"line":78},"26":{"loc":{"start":{"line":78,"column":70},"end":{"line":78,"column":99}},"type":"binary-expr","locations":[{"start":{"line":78,"column":70},"end":{"line":78,"column":93}},{"start":{"line":78,"column":93},"end":{"line":78,"column":99}}],"line":78},"27":{"loc":{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":81},"28":{"loc":{"start":{"line":81,"column":8},"end":{"line":81,"column":83}},"type":"binary-expr","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":51}},{"start":{"line":81,"column":51},"end":{"line":81,"column":83}}],"line":81},"29":{"loc":{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},{"start":{"line":105,"column":9},"end":{"line":113,"column":null}}],"line":86},"30":{"loc":{"start":{"line":86,"column":13},"end":{"line":86,"column":38}},"type":"binary-expr","locations":[{"start":{"line":86,"column":13},"end":{"line":86,"column":26}},{"start":{"line":86,"column":26},"end":{"line":86,"column":38}}],"line":86},"31":{"loc":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":87},"32":{"loc":{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":97},"33":{"loc":{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},{"start":{},"end":{}}],"line":134},"34":{"loc":{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":138},"35":{"loc":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":143},"36":{"loc":{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":152},"37":{"loc":{"start":{"line":152,"column":6},"end":{"line":152,"column":60}},"type":"binary-expr","locations":[{"start":{"line":152,"column":6},"end":{"line":152,"column":32}},{"start":{"line":152,"column":32},"end":{"line":152,"column":60}}],"line":152}},"s":{"0":27,"1":27,"2":27,"3":45,"4":45,"5":14,"6":31,"7":14,"8":17,"9":4,"10":13,"11":4,"12":9,"13":2,"14":7,"15":1,"16":6,"17":6,"18":6,"19":1,"20":5,"21":5,"22":3,"23":2,"24":23,"25":17,"26":17,"27":17,"28":0,"29":17,"30":17,"31":1,"32":1,"33":1,"34":16,"35":13,"36":13,"37":13,"38":1,"39":1,"40":1,"41":12,"42":12,"43":12,"44":13,"45":13,"46":13,"47":13,"48":1,"49":1,"50":1,"51":3,"52":2,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":0,"65":1,"66":1,"67":1,"68":11,"69":11,"70":1,"71":1,"72":1,"73":10,"74":10,"75":1,"76":1,"77":1,"78":9,"79":9,"80":7,"81":9,"82":9,"83":9,"84":1,"85":1,"86":8,"87":7,"88":8,"89":8,"90":8,"91":16,"92":8,"93":5,"94":10,"95":5,"96":5,"97":5,"98":5},"f":{"0":27,"1":17,"2":0,"3":16,"4":10},"b":{"0":[14,31],"1":[14,17],"2":[4,13],"3":[4,9],"4":[2,7],"5":[1,6],"6":[6,0],"7":[1,5],"8":[6,5],"9":[3,2],"10":[5,4,4],"11":[17],"12":[17,0],"13":[17,0],"14":[17,0],"15":[1,0],"16":[13,3],"17":[16,13],"18":[13,0],"19":[13,0],"20":[1,12],"21":[12,0],"22":[12,12],"23":[12,0],"24":[11,1],"25":[13,12],"26":[11,0],"27":[1,12],"28":[13,11],"29":[2,1],"30":[3,2],"31":[1,1],"32":[1,0],"33":[7,2],"34":[1,8],"35":[7,1],"36":[5,3],"37":[8,7]},"meta":{"lastBranch":38,"lastFunction":5,"lastStatement":99,"seen":{"f:21:16:21:26":0,"s:22:24:22:Infinity":0,"s:23:2:42:Infinity":1,"s:23:15:23:18":2,"s:24:16:24:Infinity":3,"b:25:4:41:Infinity:26:9:41:Infinity":0,"s:25:4:41:Infinity":4,"s:25:26:25:Infinity":5,"b:26:9:41:Infinity:27:9:41:Infinity":1,"s:26:9:41:Infinity":6,"s:26:29:26:Infinity":7,"b:27:9:41:Infinity:28:9:41:Infinity":2,"s:27:9:41:Infinity":8,"s:27:31:27:Infinity":9,"b:28:9:41:Infinity:29:9:41:Infinity":3,"s:28:9:41:Infinity":10,"s:28:32:28:Infinity":11,"b:29:9:41:Infinity:30:9:41:Infinity":4,"s:29:9:41:Infinity":12,"s:29:34:29:Infinity":13,"b:30:9:41:Infinity:31:9:41:Infinity":5,"s:30:9:41:Infinity":14,"s:30:46:30:Infinity":15,"b:31:9:41:Infinity:undefined:undefined:undefined:undefined":6,"s:31:9:41:Infinity":16,"s:32:18:32:Infinity":17,"b:33:6:35:Infinity:undefined:undefined:undefined:undefined":7,"s:33:6:35:Infinity":18,"b:33:10:33:18:33:18:33:40":8,"s:34:8:34:Infinity":19,"s:36:21:36:Infinity":20,"b:37:6:39:Infinity:undefined:undefined:undefined:undefined":9,"s:37:6:39:Infinity":21,"b:37:10:37:42:37:42:37:70:37:70:37:82":10,"s:38:8:38:Infinity":22,"s:40:6:40:Infinity":23,"s:43:2:43:Infinity":24,"f:46:16:46:24":1,"b:46:52:46:62":11,"s:47:14:47:Infinity":25,"b:47:14:47:27:47:27:47:Infinity":12,"s:48:14:48:Infinity":26,"b:48:14:48:27:48:27:48:Infinity":13,"s:49:15:49:Infinity":27,"b:49:15:49:28:49:18:49:Infinity":14,"f:49:18:49:28":2,"s:49:49:49:Infinity":28,"s:51:2:57:Infinity":29,"s:52:4:52:Infinity":30,"s:54:4:54:Infinity":31,"b:54:61:54:73:54:73:54:74":15,"s:55:4:55:Infinity":32,"s:56:4:56:Infinity":33,"b:64:2:113:Infinity:86:9:113:Infinity":16,"s:64:2:113:Infinity":34,"b:64:6:64:19:64:19:64:28":17,"s:65:4:67:Infinity":35,"b:66:8:66:Infinity:67:8:67:Infinity":18,"s:68:4:68:Infinity":36,"b:68:43:68:53:68:53:68:Infinity":19,"b:70:4:74:Infinity:undefined:undefined:undefined:undefined":20,"s:70:4:74:Infinity":37,"s:71:6:71:Infinity":38,"s:72:6:72:Infinity":39,"s:73:6:73:Infinity":40,"s:75:18:75:Infinity":41,"s:76:21:76:Infinity":42,"s:77:21:77:Infinity":43,"b:77:69:77:98:77:98:77:Infinity":21,"b:77:21:77:38:77:38:77:69":22,"b:77:69:77:92:77:92:77:98":23,"s:78:22:78:Infinity":44,"b:78:70:78:99:78:99:78:Infinity":24,"b:78:22:78:39:78:39:78:70":25,"b:78:70:78:93:78:93:78:99":26,"s:79:4:79:Infinity":45,"s:80:4:80:Infinity":46,"b:81:4:85:Infinity:undefined:undefined:undefined:undefined":27,"s:81:4:85:Infinity":47,"b:81:8:81:51:81:51:81:83":28,"s:82:6:82:Infinity":48,"s:83:6:83:Infinity":49,"s:84:6:84:Infinity":50,"b:86:9:113:Infinity:105:9:113:Infinity":29,"s:86:9:113:Infinity":51,"b:86:13:86:26:86:26:86:38":30,"b:87:4:91:Infinity:undefined:undefined:undefined:undefined":31,"s:87:4:91:Infinity":52,"s:88:6:88:Infinity":53,"s:89:6:89:Infinity":54,"s:90:6:90:Infinity":55,"s:92:4:92:Infinity":56,"s:93:4:93:Infinity":57,"s:94:4:94:Infinity":58,"s:96:18:96:Infinity":59,"b:97:4:103:Infinity:undefined:undefined:undefined:undefined":32,"s:97:4:103:Infinity":60,"s:98:6:100:Infinity":61,"s:101:6:101:Infinity":62,"s:102:6:102:Infinity":63,"s:104:4:104:Infinity":64,"s:106:4:110:Infinity":65,"s:111:4:111:Infinity":66,"s:112:4:112:Infinity":67,"s:116:2:122:Infinity":68,"s:117:4:117:Infinity":69,"s:119:4:119:Infinity":70,"s:120:4:120:Infinity":71,"s:121:4:121:Infinity":72,"s:125:2:131:Infinity":73,"s:126:4:126:Infinity":74,"s:128:4:128:Infinity":75,"s:129:4:129:Infinity":76,"s:130:4:130:Infinity":77,"s:133:37:133:Infinity":78,"b:134:2:134:Infinity:undefined:undefined:undefined:undefined":33,"s:134:2:134:Infinity":79,"s:134:14:134:Infinity":80,"s:135:17:135:Infinity":81,"s:136:15:136:Infinity":82,"b:138:2:141:Infinity:undefined:undefined:undefined:undefined":34,"s:138:2:141:Infinity":83,"s:139:4:139:Infinity":84,"s:140:4:140:Infinity":85,"b:143:2:143:Infinity:undefined:undefined:undefined:undefined":35,"s:143:2:143:Infinity":86,"s:143:33:143:Infinity":87,"s:144:21:144:Infinity":88,"s:145:2:145:Infinity":89,"s:147:2:150:Infinity":90,"f:148:36:148:44":3,"s:148:50:148:69":91,"b:152:2:160:Infinity:undefined:undefined:undefined:undefined":36,"s:152:2:160:Infinity":92,"b:152:6:152:32:152:32:152:60":37,"s:153:25:153:Infinity":93,"f:153:45:153:50":4,"s:153:56:153:64":94,"s:154:15:154:Infinity":95,"s:155:19:155:Infinity":96,"s:156:4:156:Infinity":97,"s:157:4:159:Infinity":98}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rir-followups-client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rir-followups-client.ts","statementMap":{"0":{"start":{"line":119,"column":46},"end":{"line":119,"column":null}},"1":{"start":{"line":126,"column":34},"end":{"line":126,"column":null}},"2":{"start":{"line":129,"column":36},"end":{"line":129,"column":null}},"3":{"start":{"line":132,"column":36},"end":{"line":132,"column":null}},"4":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"5":{"start":{"line":161,"column":14},"end":{"line":161,"column":null}},"6":{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},"7":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"8":{"start":{"line":165,"column":15},"end":{"line":165,"column":null}},"9":{"start":{"line":166,"column":16},"end":{"line":166,"column":null}},"10":{"start":{"line":167,"column":14},"end":{"line":167,"column":null}},"11":{"start":{"line":169,"column":23},"end":{"line":169,"column":null}},"12":{"start":{"line":170,"column":8},"end":{"line":170,"column":null}},"13":{"start":{"line":172,"column":30},"end":{"line":172,"column":null}},"14":{"start":{"line":173,"column":22},"end":{"line":173,"column":null}},"15":{"start":{"line":175,"column":8},"end":{"line":175,"column":null}},"16":{"start":{"line":175,"column":37},"end":{"line":175,"column":null}},"17":{"start":{"line":176,"column":2},"end":{"line":176,"column":null}},"18":{"start":{"line":204,"column":14},"end":{"line":204,"column":null}},"19":{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},"20":{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},"21":{"start":{"line":211,"column":6},"end":{"line":211,"column":null}},"22":{"start":{"line":213,"column":4},"end":{"line":213,"column":null}},"23":{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},"24":{"start":{"line":217,"column":21},"end":{"line":217,"column":null}},"25":{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},"26":{"start":{"line":219,"column":6},"end":{"line":219,"column":null}},"27":{"start":{"line":223,"column":2},"end":{"line":223,"column":null}},"28":{"start":{"line":238,"column":14},"end":{"line":238,"column":null}},"29":{"start":{"line":239,"column":19},"end":{"line":239,"column":null}},"30":{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},"31":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"32":{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},"33":{"start":{"line":244,"column":4},"end":{"line":244,"column":null}},"34":{"start":{"line":246,"column":17},"end":{"line":246,"column":null}},"35":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"36":{"start":{"line":266,"column":14},"end":{"line":266,"column":null}},"37":{"start":{"line":267,"column":37},"end":{"line":267,"column":null}},"38":{"start":{"line":269,"column":2},"end":{"line":286,"column":null}},"39":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"40":{"start":{"line":270,"column":36},"end":{"line":270,"column":null}},"41":{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},"42":{"start":{"line":271,"column":38},"end":{"line":271,"column":null}},"43":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"44":{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},"45":{"start":{"line":275,"column":6},"end":{"line":284,"column":null}},"46":{"start":{"line":288,"column":2},"end":{"line":288,"column":null}},"47":{"start":{"line":288,"column":31},"end":{"line":288,"column":62}},"48":{"start":{"line":309,"column":14},"end":{"line":309,"column":null}},"49":{"start":{"line":312,"column":4},"end":{"line":312,"column":null}},"50":{"start":{"line":314,"column":4},"end":{"line":314,"column":null}},"51":{"start":{"line":316,"column":15},"end":{"line":333,"column":null}},"52":{"start":{"line":317,"column":19},"end":{"line":317,"column":null}},"53":{"start":{"line":318,"column":20},"end":{"line":320,"column":null}},"54":{"start":{"line":321,"column":23},"end":{"line":321,"column":null}},"55":{"start":{"line":322,"column":24},"end":{"line":327,"column":null}},"56":{"start":{"line":328,"column":24},"end":{"line":328,"column":null}},"57":{"start":{"line":329,"column":22},"end":{"line":331,"column":null}},"58":{"start":{"line":332,"column":4},"end":{"line":332,"column":null}},"59":{"start":{"line":335,"column":2},"end":{"line":335,"column":null}},"60":{"start":{"line":358,"column":16},"end":{"line":358,"column":null}},"61":{"start":{"line":359,"column":16},"end":{"line":367,"column":null}},"62":{"start":{"line":369,"column":22},"end":{"line":369,"column":null}},"63":{"start":{"line":370,"column":20},"end":{"line":370,"column":null}},"64":{"start":{"line":371,"column":19},"end":{"line":371,"column":null}},"65":{"start":{"line":372,"column":17},"end":{"line":372,"column":null}},"66":{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},"67":{"start":{"line":375,"column":4},"end":{"line":378,"column":null}},"68":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"69":{"start":{"line":400,"column":13},"end":{"line":400,"column":null}},"70":{"start":{"line":401,"column":2},"end":{"line":403,"column":null}},"71":{"start":{"line":401,"column":25},"end":{"line":402,"column":null}},"72":{"start":{"line":402,"column":37},"end":{"line":402,"column":59}},"73":{"start":{"line":416,"column":2},"end":{"line":416,"column":null}},"74":{"start":{"line":416,"column":31},"end":{"line":416,"column":63}},"75":{"start":{"line":429,"column":46},"end":{"line":434,"column":null}},"76":{"start":{"line":435,"column":20},"end":{"line":435,"column":null}},"77":{"start":{"line":436,"column":2},"end":{"line":436,"column":null}},"78":{"start":{"line":436,"column":31},"end":{"line":436,"column":85}},"79":{"start":{"line":450,"column":27},"end":{"line":450,"column":null}},"80":{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},"81":{"start":{"line":453,"column":4},"end":{"line":453,"column":null}},"82":{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},"83":{"start":{"line":456,"column":4},"end":{"line":456,"column":null}},"84":{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},"85":{"start":{"line":459,"column":4},"end":{"line":459,"column":null}},"86":{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},"87":{"start":{"line":462,"column":4},"end":{"line":462,"column":null}},"88":{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},"89":{"start":{"line":465,"column":4},"end":{"line":465,"column":null}},"90":{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},"91":{"start":{"line":468,"column":4},"end":{"line":468,"column":null}},"92":{"start":{"line":470,"column":45},"end":{"line":470,"column":null}},"93":{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},"94":{"start":{"line":472,"column":4},"end":{"line":472,"column":null}},"95":{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},"96":{"start":{"line":475,"column":4},"end":{"line":475,"column":null}},"97":{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},"98":{"start":{"line":476,"column":66},"end":{"line":476,"column":88}},"99":{"start":{"line":477,"column":4},"end":{"line":477,"column":null}},"100":{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},"101":{"start":{"line":484,"column":4},"end":{"line":484,"column":null}},"102":{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},"103":{"start":{"line":490,"column":4},"end":{"line":490,"column":null}},"104":{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},"105":{"start":{"line":494,"column":4},"end":{"line":494,"column":null}},"106":{"start":{"line":497,"column":2},"end":{"line":497,"column":null}},"107":{"start":{"line":508,"column":19},"end":{"line":508,"column":null}},"108":{"start":{"line":509,"column":2},"end":{"line":514,"column":null}},"109":{"start":{"line":510,"column":19},"end":{"line":510,"column":null}},"110":{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},"111":{"start":{"line":512,"column":6},"end":{"line":512,"column":null}},"112":{"start":{"line":515,"column":2},"end":{"line":515,"column":null}},"113":{"start":{"line":533,"column":14},"end":{"line":533,"column":null}},"114":{"start":{"line":534,"column":2},"end":{"line":534,"column":null}},"115":{"start":{"line":552,"column":4},"end":{"line":556,"column":null}},"116":{"start":{"line":557,"column":2},"end":{"line":557,"column":null}}},"fnMap":{"0":{"name":"calculateSkrivelseDeadline","decl":{"start":{"line":156,"column":16},"end":{"line":156,"column":null}},"loc":{"start":{"line":159,"column":10},"end":{"line":177,"column":null}},"line":159},"1":{"name":"(anonymous_1)","decl":{"start":{"line":175,"column":8},"end":{"line":175,"column":15}},"loc":{"start":{"line":175,"column":37},"end":{"line":175,"column":null}},"line":175},"2":{"name":"deriveResponseStatus","decl":{"start":{"line":200,"column":16},"end":{"line":200,"column":null}},"loc":{"start":{"line":203,"column":21},"end":{"line":224,"column":null}},"line":203},"3":{"name":"daysOverdue","decl":{"start":{"line":234,"column":16},"end":{"line":234,"column":null}},"loc":{"start":{"line":237,"column":10},"end":{"line":248,"column":null}},"line":237},"4":{"name":"detectOverdueAlerts","decl":{"start":{"line":262,"column":16},"end":{"line":262,"column":null}},"loc":{"start":{"line":265,"column":31},"end":{"line":289,"column":null}},"line":265},"5":{"name":"(anonymous_5)","decl":{"start":{"line":288,"column":16},"end":{"line":288,"column":22}},"loc":{"start":{"line":288,"column":31},"end":{"line":288,"column":62}},"line":288},"6":{"name":"renderRirFollowUpTable","decl":{"start":{"line":305,"column":16},"end":{"line":305,"column":null}},"loc":{"start":{"line":308,"column":10},"end":{"line":336,"column":null}},"line":308},"7":{"name":"(anonymous_7)","decl":{"start":{"line":316,"column":23},"end":{"line":316,"column":28}},"loc":{"start":{"line":316,"column":34},"end":{"line":333,"column":3}},"line":316},"8":{"name":"injectRirTableIntoDocument","decl":{"start":{"line":353,"column":16},"end":{"line":353,"column":null}},"loc":{"start":{"line":357,"column":10},"end":{"line":383,"column":null}},"line":357},"9":{"name":"filterByCommittee","decl":{"start":{"line":396,"column":16},"end":{"line":396,"column":null}},"loc":{"start":{"line":399,"column":32},"end":{"line":404,"column":null}},"line":399},"10":{"name":"(anonymous_10)","decl":{"start":{"line":401,"column":17},"end":{"line":401,"column":25}},"loc":{"start":{"line":401,"column":25},"end":{"line":402,"column":null}},"line":401},"11":{"name":"(anonymous_11)","decl":{"start":{"line":402,"column":25},"end":{"line":402,"column":31}},"loc":{"start":{"line":402,"column":37},"end":{"line":402,"column":59}},"line":402},"12":{"name":"filterByStatus","decl":{"start":{"line":412,"column":16},"end":{"line":412,"column":null}},"loc":{"start":{"line":415,"column":32},"end":{"line":417,"column":null}},"line":415},"13":{"name":"(anonymous_13)","decl":{"start":{"line":416,"column":17},"end":{"line":416,"column":25}},"loc":{"start":{"line":416,"column":31},"end":{"line":416,"column":63}},"line":416},"14":{"name":"filterByMinRiskLevel","decl":{"start":{"line":425,"column":16},"end":{"line":425,"column":null}},"loc":{"start":{"line":428,"column":32},"end":{"line":437,"column":null}},"line":428},"15":{"name":"(anonymous_15)","decl":{"start":{"line":436,"column":17},"end":{"line":436,"column":25}},"loc":{"start":{"line":436,"column":31},"end":{"line":436,"column":85}},"line":436},"16":{"name":"validateRirRecord","decl":{"start":{"line":449,"column":16},"end":{"line":449,"column":34}},"loc":{"start":{"line":449,"column":80},"end":{"line":498,"column":null}},"line":449},"17":{"name":"(anonymous_17)","decl":{"start":{"line":476,"column":52},"end":{"line":476,"column":59}},"loc":{"start":{"line":476,"column":66},"end":{"line":476,"column":88}},"line":476},"18":{"name":"validateRirDataset","decl":{"start":{"line":505,"column":16},"end":{"line":505,"column":null}},"loc":{"start":{"line":507,"column":34},"end":{"line":516,"column":null}},"line":507},"19":{"name":"loadRirDataset","decl":{"start":{"line":529,"column":16},"end":{"line":529,"column":null}},"loc":{"start":{"line":532,"column":23},"end":{"line":535,"column":null}},"line":532},"20":{"name":"saveRirDataset","decl":{"start":{"line":545,"column":16},"end":{"line":545,"column":null}},"loc":{"start":{"line":550,"column":8},"end":{"line":558,"column":null}},"line":550}},"branchMap":{"0":{"loc":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"type":"default-arg","locations":[{"start":{"line":158,"column":39},"end":{"line":158,"column":null}}],"line":158},"1":{"loc":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"type":"binary-expr","locations":[{"start":{"line":160,"column":17},"end":{"line":160,"column":43}},{"start":{"line":160,"column":43},"end":{"line":160,"column":null}}],"line":160},"2":{"loc":{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":162},"3":{"loc":{"start":{"line":202,"column":2},"end":{"line":202,"column":null}},"type":"default-arg","locations":[{"start":{"line":202,"column":24},"end":{"line":202,"column":null}}],"line":202},"4":{"loc":{"start":{"line":204,"column":14},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":204,"column":41},"end":{"line":204,"column":73}},{"start":{"line":204,"column":73},"end":{"line":204,"column":null}}],"line":204},"5":{"loc":{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":206},"6":{"loc":{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},{"start":{},"end":{}}],"line":207},"7":{"loc":{"start":{"line":208,"column":6},"end":{"line":209,"column":null}},"type":"binary-expr","locations":[{"start":{"line":208,"column":6},"end":{"line":208,"column":null}},{"start":{"line":209,"column":7},"end":{"line":209,"column":58}},{"start":{"line":209,"column":58},"end":{"line":209,"column":null}}],"line":208},"8":{"loc":{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":216},"9":{"loc":{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"10":{"loc":{"start":{"line":236,"column":2},"end":{"line":236,"column":null}},"type":"default-arg","locations":[{"start":{"line":236,"column":24},"end":{"line":236,"column":null}}],"line":236},"11":{"loc":{"start":{"line":238,"column":14},"end":{"line":238,"column":null}},"type":"cond-expr","locations":[{"start":{"line":238,"column":41},"end":{"line":238,"column":73}},{"start":{"line":238,"column":73},"end":{"line":238,"column":null}}],"line":238},"12":{"loc":{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},{"start":{},"end":{}}],"line":240},"13":{"loc":{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},"type":"if","locations":[{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},{"start":{},"end":{}}],"line":243},"14":{"loc":{"start":{"line":247,"column":9},"end":{"line":247,"column":null}},"type":"cond-expr","locations":[{"start":{"line":247,"column":22},"end":{"line":247,"column":67}},{"start":{"line":247,"column":67},"end":{"line":247,"column":null}}],"line":247},"15":{"loc":{"start":{"line":264,"column":2},"end":{"line":264,"column":null}},"type":"default-arg","locations":[{"start":{"line":264,"column":24},"end":{"line":264,"column":null}}],"line":264},"16":{"loc":{"start":{"line":266,"column":14},"end":{"line":266,"column":null}},"type":"cond-expr","locations":[{"start":{"line":266,"column":41},"end":{"line":266,"column":73}},{"start":{"line":266,"column":73},"end":{"line":266,"column":null}}],"line":266},"17":{"loc":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},{"start":{},"end":{}}],"line":270},"18":{"loc":{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},"type":"if","locations":[{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},{"start":{},"end":{}}],"line":271},"19":{"loc":{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},"type":"if","locations":[{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},{"start":{},"end":{}}],"line":274},"20":{"loc":{"start":{"line":282,"column":20},"end":{"line":282,"column":null}},"type":"binary-expr","locations":[{"start":{"line":282,"column":20},"end":{"line":282,"column":41}},{"start":{"line":282,"column":41},"end":{"line":282,"column":null}}],"line":282},"21":{"loc":{"start":{"line":307,"column":2},"end":{"line":307,"column":null}},"type":"default-arg","locations":[{"start":{"line":307,"column":24},"end":{"line":307,"column":null}}],"line":307},"22":{"loc":{"start":{"line":309,"column":14},"end":{"line":309,"column":null}},"type":"cond-expr","locations":[{"start":{"line":309,"column":41},"end":{"line":309,"column":73}},{"start":{"line":309,"column":73},"end":{"line":309,"column":null}}],"line":309},"23":{"loc":{"start":{"line":318,"column":20},"end":{"line":320,"column":null}},"type":"cond-expr","locations":[{"start":{"line":319,"column":8},"end":{"line":319,"column":null}},{"start":{"line":320,"column":8},"end":{"line":320,"column":null}}],"line":318},"24":{"loc":{"start":{"line":318,"column":20},"end":{"line":318,"column":null}},"type":"binary-expr","locations":[{"start":{"line":318,"column":20},"end":{"line":318,"column":44}},{"start":{"line":318,"column":44},"end":{"line":318,"column":null}}],"line":318},"25":{"loc":{"start":{"line":321,"column":23},"end":{"line":321,"column":null}},"type":"cond-expr","locations":[{"start":{"line":321,"column":37},"end":{"line":321,"column":55}},{"start":{"line":321,"column":55},"end":{"line":321,"column":null}}],"line":321},"26":{"loc":{"start":{"line":328,"column":24},"end":{"line":328,"column":null}},"type":"binary-expr","locations":[{"start":{"line":328,"column":24},"end":{"line":328,"column":48}},{"start":{"line":328,"column":48},"end":{"line":328,"column":null}}],"line":328},"27":{"loc":{"start":{"line":329,"column":22},"end":{"line":331,"column":null}},"type":"cond-expr","locations":[{"start":{"line":330,"column":8},"end":{"line":330,"column":null}},{"start":{"line":331,"column":8},"end":{"line":331,"column":null}}],"line":329},"28":{"loc":{"start":{"line":356,"column":2},"end":{"line":356,"column":null}},"type":"default-arg","locations":[{"start":{"line":356,"column":24},"end":{"line":356,"column":null}}],"line":356},"29":{"loc":{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},"type":"if","locations":[{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},{"start":{},"end":{}}],"line":374},"30":{"loc":{"start":{"line":374,"column":6},"end":{"line":374,"column":61}},"type":"binary-expr","locations":[{"start":{"line":374,"column":6},"end":{"line":374,"column":25}},{"start":{"line":374,"column":25},"end":{"line":374,"column":42}},{"start":{"line":374,"column":42},"end":{"line":374,"column":61}}],"line":374},"31":{"loc":{"start":{"line":402,"column":5},"end":{"line":402,"column":23}},"type":"binary-expr","locations":[{"start":{"line":402,"column":5},"end":{"line":402,"column":21}},{"start":{"line":402,"column":21},"end":{"line":402,"column":23}}],"line":402},"32":{"loc":{"start":{"line":436,"column":37},"end":{"line":436,"column":76}},"type":"binary-expr","locations":[{"start":{"line":436,"column":37},"end":{"line":436,"column":53}},{"start":{"line":436,"column":53},"end":{"line":436,"column":76}}],"line":436},"33":{"loc":{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},"type":"if","locations":[{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},{"start":{},"end":{}}],"line":452},"34":{"loc":{"start":{"line":452,"column":6},"end":{"line":452,"column":73}},"type":"binary-expr","locations":[{"start":{"line":452,"column":6},"end":{"line":452,"column":31}},{"start":{"line":452,"column":31},"end":{"line":452,"column":73}}],"line":452},"35":{"loc":{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},"type":"if","locations":[{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},{"start":{},"end":{}}],"line":455},"36":{"loc":{"start":{"line":455,"column":6},"end":{"line":455,"column":72}},"type":"binary-expr","locations":[{"start":{"line":455,"column":6},"end":{"line":455,"column":28}},{"start":{"line":455,"column":28},"end":{"line":455,"column":72}}],"line":455},"37":{"loc":{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},"type":"if","locations":[{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},{"start":{},"end":{}}],"line":458},"38":{"loc":{"start":{"line":458,"column":6},"end":{"line":458,"column":57}},"type":"binary-expr","locations":[{"start":{"line":458,"column":6},"end":{"line":458,"column":23}},{"start":{"line":458,"column":23},"end":{"line":458,"column":57}}],"line":458},"39":{"loc":{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},"type":"if","locations":[{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},{"start":{},"end":{}}],"line":461},"40":{"loc":{"start":{"line":461,"column":6},"end":{"line":461,"column":59}},"type":"binary-expr","locations":[{"start":{"line":461,"column":6},"end":{"line":461,"column":24}},{"start":{"line":461,"column":24},"end":{"line":461,"column":59}}],"line":461},"41":{"loc":{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},"type":"if","locations":[{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},{"start":{},"end":{}}],"line":464},"42":{"loc":{"start":{"line":464,"column":6},"end":{"line":464,"column":80}},"type":"binary-expr","locations":[{"start":{"line":464,"column":6},"end":{"line":464,"column":30}},{"start":{"line":464,"column":30},"end":{"line":464,"column":80}}],"line":464},"43":{"loc":{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},{"start":{},"end":{}}],"line":467},"44":{"loc":{"start":{"line":467,"column":6},"end":{"line":467,"column":106}},"type":"binary-expr","locations":[{"start":{"line":467,"column":6},"end":{"line":467,"column":44}},{"start":{"line":467,"column":44},"end":{"line":467,"column":106}}],"line":467},"45":{"loc":{"start":{"line":467,"column":72},"end":{"line":467,"column":103}},"type":"binary-expr","locations":[{"start":{"line":467,"column":72},"end":{"line":467,"column":101}},{"start":{"line":467,"column":101},"end":{"line":467,"column":103}}],"line":467},"46":{"loc":{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},"type":"if","locations":[{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},{"start":{},"end":{}}],"line":471},"47":{"loc":{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},"type":"if","locations":[{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},{"start":{"line":476,"column":9},"end":{"line":478,"column":null}}],"line":474},"48":{"loc":{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},"type":"if","locations":[{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},{"start":{},"end":{}}],"line":476},"49":{"loc":{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},{"start":{},"end":{}}],"line":479},"50":{"loc":{"start":{"line":480,"column":4},"end":{"line":482,"column":null}},"type":"binary-expr","locations":[{"start":{"line":480,"column":4},"end":{"line":480,"column":null}},{"start":{"line":481,"column":5},"end":{"line":481,"column":null}},{"start":{"line":482,"column":6},"end":{"line":482,"column":null}}],"line":480},"51":{"loc":{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},"type":"if","locations":[{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},{"start":{},"end":{}}],"line":486},"52":{"loc":{"start":{"line":487,"column":4},"end":{"line":488,"column":null}},"type":"binary-expr","locations":[{"start":{"line":487,"column":4},"end":{"line":487,"column":null}},{"start":{"line":488,"column":4},"end":{"line":488,"column":null}}],"line":487},"53":{"loc":{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},"type":"if","locations":[{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},{"start":{},"end":{}}],"line":493},"54":{"loc":{"start":{"line":493,"column":6},"end":{"line":493,"column":83}},"type":"binary-expr","locations":[{"start":{"line":493,"column":6},"end":{"line":493,"column":52}},{"start":{"line":493,"column":52},"end":{"line":493,"column":83}}],"line":493},"55":{"loc":{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},"type":"if","locations":[{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},{"start":{},"end":{}}],"line":511},"56":{"loc":{"start":{"line":512,"column":19},"end":{"line":512,"column":56}},"type":"binary-expr","locations":[{"start":{"line":512,"column":19},"end":{"line":512,"column":43}},{"start":{"line":512,"column":43},"end":{"line":512,"column":56}}],"line":512},"57":{"loc":{"start":{"line":531,"column":2},"end":{"line":531,"column":null}},"type":"default-arg","locations":[{"start":{"line":531,"column":67},"end":{"line":531,"column":null}}],"line":531},"58":{"loc":{"start":{"line":548,"column":2},"end":{"line":548,"column":null}},"type":"default-arg","locations":[{"start":{"line":548,"column":80},"end":{"line":548,"column":null}}],"line":548},"59":{"loc":{"start":{"line":549,"column":2},"end":{"line":549,"column":null}},"type":"default-arg","locations":[{"start":{"line":549,"column":18},"end":{"line":549,"column":null}}],"line":549}},"s":{"0":1,"1":1,"2":1,"3":1,"4":7,"5":7,"6":7,"7":1,"8":6,"9":6,"10":6,"11":6,"12":6,"13":6,"14":6,"15":6,"16":12,"17":6,"18":22,"19":22,"20":6,"21":2,"22":4,"23":16,"24":15,"25":15,"26":7,"27":9,"28":10,"29":10,"30":10,"31":1,"32":9,"33":1,"34":8,"35":8,"36":6,"37":6,"38":6,"39":16,"40":1,"41":15,"42":7,"43":8,"44":8,"45":4,"46":6,"47":1,"48":8,"49":8,"50":8,"51":8,"52":6,"53":6,"54":6,"55":6,"56":6,"57":6,"58":6,"59":8,"60":3,"61":3,"62":3,"63":3,"64":3,"65":3,"66":3,"67":2,"68":1,"69":5,"70":5,"71":17,"72":16,"73":4,"74":16,"75":5,"76":5,"77":5,"78":14,"79":20,"80":20,"81":2,"82":20,"83":1,"84":20,"85":0,"86":20,"87":0,"88":20,"89":1,"90":20,"91":0,"92":20,"93":20,"94":1,"95":20,"96":0,"97":20,"98":21,"99":1,"100":20,"101":1,"102":20,"103":1,"104":20,"105":2,"106":20,"107":3,"108":3,"109":10,"110":10,"111":2,"112":3,"113":2,"114":2,"115":2,"116":2},"f":{"0":7,"1":12,"2":22,"3":10,"4":6,"5":1,"6":8,"7":6,"8":3,"9":5,"10":17,"11":16,"12":4,"13":16,"14":5,"15":14,"16":20,"17":21,"18":3,"19":2,"20":2},"b":{"0":[7],"1":[7,5],"2":[1,6],"3":[22],"4":[7,15],"5":[6,16],"6":[2,4],"7":[6,5,5],"8":[15,1],"9":[7,8],"10":[10],"11":[5,5],"12":[1,9],"13":[1,8],"14":[6,2],"15":[6],"16":[6,0],"17":[1,15],"18":[7,8],"19":[4,4],"20":[4,0],"21":[8],"22":[8,0],"23":[1,5],"24":[6,1],"25":[1,5],"26":[6,0],"27":[3,3],"28":[3],"29":[2,1],"30":[3,2,2],"31":[17,1],"32":[14,2],"33":[2,18],"34":[20,18],"35":[1,19],"36":[20,20],"37":[0,20],"38":[20,20],"39":[0,20],"40":[20,20],"41":[1,19],"42":[20,20],"43":[0,20],"44":[20,19],"45":[19,0],"46":[1,19],"47":[0,20],"48":[1,19],"49":[1,19],"50":[20,20,20],"51":[1,19],"52":[20,6],"53":[2,18],"54":[20,5],"55":[2,8],"56":[2,0],"57":[2],"58":[2],"59":[2]},"meta":{"lastBranch":60,"lastFunction":21,"lastStatement":117,"seen":{"s:119:46:119:Infinity":0,"s:126:34:126:Infinity":1,"s:129:36:129:Infinity":2,"s:132:36:132:Infinity":3,"f:156:16:156:Infinity":0,"b:158:39:158:Infinity":0,"s:160:17:160:Infinity":4,"b:160:17:160:43:160:43:160:Infinity":1,"s:161:14:161:Infinity":5,"b:162:2:164:Infinity:undefined:undefined:undefined:undefined":2,"s:162:2:164:Infinity":6,"s:163:4:163:Infinity":7,"s:165:15:165:Infinity":8,"s:166:16:166:Infinity":9,"s:167:14:167:Infinity":10,"s:169:23:169:Infinity":11,"s:170:8:170:Infinity":12,"s:172:30:172:Infinity":13,"s:173:22:173:Infinity":14,"s:175:8:175:Infinity":15,"f:175:8:175:15":1,"s:175:37:175:Infinity":16,"s:176:2:176:Infinity":17,"f:200:16:200:Infinity":2,"b:202:24:202:Infinity":3,"s:204:14:204:Infinity":18,"b:204:41:204:73:204:73:204:Infinity":4,"b:206:2:214:Infinity:undefined:undefined:undefined:undefined":5,"s:206:2:214:Infinity":19,"b:207:4:212:Infinity:undefined:undefined:undefined:undefined":6,"s:207:4:212:Infinity":20,"b:208:6:208:Infinity:209:7:209:58:209:58:209:Infinity":7,"s:211:6:211:Infinity":21,"s:213:4:213:Infinity":22,"b:216:2:221:Infinity:undefined:undefined:undefined:undefined":8,"s:216:2:221:Infinity":23,"s:217:21:217:Infinity":24,"b:218:4:220:Infinity:undefined:undefined:undefined:undefined":9,"s:218:4:220:Infinity":25,"s:219:6:219:Infinity":26,"s:223:2:223:Infinity":27,"f:234:16:234:Infinity":3,"b:236:24:236:Infinity":10,"s:238:14:238:Infinity":28,"b:238:41:238:73:238:73:238:Infinity":11,"s:239:19:239:Infinity":29,"b:240:2:242:Infinity:undefined:undefined:undefined:undefined":12,"s:240:2:242:Infinity":30,"s:241:4:241:Infinity":31,"b:243:2:245:Infinity:undefined:undefined:undefined:undefined":13,"s:243:2:245:Infinity":32,"s:244:4:244:Infinity":33,"s:246:17:246:Infinity":34,"s:247:2:247:Infinity":35,"b:247:22:247:67:247:67:247:Infinity":14,"f:262:16:262:Infinity":4,"b:264:24:264:Infinity":15,"s:266:14:266:Infinity":36,"b:266:41:266:73:266:73:266:Infinity":16,"s:267:37:267:Infinity":37,"s:269:2:286:Infinity":38,"b:270:4:270:Infinity:undefined:undefined:undefined:undefined":17,"s:270:4:270:Infinity":39,"s:270:36:270:Infinity":40,"b:271:4:271:Infinity:undefined:undefined:undefined:undefined":18,"s:271:4:271:Infinity":41,"s:271:38:271:Infinity":42,"s:273:19:273:Infinity":43,"b:274:4:285:Infinity:undefined:undefined:undefined:undefined":19,"s:274:4:285:Infinity":44,"s:275:6:284:Infinity":45,"b:282:20:282:41:282:41:282:Infinity":20,"s:288:2:288:Infinity":46,"f:288:16:288:22":5,"s:288:31:288:62":47,"f:305:16:305:Infinity":6,"b:307:24:307:Infinity":21,"s:309:14:309:Infinity":48,"b:309:41:309:73:309:73:309:Infinity":22,"s:312:4:312:Infinity":49,"s:314:4:314:Infinity":50,"s:316:15:333:Infinity":51,"f:316:23:316:28":7,"s:317:19:317:Infinity":52,"s:318:20:320:Infinity":53,"b:319:8:319:Infinity:320:8:320:Infinity":23,"b:318:20:318:44:318:44:318:Infinity":24,"s:321:23:321:Infinity":54,"b:321:37:321:55:321:55:321:Infinity":25,"s:322:24:327:Infinity":55,"s:328:24:328:Infinity":56,"b:328:24:328:48:328:48:328:Infinity":26,"s:329:22:331:Infinity":57,"b:330:8:330:Infinity:331:8:331:Infinity":27,"s:332:4:332:Infinity":58,"s:335:2:335:Infinity":59,"f:353:16:353:Infinity":8,"b:356:24:356:Infinity":28,"s:358:16:358:Infinity":60,"s:359:16:367:Infinity":61,"s:369:22:369:Infinity":62,"s:370:20:370:Infinity":63,"s:371:19:371:Infinity":64,"s:372:17:372:Infinity":65,"b:374:2:380:Infinity:undefined:undefined:undefined:undefined":29,"s:374:2:380:Infinity":66,"b:374:6:374:25:374:25:374:42:374:42:374:61":30,"s:375:4:378:Infinity":67,"s:382:2:382:Infinity":68,"f:396:16:396:Infinity":9,"s:400:13:400:Infinity":69,"s:401:2:403:Infinity":70,"f:401:17:401:25":10,"s:401:25:402:Infinity":71,"b:402:5:402:21:402:21:402:23":31,"f:402:25:402:31":11,"s:402:37:402:59":72,"f:412:16:412:Infinity":12,"s:416:2:416:Infinity":73,"f:416:17:416:25":13,"s:416:31:416:63":74,"f:425:16:425:Infinity":14,"s:429:46:434:Infinity":75,"s:435:20:435:Infinity":76,"s:436:2:436:Infinity":77,"f:436:17:436:25":15,"s:436:31:436:85":78,"b:436:37:436:53:436:53:436:76":32,"f:449:16:449:34":16,"s:450:27:450:Infinity":79,"b:452:2:454:Infinity:undefined:undefined:undefined:undefined":33,"s:452:2:454:Infinity":80,"b:452:6:452:31:452:31:452:73":34,"s:453:4:453:Infinity":81,"b:455:2:457:Infinity:undefined:undefined:undefined:undefined":35,"s:455:2:457:Infinity":82,"b:455:6:455:28:455:28:455:72":36,"s:456:4:456:Infinity":83,"b:458:2:460:Infinity:undefined:undefined:undefined:undefined":37,"s:458:2:460:Infinity":84,"b:458:6:458:23:458:23:458:57":38,"s:459:4:459:Infinity":85,"b:461:2:463:Infinity:undefined:undefined:undefined:undefined":39,"s:461:2:463:Infinity":86,"b:461:6:461:24:461:24:461:59":40,"s:462:4:462:Infinity":87,"b:464:2:466:Infinity:undefined:undefined:undefined:undefined":41,"s:464:2:466:Infinity":88,"b:464:6:464:30:464:30:464:80":42,"s:465:4:465:Infinity":89,"b:467:2:469:Infinity:undefined:undefined:undefined:undefined":43,"s:467:2:469:Infinity":90,"b:467:6:467:44:467:44:467:106":44,"b:467:72:467:101:467:101:467:103":45,"s:468:4:468:Infinity":91,"s:470:45:470:Infinity":92,"b:471:2:473:Infinity:undefined:undefined:undefined:undefined":46,"s:471:2:473:Infinity":93,"s:472:4:472:Infinity":94,"b:474:2:478:Infinity:476:9:478:Infinity":47,"s:474:2:478:Infinity":95,"s:475:4:475:Infinity":96,"b:476:9:478:Infinity:undefined:undefined:undefined:undefined":48,"s:476:9:478:Infinity":97,"f:476:52:476:59":17,"s:476:66:476:88":98,"s:477:4:477:Infinity":99,"b:479:2:485:Infinity:undefined:undefined:undefined:undefined":49,"s:479:2:485:Infinity":100,"b:480:4:480:Infinity:481:5:481:Infinity:482:6:482:Infinity":50,"s:484:4:484:Infinity":101,"b:486:2:491:Infinity:undefined:undefined:undefined:undefined":51,"s:486:2:491:Infinity":102,"b:487:4:487:Infinity:488:4:488:Infinity":52,"s:490:4:490:Infinity":103,"b:493:2:495:Infinity:undefined:undefined:undefined:undefined":53,"s:493:2:495:Infinity":104,"b:493:6:493:52:493:52:493:83":54,"s:494:4:494:Infinity":105,"s:497:2:497:Infinity":106,"f:505:16:505:Infinity":18,"s:508:19:508:Infinity":107,"s:509:2:514:Infinity":108,"s:510:19:510:Infinity":109,"b:511:4:513:Infinity:undefined:undefined:undefined:undefined":55,"s:511:4:513:Infinity":110,"s:512:6:512:Infinity":111,"b:512:19:512:43:512:43:512:56":56,"s:515:2:515:Infinity":112,"f:529:16:529:Infinity":19,"b:531:67:531:Infinity":57,"s:533:14:533:Infinity":113,"s:534:2:534:Infinity":114,"f:545:16:545:Infinity":20,"b:548:80:548:Infinity":58,"b:549:18:549:Infinity":59,"s:552:4:556:Infinity":115,"s:557:2:557:Infinity":116}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/confidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/confidence.ts","statementMap":{"0":{"start":{"line":18,"column":14},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},"2":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"4":{"start":{"line":22,"column":42},"end":{"line":22,"column":null}},"5":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}}},"fnMap":{"0":{"name":"degrade","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":24}},"loc":{"start":{"line":17,"column":51},"end":{"line":24,"column":null}},"line":17}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":19},"1":{"loc":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"type":"if","locations":[{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},{"start":{},"end":{}}],"line":22}},"s":{"0":35,"1":35,"2":1,"3":34,"4":2,"5":32},"f":{"0":35},"b":{"0":[1,34],"1":[2,32]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":6,"seen":{"f:17:16:17:24":0,"s:18:14:18:Infinity":0,"b:19:2:21:Infinity:undefined:undefined:undefined:undefined":0,"s:19:2:21:Infinity":1,"s:20:4:20:Infinity":2,"b:22:2:22:Infinity:undefined:undefined:undefined:undefined":1,"s:22:2:22:Infinity":3,"s:22:42:22:Infinity":4,"s:23:2:23:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/constants.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/constants.ts","statementMap":{"0":{"start":{"line":16,"column":18},"end":{"line":16,"column":null}},"1":{"start":{"line":19,"column":25},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":28},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":24},"end":{"line":21,"column":null}},"4":{"start":{"line":23,"column":28},"end":{"line":37,"column":null}},"5":{"start":{"line":39,"column":30},"end":{"line":45,"column":null}},"6":{"start":{"line":47,"column":46},"end":{"line":53,"column":null}},"7":{"start":{"line":54,"column":33},"end":{"line":54,"column":null}},"8":{"start":{"line":55,"column":30},"end":{"line":55,"column":null}},"9":{"start":{"line":62,"column":61},"end":{"line":76,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":4},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":10,"seen":{"s:16:18:16:Infinity":0,"s:19:25:19:Infinity":1,"s:20:28:20:Infinity":2,"s:21:24:21:Infinity":3,"s:23:28:37:Infinity":4,"s:39:30:45:Infinity":5,"s:47:46:53:Infinity":6,"s:54:33:54:Infinity":7,"s:55:30:55:Infinity":8,"s:62:61:76:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/date-helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/date-helpers.ts","statementMap":{"0":{"start":{"line":12,"column":12},"end":{"line":12,"column":null}},"1":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"2":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"3":{"start":{"line":19,"column":12},"end":{"line":19,"column":null}},"4":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"5":{"start":{"line":21,"column":2},"end":{"line":21,"column":null}}},"fnMap":{"0":{"name":"subtractDays","decl":{"start":{"line":11,"column":16},"end":{"line":11,"column":29}},"loc":{"start":{"line":11,"column":65},"end":{"line":15,"column":null}},"line":11},"1":{"name":"addDays","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":24}},"loc":{"start":{"line":18,"column":60},"end":{"line":22,"column":null}},"line":18}},"branchMap":{},"s":{"0":47,"1":47,"2":47,"3":39,"4":39,"5":39},"f":{"0":47,"1":39},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":6,"seen":{"f:11:16:11:29":0,"s:12:12:12:Infinity":0,"s:13:2:13:Infinity":1,"s:14:2:14:Infinity":2,"f:18:16:18:24":1,"s:19:12:19:Infinity":3,"s:20:2:20:Infinity":4,"s:21:2:21:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/horizon.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/horizon.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},"2":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"3":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"4":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"5":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}}},"fnMap":{"0":{"name":"isLongHorizon","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":57},"end":{"line":19,"column":null}},"line":17},"1":{"name":"determineOrigin","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"loc":{"start":{"line":30,"column":28},"end":{"line":38,"column":null}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":31},"1":{"loc":{"start":{"line":32,"column":11},"end":{"line":32,"column":null}},"type":"cond-expr","locations":[{"start":{"line":32,"column":42},"end":{"line":32,"column":56}},{"start":{"line":32,"column":56},"end":{"line":32,"column":null}}],"line":32},"2":{"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":37,"column":9},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":61},"end":{"line":37,"column":75}},{"start":{"line":37,"column":75},"end":{"line":37,"column":null}}],"line":37},"4":{"loc":{"start":{"line":37,"column":9},"end":{"line":37,"column":61}},"type":"binary-expr","locations":[{"start":{"line":37,"column":9},"end":{"line":37,"column":30}},{"start":{"line":37,"column":30},"end":{"line":37,"column":61}}],"line":37}},"s":{"0":14,"1":33,"2":15,"3":18,"4":18,"5":0},"f":{"0":14,"1":33},"b":{"0":[15,18],"1":[14,1],"2":[18,0],"3":[0,0],"4":[0,0]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":6,"seen":{"f:17:16:17:30":0,"s:18:2:18:Infinity":0,"f:26:16:26:Infinity":1,"b:31:2:33:Infinity:undefined:undefined:undefined:undefined":0,"s:31:2:33:Infinity":1,"s:32:4:32:Infinity":2,"b:32:42:32:56:32:56:32:Infinity":1,"b:34:2:36:Infinity:undefined:undefined:undefined:undefined":2,"s:34:2:36:Infinity":3,"s:35:4:35:Infinity":4,"s:37:2:37:Infinity":5,"b:37:61:37:75:37:75:37:Infinity":3,"b:37:9:37:30:37:30:37:61":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/emitter.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/emitter.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"2":{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"5":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"6":{"start":{"line":48,"column":22},"end":{"line":48,"column":null}},"7":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"8":{"start":{"line":52,"column":21},"end":{"line":57,"column":null}},"9":{"start":{"line":54,"column":22},"end":{"line":54,"column":null}},"10":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"11":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"12":{"start":{"line":67,"column":26},"end":{"line":67,"column":null}},"13":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"14":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"15":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"16":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"17":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"18":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"19":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"20":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"21":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"22":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"24":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"25":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"26":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"27":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"28":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"29":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"30":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"31":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"32":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"33":{"start":{"line":92,"column":2},"end":{"line":103,"column":null}},"34":{"start":{"line":93,"column":19},"end":{"line":93,"column":null}},"35":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"36":{"start":{"line":97,"column":6},"end":{"line":99,"column":null}},"37":{"start":{"line":100,"column":4},"end":{"line":102,"column":null}},"38":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"39":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"40":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"41":{"start":{"line":108,"column":19},"end":{"line":108,"column":null}},"42":{"start":{"line":108,"column":45},"end":{"line":108,"column":64}},"43":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"44":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"45":{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},"46":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"47":{"start":{"line":114,"column":4},"end":{"line":126,"column":null}},"48":{"start":{"line":115,"column":6},"end":{"line":115,"column":null}},"49":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"50":{"start":{"line":117,"column":6},"end":{"line":117,"column":null}},"51":{"start":{"line":118,"column":6},"end":{"line":118,"column":null}},"52":{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},"53":{"start":{"line":120,"column":8},"end":{"line":120,"column":null}},"54":{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},"55":{"start":{"line":123,"column":8},"end":{"line":123,"column":null}},"56":{"start":{"line":125,"column":6},"end":{"line":125,"column":null}},"57":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"58":{"start":{"line":129,"column":2},"end":{"line":129,"column":null}},"59":{"start":{"line":131,"column":23},"end":{"line":131,"column":null}},"60":{"start":{"line":131,"column":49},"end":{"line":131,"column":68}},"61":{"start":{"line":132,"column":2},"end":{"line":132,"column":null}},"62":{"start":{"line":133,"column":2},"end":{"line":133,"column":null}},"63":{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},"64":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"65":{"start":{"line":137,"column":4},"end":{"line":137,"column":null}},"66":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"67":{"start":{"line":139,"column":4},"end":{"line":142,"column":null}},"68":{"start":{"line":140,"column":20},"end":{"line":140,"column":null}},"69":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"70":{"start":{"line":144,"column":2},"end":{"line":144,"column":null}},"71":{"start":{"line":146,"column":2},"end":{"line":146,"column":null}}},"fnMap":{"0":{"name":"emitRollforwardMd","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":147,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":52,"column":28},"end":{"line":52,"column":null}},"loc":{"start":{"line":53,"column":13},"end":{"line":56,"column":7}},"line":53},"2":{"name":"(anonymous_2)","decl":{"start":{"line":108,"column":31},"end":{"line":108,"column":39}},"loc":{"start":{"line":108,"column":45},"end":{"line":108,"column":64}},"line":108},"3":{"name":"(anonymous_3)","decl":{"start":{"line":131,"column":35},"end":{"line":131,"column":43}},"loc":{"start":{"line":131,"column":49},"end":{"line":131,"column":68}},"line":131}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":63},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":19},"end":{"line":38,"column":39}},{"start":{"line":38,"column":39},"end":{"line":38,"column":null}}],"line":38},"2":{"loc":{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},{"start":{"line":47,"column":9},"end":{"line":50,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":52,"column":21},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":28},"end":{"line":56,"column":null}},{"start":{"line":57,"column":6},"end":{"line":57,"column":null}}],"line":52},"5":{"loc":{"start":{"line":55,"column":15},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":23},"end":{"line":55,"column":34}},{"start":{"line":55,"column":34},"end":{"line":55,"column":null}}],"line":55},"6":{"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":8},"end":{"line":64,"column":null}},{"start":{"line":65,"column":8},"end":{"line":65,"column":null}}],"line":59},"7":{"loc":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"type":"cond-expr","locations":[{"start":{"line":95,"column":30},"end":{"line":95,"column":65}},{"start":{"line":95,"column":65},"end":{"line":95,"column":null}}],"line":95},"8":{"loc":{"start":{"line":97,"column":6},"end":{"line":99,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":10},"end":{"line":98,"column":null}},{"start":{"line":99,"column":10},"end":{"line":99,"column":null}}],"line":97},"9":{"loc":{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},{"start":{"line":113,"column":9},"end":{"line":127,"column":null}}],"line":111},"10":{"loc":{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":119},"11":{"loc":{"start":{"line":119,"column":10},"end":{"line":119,"column":61}},"type":"binary-expr","locations":[{"start":{"line":119,"column":10},"end":{"line":119,"column":31}},{"start":{"line":119,"column":31},"end":{"line":119,"column":61}}],"line":119},"12":{"loc":{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":122},"13":{"loc":{"start":{"line":122,"column":10},"end":{"line":122,"column":61}},"type":"binary-expr","locations":[{"start":{"line":122,"column":10},"end":{"line":122,"column":31}},{"start":{"line":122,"column":31},"end":{"line":122,"column":61}}],"line":122},"14":{"loc":{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},{"start":{"line":136,"column":9},"end":{"line":143,"column":null}}],"line":134},"15":{"loc":{"start":{"line":140,"column":20},"end":{"line":140,"column":null}},"type":"cond-expr","locations":[{"start":{"line":140,"column":41},"end":{"line":140,"column":62}},{"start":{"line":140,"column":62},"end":{"line":140,"column":null}}],"line":140}},"s":{"0":16,"1":16,"2":16,"3":16,"4":16,"5":0,"6":0,"7":0,"8":16,"9":16,"10":16,"11":16,"12":16,"13":16,"14":16,"15":16,"16":16,"17":16,"18":16,"19":16,"20":16,"21":16,"22":16,"23":16,"24":16,"25":16,"26":16,"27":16,"28":16,"29":16,"30":16,"31":16,"32":16,"33":16,"34":33,"35":33,"36":33,"37":33,"38":16,"39":16,"40":16,"41":16,"42":33,"43":16,"44":16,"45":16,"46":0,"47":16,"48":17,"49":17,"50":17,"51":17,"52":17,"53":16,"54":17,"55":16,"56":17,"57":16,"58":16,"59":16,"60":33,"61":16,"62":16,"63":16,"64":0,"65":16,"66":16,"67":16,"68":16,"69":16,"70":16,"71":16},"f":{"0":16,"1":16,"2":33,"3":33},"b":{"0":[16],"1":[16,5],"2":[16,0],"3":[0,16],"4":[16,0],"5":[16,0],"6":[16,0],"7":[17,16],"8":[17,16],"9":[0,16],"10":[16,1],"11":[17,17],"12":[16,1],"13":[17,17],"14":[0,16],"15":[16,0]},"meta":{"lastBranch":16,"lastFunction":4,"lastStatement":72,"seen":{"f:32:16:32:Infinity":0,"b:36:63:36:Infinity":0,"s:38:19:38:Infinity":0,"b:38:19:38:39:38:39:38:Infinity":1,"s:39:22:39:Infinity":1,"b:42:2:50:Infinity:47:9:50:Infinity":2,"s:42:2:50:Infinity":2,"s:43:4:43:Infinity":3,"b:44:4:46:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:46:Infinity":4,"s:45:6:45:Infinity":5,"s:48:22:48:Infinity":6,"s:49:4:49:Infinity":7,"s:52:21:57:Infinity":8,"b:52:28:56:Infinity:57:6:57:Infinity":4,"f:52:28:52:Infinity":1,"s:54:22:54:Infinity":9,"s:55:8:55:Infinity":10,"b:55:23:55:34:55:34:55:Infinity":5,"s:59:4:65:Infinity":11,"b:60:8:64:Infinity:65:8:65:Infinity":6,"s:67:26:67:Infinity":12,"s:69:2:69:Infinity":13,"s:70:2:70:Infinity":14,"s:71:2:71:Infinity":15,"s:72:2:72:Infinity":16,"s:73:2:73:Infinity":17,"s:74:2:74:Infinity":18,"s:75:2:75:Infinity":19,"s:77:2:77:Infinity":20,"s:78:2:78:Infinity":21,"s:79:2:79:Infinity":22,"s:80:2:80:Infinity":23,"s:81:2:81:Infinity":24,"s:82:2:82:Infinity":25,"s:83:2:83:Infinity":26,"s:84:2:84:Infinity":27,"s:85:2:85:Infinity":28,"s:87:2:87:Infinity":29,"s:88:2:88:Infinity":30,"s:89:2:89:Infinity":31,"s:90:2:90:Infinity":32,"s:92:2:103:Infinity":33,"s:93:19:93:Infinity":34,"s:95:6:95:Infinity":35,"b:95:30:95:65:95:65:95:Infinity":7,"s:97:6:99:Infinity":36,"b:98:10:98:Infinity:99:10:99:Infinity":8,"s:100:4:102:Infinity":37,"s:104:2:104:Infinity":38,"s:105:2:105:Infinity":39,"s:106:2:106:Infinity":40,"s:108:19:108:Infinity":41,"f:108:31:108:39":2,"s:108:45:108:64":42,"s:109:2:109:Infinity":43,"s:110:2:110:Infinity":44,"b:111:2:127:Infinity:113:9:127:Infinity":9,"s:111:2:127:Infinity":45,"s:112:4:112:Infinity":46,"s:114:4:126:Infinity":47,"s:115:6:115:Infinity":48,"s:116:6:116:Infinity":49,"s:117:6:117:Infinity":50,"s:118:6:118:Infinity":51,"b:119:6:121:Infinity:undefined:undefined:undefined:undefined":10,"s:119:6:121:Infinity":52,"b:119:10:119:31:119:31:119:61":11,"s:120:8:120:Infinity":53,"b:122:6:124:Infinity:undefined:undefined:undefined:undefined":12,"s:122:6:124:Infinity":54,"b:122:10:122:31:122:31:122:61":13,"s:123:8:123:Infinity":55,"s:125:6:125:Infinity":56,"s:128:2:128:Infinity":57,"s:129:2:129:Infinity":58,"s:131:23:131:Infinity":59,"f:131:35:131:43":3,"s:131:49:131:68":60,"s:132:2:132:Infinity":61,"s:133:2:133:Infinity":62,"b:134:2:143:Infinity:136:9:143:Infinity":14,"s:134:2:143:Infinity":63,"s:135:4:135:Infinity":64,"s:137:4:137:Infinity":65,"s:138:4:138:Infinity":66,"s:139:4:142:Infinity":67,"s:140:20:140:Infinity":68,"b:140:41:140:62:140:62:140:Infinity":15,"s:141:6:141:Infinity":69,"s:144:2:144:Infinity":70,"s:146:2:146:Infinity":71}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/roll-forward.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/roll-forward.ts","statementMap":{"0":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"1":{"start":{"line":33,"column":36},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"3":{"start":{"line":36,"column":27},"end":{"line":47,"column":null}},"4":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"5":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"6":{"start":{"line":40,"column":50},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":4},"end":{"line":46,"column":null}},"9":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"10":{"start":{"line":51,"column":4},"end":{"line":55,"column":null}},"11":{"start":{"line":57,"column":2},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"rollForward","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"loc":{"start":{"line":32,"column":17},"end":{"line":66,"column":null}},"line":32},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":22},"end":{"line":33,"column":36}},"loc":{"start":{"line":33,"column":36},"end":{"line":33,"column":null}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":39},"end":{"line":36,"column":44}},"loc":{"start":{"line":36,"column":50},"end":{"line":47,"column":3}},"line":36}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"default-arg","locations":[{"start":{"line":31,"column":53},"end":{"line":31,"column":null}}],"line":31},"1":{"loc":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":14},"end":{"line":33,"column":36}},{"start":{"line":33,"column":22},"end":{"line":33,"column":null}}],"line":33},"2":{"loc":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":19},"end":{"line":34,"column":39}},{"start":{"line":34,"column":39},"end":{"line":34,"column":null}}],"line":34},"3":{"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"4":{"loc":{"start":{"line":45,"column":26},"end":{"line":45,"column":50}},"type":"binary-expr","locations":[{"start":{"line":45,"column":26},"end":{"line":45,"column":45}},{"start":{"line":45,"column":45},"end":{"line":45,"column":50}}],"line":45},"5":{"loc":{"start":{"line":51,"column":4},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},{"start":{"line":55,"column":8},"end":{"line":55,"column":null}}],"line":51},"6":{"loc":{"start":{"line":51,"column":4},"end":{"line":53,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},{"start":{"line":53,"column":4},"end":{"line":53,"column":null}}],"line":51}},"s":{"0":30,"1":2,"2":30,"3":30,"4":56,"5":27,"6":29,"7":29,"8":29,"9":30,"10":30,"11":30},"f":{"0":30,"1":2,"2":56},"b":{"0":[30],"1":[30,2],"2":[30,16],"3":[27,29],"4":[29,2],"5":[13,17],"6":[30,30,13]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":12,"seen":{"f:26:16:26:Infinity":0,"b:31:53:31:Infinity":0,"s:33:14:33:Infinity":0,"b:33:14:33:36:33:22:33:Infinity":1,"f:33:22:33:36":1,"s:33:36:33:Infinity":1,"s:34:19:34:Infinity":2,"b:34:19:34:39:34:39:34:Infinity":2,"s:36:27:47:Infinity":3,"f:36:39:36:44":2,"b:37:4:39:Infinity:undefined:undefined:undefined:undefined":3,"s:37:4:39:Infinity":4,"s:38:6:38:Infinity":5,"s:40:50:40:Infinity":6,"s:41:4:41:Infinity":7,"s:42:4:46:Infinity":8,"b:45:26:45:45:45:45:45:50":4,"s:49:25:49:Infinity":9,"s:51:4:55:Infinity":10,"b:54:8:54:Infinity:55:8:55:Infinity":5,"b:51:4:51:Infinity:52:4:52:Infinity:53:4:53:Infinity":6,"s:57:2:65:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/source-locator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/source-locator.ts","statementMap":{"0":{"start":{"line":26,"column":2},"end":{"line":34,"column":null}},"1":{"start":{"line":26,"column":15},"end":{"line":26,"column":18}},"2":{"start":{"line":27,"column":22},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"4":{"start":{"line":33,"column":34},"end":{"line":33,"column":null}},"5":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}}},"fnMap":{"0":{"name":"findLatestSource","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":null}},"loc":{"start":{"line":25,"column":17},"end":{"line":36,"column":null}},"line":25}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"default-arg","locations":[{"start":{"line":23,"column":16},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"default-arg","locations":[{"start":{"line":24,"column":24},"end":{"line":24,"column":null}}],"line":24},"2":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33}},"s":{"0":5,"1":5,"2":38,"3":38,"4":2,"5":3},"f":{"0":5},"b":{"0":[5],"1":[5],"2":[2,36]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":6,"seen":{"f:20:16:20:Infinity":0,"b:23:16:23:Infinity":0,"b:24:24:24:Infinity":1,"s:26:2:34:Infinity":0,"s:26:15:26:18":1,"s:27:22:32:Infinity":2,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":2,"s:33:4:33:Infinity":3,"s:33:34:33:Infinity":4,"s:35:2:35:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/validator.ts","statementMap":{"0":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":34,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"5":{"start":{"line":33,"column":23},"end":{"line":33,"column":null}},"6":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"7":{"start":{"line":36,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},"9":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"10":{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},"11":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"12":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"13":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},"15":{"start":{"line":50,"column":4},"end":{"line":52,"column":null}},"16":{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},"17":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"18":{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},"19":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"20":{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},"21":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"22":{"start":{"line":67,"column":2},"end":{"line":103,"column":null}},"23":{"start":{"line":67,"column":15},"end":{"line":67,"column":18}},"24":{"start":{"line":68,"column":15},"end":{"line":68,"column":null}},"25":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"26":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"27":{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},"28":{"start":{"line":73,"column":6},"end":{"line":75,"column":null}},"29":{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},"30":{"start":{"line":78,"column":6},"end":{"line":80,"column":null}},"31":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"32":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"33":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"34":{"start":{"line":88,"column":6},"end":{"line":90,"column":null}},"35":{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},"36":{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},"37":{"start":{"line":94,"column":8},"end":{"line":96,"column":null}},"38":{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},"39":{"start":{"line":99,"column":6},"end":{"line":101,"column":null}},"40":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}}},"fnMap":{"0":{"name":"validateSource","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":31}},"loc":{"start":{"line":27,"column":78},"end":{"line":105,"column":null}},"line":27}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":28,"column":6},"end":{"line":28,"column":47}},"type":"binary-expr","locations":[{"start":{"line":28,"column":6},"end":{"line":28,"column":33}},{"start":{"line":28,"column":33},"end":{"line":28,"column":47}}],"line":28},"2":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"3":{"loc":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":35},"4":{"loc":{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":40},"5":{"loc":{"start":{"line":40,"column":6},"end":{"line":40,"column":88}},"type":"binary-expr","locations":[{"start":{"line":40,"column":6},"end":{"line":40,"column":42}},{"start":{"line":40,"column":42},"end":{"line":40,"column":88}}],"line":40},"6":{"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":43},"7":{"loc":{"start":{"line":43,"column":6},"end":{"line":43,"column":83}},"type":"binary-expr","locations":[{"start":{"line":43,"column":6},"end":{"line":43,"column":41}},{"start":{"line":43,"column":41},"end":{"line":43,"column":83}}],"line":43},"8":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"9":{"loc":{"start":{"line":46,"column":6},"end":{"line":46,"column":77}},"type":"binary-expr","locations":[{"start":{"line":46,"column":6},"end":{"line":46,"column":46}},{"start":{"line":46,"column":46},"end":{"line":46,"column":77}}],"line":46},"10":{"loc":{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":49},"11":{"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":54},"12":{"loc":{"start":{"line":54,"column":6},"end":{"line":54,"column":96}},"type":"binary-expr","locations":[{"start":{"line":54,"column":6},"end":{"line":54,"column":49}},{"start":{"line":54,"column":49},"end":{"line":54,"column":96}}],"line":54},"13":{"loc":{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":57},"14":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},{"start":{"line":59,"column":4},"end":{"line":59,"column":null}},{"start":{"line":60,"column":4},"end":{"line":60,"column":null}}],"line":58},"15":{"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"16":{"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69},"17":{"loc":{"start":{"line":69,"column":8},"end":{"line":69,"column":45}},"type":"binary-expr","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":33}},{"start":{"line":69,"column":33},"end":{"line":69,"column":45}}],"line":69},"18":{"loc":{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":72},"19":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":78}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":43}},{"start":{"line":72,"column":43},"end":{"line":72,"column":78}}],"line":72},"20":{"loc":{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":77},"21":{"loc":{"start":{"line":77,"column":8},"end":{"line":77,"column":74}},"type":"binary-expr","locations":[{"start":{"line":77,"column":8},"end":{"line":77,"column":46}},{"start":{"line":77,"column":46},"end":{"line":77,"column":74}}],"line":77},"22":{"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"23":{"loc":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":87},"24":{"loc":{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},{"start":{"line":98,"column":11},"end":{"line":102,"column":null}}],"line":92},"25":{"loc":{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},{"start":{},"end":{}}],"line":93},"26":{"loc":{"start":{"line":93,"column":10},"end":{"line":93,"column":87}},"type":"binary-expr","locations":[{"start":{"line":93,"column":10},"end":{"line":93,"column":53}},{"start":{"line":93,"column":53},"end":{"line":93,"column":87}}],"line":93},"27":{"loc":{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":98}},"s":{"0":30,"1":2,"2":28,"3":28,"4":159,"5":2,"6":26,"7":1,"8":25,"9":1,"10":24,"11":1,"12":23,"13":1,"14":22,"15":1,"16":21,"17":1,"18":20,"19":1,"20":19,"21":1,"22":18,"23":18,"24":28,"25":28,"26":1,"27":27,"28":1,"29":26,"30":1,"31":25,"32":1,"33":24,"34":2,"35":22,"36":11,"37":1,"38":11,"39":1,"40":10},"f":{"0":30},"b":{"0":[2,28],"1":[30,29],"2":[2,157],"3":[1,25],"4":[1,24],"5":[25,25],"6":[1,23],"7":[24,24],"8":[1,22],"9":[23,23],"10":[1,21],"11":[1,20],"12":[21,21],"13":[1,19],"14":[20,20,1],"15":[1,18],"16":[1,27],"17":[28,27],"18":[1,26],"19":[27,27],"20":[1,25],"21":[26,26],"22":[1,24],"23":[2,22],"24":[11,11],"25":[1,10],"26":[11,10],"27":[1,10]},"meta":{"lastBranch":28,"lastFunction":1,"lastStatement":41,"seen":{"f:27:16:27:31":0,"b:28:2:30:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:30:Infinity":0,"b:28:6:28:33:28:33:28:47":1,"s:29:4:29:Infinity":1,"s:31:14:31:Infinity":2,"s:32:2:34:Infinity":3,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":2,"s:33:4:33:Infinity":4,"s:33:23:33:Infinity":5,"b:35:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:35:2:39:Infinity":6,"s:36:4:38:Infinity":7,"b:40:2:42:Infinity:undefined:undefined:undefined:undefined":4,"s:40:2:42:Infinity":8,"b:40:6:40:42:40:42:40:88":5,"s:41:4:41:Infinity":9,"b:43:2:45:Infinity:undefined:undefined:undefined:undefined":6,"s:43:2:45:Infinity":10,"b:43:6:43:41:43:41:43:83":7,"s:44:4:44:Infinity":11,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":8,"s:46:2:48:Infinity":12,"b:46:6:46:46:46:46:46:77":9,"s:47:4:47:Infinity":13,"b:49:2:53:Infinity:undefined:undefined:undefined:undefined":10,"s:49:2:53:Infinity":14,"s:50:4:52:Infinity":15,"b:54:2:56:Infinity:undefined:undefined:undefined:undefined":11,"s:54:2:56:Infinity":16,"b:54:6:54:49:54:49:54:96":12,"s:55:4:55:Infinity":17,"b:57:2:63:Infinity:undefined:undefined:undefined:undefined":13,"s:57:2:63:Infinity":18,"b:58:4:58:Infinity:59:4:59:Infinity:60:4:60:Infinity":14,"s:62:4:62:Infinity":19,"b:64:2:66:Infinity:undefined:undefined:undefined:undefined":15,"s:64:2:66:Infinity":20,"s:65:4:65:Infinity":21,"s:67:2:103:Infinity":22,"s:67:15:67:18":23,"s:68:15:68:Infinity":24,"b:69:4:71:Infinity:undefined:undefined:undefined:undefined":16,"s:69:4:71:Infinity":25,"b:69:8:69:33:69:33:69:45":17,"s:70:6:70:Infinity":26,"b:72:4:76:Infinity:undefined:undefined:undefined:undefined":18,"s:72:4:76:Infinity":27,"b:72:8:72:43:72:43:72:78":19,"s:73:6:75:Infinity":28,"b:77:4:81:Infinity:undefined:undefined:undefined:undefined":20,"s:77:4:81:Infinity":29,"b:77:8:77:46:77:46:77:74":21,"s:78:6:80:Infinity":30,"b:82:4:86:Infinity:undefined:undefined:undefined:undefined":22,"s:82:4:86:Infinity":31,"s:83:6:85:Infinity":32,"b:87:4:91:Infinity:undefined:undefined:undefined:undefined":23,"s:87:4:91:Infinity":33,"s:88:6:90:Infinity":34,"b:92:4:102:Infinity:98:11:102:Infinity":24,"s:92:4:102:Infinity":35,"b:93:6:97:Infinity:undefined:undefined:undefined:undefined":25,"s:93:6:97:Infinity":36,"b:93:10:93:53:93:53:93:87":26,"s:94:8:96:Infinity":37,"b:98:11:102:Infinity:undefined:undefined:undefined:undefined":27,"s:98:11:102:Infinity":38,"s:99:6:101:Infinity":39,"s:104:2:104:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss-watch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss-watch.ts","statementMap":{"0":{"start":{"line":37,"column":18},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"2":{"start":{"line":39,"column":34},"end":{"line":39,"column":null}},"3":{"start":{"line":43,"column":36},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":38},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"6":{"start":{"line":49,"column":20},"end":{"line":49,"column":null}},"7":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"8":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"9":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"10":{"start":{"line":61,"column":27},"end":{"line":61,"column":null}},"11":{"start":{"line":62,"column":2},"end":{"line":75,"column":null}},"12":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"13":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"14":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"15":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"17":{"start":{"line":67,"column":34},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":4},"end":{"line":74,"column":null}},"19":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"20":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"21":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"22":{"start":{"line":88,"column":24},"end":{"line":90,"column":null}},"23":{"start":{"line":89,"column":20},"end":{"line":89,"column":46}},"24":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"25":{"start":{"line":91,"column":34},"end":{"line":91,"column":null}},"26":{"start":{"line":92,"column":2},"end":{"line":97,"column":null}},"27":{"start":{"line":93,"column":21},"end":{"line":93,"column":null}},"28":{"start":{"line":94,"column":26},"end":{"line":94,"column":null}},"29":{"start":{"line":94,"column":58},"end":{"line":94,"column":95}},"30":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"31":{"start":{"line":95,"column":36},"end":{"line":95,"column":null}},"32":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"33":{"start":{"line":105,"column":20},"end":{"line":105,"column":null}},"34":{"start":{"line":106,"column":21},"end":{"line":106,"column":null}},"35":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"36":{"start":{"line":107,"column":33},"end":{"line":107,"column":53}},"37":{"start":{"line":108,"column":2},"end":{"line":174,"column":null}},"38":{"start":{"line":109,"column":21},"end":{"line":115,"column":null}},"39":{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},"40":{"start":{"line":117,"column":6},"end":{"line":127,"column":null}},"41":{"start":{"line":129,"column":16},"end":{"line":129,"column":null}},"42":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"43":{"start":{"line":135,"column":6},"end":{"line":145,"column":null}},"44":{"start":{"line":147,"column":18},"end":{"line":147,"column":null}},"45":{"start":{"line":148,"column":20},"end":{"line":148,"column":null}},"46":{"start":{"line":149,"column":4},"end":{"line":159,"column":null}},"47":{"start":{"line":161,"column":4},"end":{"line":171,"column":null}},"48":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"49":{"start":{"line":178,"column":2},"end":{"line":178,"column":null}},"50":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"51":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"52":{"start":{"line":184,"column":16},"end":{"line":184,"column":null}},"53":{"start":{"line":185,"column":32},"end":{"line":185,"column":null}},"54":{"start":{"line":186,"column":15},"end":{"line":186,"column":null}},"55":{"start":{"line":187,"column":16},"end":{"line":187,"column":null}},"56":{"start":{"line":188,"column":2},"end":{"line":209,"column":null}},"57":{"start":{"line":188,"column":15},"end":{"line":188,"column":18}},"58":{"start":{"line":189,"column":18},"end":{"line":189,"column":null}},"59":{"start":{"line":190,"column":17},"end":{"line":190,"column":null}},"60":{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},"61":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"62":{"start":{"line":193,"column":6},"end":{"line":193,"column":null}},"63":{"start":{"line":194,"column":6},"end":{"line":194,"column":null}},"64":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"65":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"66":{"start":{"line":197,"column":53},"end":{"line":197,"column":65}},"67":{"start":{"line":198,"column":6},"end":{"line":198,"column":null}},"68":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"69":{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},"70":{"start":{"line":202,"column":6},"end":{"line":202,"column":null}},"71":{"start":{"line":203,"column":6},"end":{"line":203,"column":null}},"72":{"start":{"line":204,"column":6},"end":{"line":204,"column":null}},"73":{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},"74":{"start":{"line":207,"column":6},"end":{"line":207,"column":null}},"75":{"start":{"line":210,"column":2},"end":{"line":210,"column":null}},"76":{"start":{"line":214,"column":15},"end":{"line":214,"column":null}},"77":{"start":{"line":215,"column":17},"end":{"line":215,"column":null}},"78":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"79":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"80":{"start":{"line":219,"column":2},"end":{"line":219,"column":null}},"81":{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},"82":{"start":{"line":223,"column":2},"end":{"line":226,"column":null}},"83":{"start":{"line":224,"column":4},"end":{"line":224,"column":null}},"84":{"start":{"line":225,"column":4},"end":{"line":225,"column":null}}},"fnMap":{"0":{"name":"decodeXml","decl":{"start":{"line":51,"column":9},"end":{"line":51,"column":19}},"loc":{"start":{"line":51,"column":54},"end":{"line":53,"column":null}},"line":51},"1":{"name":"getTag","decl":{"start":{"line":55,"column":9},"end":{"line":55,"column":16}},"loc":{"start":{"line":55,"column":68},"end":{"line":58,"column":null}},"line":55},"2":{"name":"parseRssItems","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":30}},"loc":{"start":{"line":60,"column":54},"end":{"line":77,"column":null}},"line":60},"3":{"name":"dokIdMatchesHaystack","decl":{"start":{"line":79,"column":9},"end":{"line":79,"column":30}},"loc":{"start":{"line":79,"column":72},"end":{"line":85,"column":null}},"line":79},"4":{"name":"buildRssSignals","decl":{"start":{"line":87,"column":16},"end":{"line":87,"column":32}},"loc":{"start":{"line":87,"column":106},"end":{"line":98,"column":null}},"line":87},"5":{"name":"(anonymous_5)","decl":{"start":{"line":89,"column":5},"end":{"line":89,"column":10}},"loc":{"start":{"line":89,"column":20},"end":{"line":89,"column":46}},"line":89},"6":{"name":"(anonymous_6)","decl":{"start":{"line":92,"column":15},"end":{"line":92,"column":24}},"loc":{"start":{"line":92,"column":33},"end":{"line":97,"column":3}},"line":92},"7":{"name":"(anonymous_7)","decl":{"start":{"line":94,"column":40},"end":{"line":94,"column":48}},"loc":{"start":{"line":94,"column":58},"end":{"line":94,"column":95}},"line":94},"8":{"name":"watchRssFeed","decl":{"start":{"line":100,"column":22},"end":{"line":100,"column":null}},"loc":{"start":{"line":104,"column":27},"end":{"line":175,"column":null}},"line":104},"9":{"name":"(anonymous_9)","decl":{"start":{"line":107,"column":16},"end":{"line":107,"column":33}},"loc":{"start":{"line":107,"column":33},"end":{"line":107,"column":53}},"line":107},"10":{"name":"persistRssWatch","decl":{"start":{"line":177,"column":16},"end":{"line":177,"column":32}},"loc":{"start":{"line":177,"column":97},"end":{"line":181,"column":null}},"line":177},"11":{"name":"parseArgs","decl":{"start":{"line":183,"column":9},"end":{"line":183,"column":19}},"loc":{"start":{"line":183,"column":124},"end":{"line":211,"column":null}},"line":183},"12":{"name":"(anonymous_12)","decl":{"start":{"line":197,"column":38},"end":{"line":197,"column":43}},"loc":{"start":{"line":197,"column":53},"end":{"line":197,"column":65}},"line":197},"13":{"name":"main","decl":{"start":{"line":213,"column":15},"end":{"line":213,"column":37}},"loc":{"start":{"line":213,"column":37},"end":{"line":220,"column":null}},"line":213},"14":{"name":"(anonymous_14)","decl":{"start":{"line":223,"column":9},"end":{"line":223,"column":16}},"loc":{"start":{"line":223,"column":35},"end":{"line":226,"column":3}},"line":223}},"branchMap":{"0":{"loc":{"start":{"line":52,"column":29},"end":{"line":52,"column":40}},"type":"binary-expr","locations":[{"start":{"line":52,"column":29},"end":{"line":52,"column":38}},{"start":{"line":52,"column":38},"end":{"line":52,"column":40}}],"line":52},"1":{"loc":{"start":{"line":57,"column":9},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":22},"end":{"line":57,"column":44}},{"start":{"line":57,"column":44},"end":{"line":57,"column":null}}],"line":57},"2":{"loc":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":18},"end":{"line":63,"column":30}},{"start":{"line":63,"column":30},"end":{"line":63,"column":null}}],"line":63},"3":{"loc":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":17},"end":{"line":66,"column":42}},{"start":{"line":66,"column":42},"end":{"line":66,"column":null}}],"line":66},"4":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"5":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":34}},"type":"binary-expr","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":18}},{"start":{"line":67,"column":18},"end":{"line":67,"column":27}},{"start":{"line":67,"column":27},"end":{"line":67,"column":34}}],"line":67},"6":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"7":{"loc":{"start":{"line":93,"column":64},"end":{"line":93,"column":89}},"type":"binary-expr","locations":[{"start":{"line":93,"column":64},"end":{"line":93,"column":84}},{"start":{"line":93,"column":84},"end":{"line":93,"column":89}}],"line":93},"8":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"9":{"loc":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"type":"default-arg","locations":[{"start":{"line":101,"column":12},"end":{"line":101,"column":null}}],"line":101},"10":{"loc":{"start":{"line":102,"column":2},"end":{"line":102,"column":null}},"type":"default-arg","locations":[{"start":{"line":102,"column":37},"end":{"line":102,"column":null}}],"line":102},"11":{"loc":{"start":{"line":103,"column":2},"end":{"line":103,"column":null}},"type":"default-arg","locations":[{"start":{"line":103,"column":26},"end":{"line":103,"column":null}}],"line":103},"12":{"loc":{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":116},"13":{"loc":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":134},"14":{"loc":{"start":{"line":158,"column":13},"end":{"line":158,"column":null}},"type":"cond-expr","locations":[{"start":{"line":158,"column":40},"end":{"line":158,"column":113}},{"start":{"line":158,"column":113},"end":{"line":158,"column":null}}],"line":158},"15":{"loc":{"start":{"line":170,"column":13},"end":{"line":170,"column":null}},"type":"cond-expr","locations":[{"start":{"line":170,"column":38},"end":{"line":170,"column":54}},{"start":{"line":170,"column":54},"end":{"line":170,"column":null}}],"line":170},"16":{"loc":{"start":{"line":177,"column":56},"end":{"line":177,"column":97}},"type":"default-arg","locations":[{"start":{"line":177,"column":69},"end":{"line":177,"column":97}}],"line":177},"17":{"loc":{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},"type":"if","locations":[{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},{"start":{},"end":{}}],"line":191},"18":{"loc":{"start":{"line":191,"column":8},"end":{"line":191,"column":40}},"type":"binary-expr","locations":[{"start":{"line":191,"column":8},"end":{"line":191,"column":34}},{"start":{"line":191,"column":34},"end":{"line":191,"column":40}}],"line":191},"19":{"loc":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"type":"if","locations":[{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},{"start":{},"end":{}}],"line":196},"20":{"loc":{"start":{"line":196,"column":8},"end":{"line":196,"column":39}},"type":"binary-expr","locations":[{"start":{"line":196,"column":8},"end":{"line":196,"column":33}},{"start":{"line":196,"column":33},"end":{"line":196,"column":39}}],"line":196},"21":{"loc":{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},"type":"if","locations":[{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},{"start":{},"end":{}}],"line":201},"22":{"loc":{"start":{"line":201,"column":8},"end":{"line":201,"column":38}},"type":"binary-expr","locations":[{"start":{"line":201,"column":8},"end":{"line":201,"column":32}},{"start":{"line":201,"column":32},"end":{"line":201,"column":38}}],"line":201},"23":{"loc":{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":206},"24":{"loc":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},{"start":{},"end":{}}],"line":216},"25":{"loc":{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},{"start":{},"end":{}}],"line":222},"26":{"loc":{"start":{"line":222,"column":66},"end":{"line":222,"column":87}},"type":"binary-expr","locations":[{"start":{"line":222,"column":66},"end":{"line":222,"column":85}},{"start":{"line":222,"column":85},"end":{"line":222,"column":87}}],"line":222},"27":{"loc":{"start":{"line":224,"column":32},"end":{"line":224,"column":88}},"type":"cond-expr","locations":[{"start":{"line":224,"column":57},"end":{"line":224,"column":73}},{"start":{"line":224,"column":73},"end":{"line":224,"column":88}}],"line":224}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":10,"8":15,"9":15,"10":3,"11":3,"12":3,"13":3,"14":3,"15":3,"16":3,"17":0,"18":3,"19":3,"20":3,"21":3,"22":3,"23":3,"24":3,"25":0,"26":3,"27":3,"28":3,"29":3,"30":3,"31":1,"32":2,"33":1,"34":1,"35":1,"36":0,"37":1,"38":1,"39":1,"40":0,"41":1,"42":1,"43":0,"44":1,"45":1,"46":1,"47":0,"48":1,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":1,"82":0,"83":0,"84":0},"f":{"0":10,"1":15,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":1,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},"b":{"0":[10,0],"1":[10,5],"2":[3,0],"3":[3,0],"4":[0,3],"5":[3,3,3],"6":[0,3],"7":[3,2],"8":[1,2],"9":[1],"10":[1],"11":[1],"12":[0,1],"13":[0,1],"14":[1,0],"15":[0,0],"16":[0],"17":[0,0],"18":[0,0],"19":[0,0],"20":[0,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[0,0],"25":[0,1],"26":[1,0],"27":[0,0]},"meta":{"lastBranch":28,"lastFunction":15,"lastStatement":85,"seen":{"s:37:18:37:Infinity":0,"s:38:18:38:Infinity":1,"s:39:34:39:Infinity":2,"s:43:36:43:Infinity":3,"s:44:38:44:Infinity":4,"s:45:16:45:Infinity":5,"s:49:20:49:Infinity":6,"f:51:9:51:19":0,"s:52:2:52:Infinity":7,"b:52:29:52:38:52:38:52:40":0,"f:55:9:55:16":1,"s:56:16:56:Infinity":8,"s:57:2:57:Infinity":9,"b:57:22:57:44:57:44:57:Infinity":1,"f:60:16:60:30":2,"s:61:27:61:Infinity":10,"s:62:2:75:Infinity":11,"s:63:18:63:Infinity":12,"b:63:18:63:30:63:30:63:Infinity":2,"s:64:18:64:Infinity":13,"s:65:17:65:Infinity":14,"s:66:17:66:Infinity":15,"b:66:17:66:42:66:42:66:Infinity":3,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":4,"s:67:4:67:Infinity":16,"b:67:8:67:18:67:18:67:27:67:27:67:34":5,"s:67:34:67:Infinity":17,"s:68:4:74:Infinity":18,"s:76:2:76:Infinity":19,"f:79:9:79:30":3,"s:83:18:83:Infinity":20,"s:84:2:84:Infinity":21,"f:87:16:87:32":4,"s:88:24:90:Infinity":22,"f:89:5:89:10":5,"s:89:20:89:46":23,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":6,"s:91:2:91:Infinity":24,"s:91:34:91:Infinity":25,"s:92:2:97:Infinity":26,"f:92:15:92:24":6,"s:93:21:93:Infinity":27,"b:93:64:93:84:93:84:93:89":7,"s:94:26:94:Infinity":28,"f:94:40:94:48":7,"s:94:58:94:95":29,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":8,"s:95:4:95:Infinity":30,"s:95:36:95:Infinity":31,"s:96:4:96:Infinity":32,"f:100:22:100:Infinity":8,"b:101:12:101:Infinity":9,"b:102:37:102:Infinity":10,"b:103:26:103:Infinity":11,"s:105:20:105:Infinity":33,"s:106:21:106:Infinity":34,"s:107:16:107:Infinity":35,"f:107:16:107:33":9,"s:107:33:107:53":36,"s:108:2:174:Infinity":37,"s:109:21:115:Infinity":38,"b:116:4:128:Infinity:undefined:undefined:undefined:undefined":12,"s:116:4:128:Infinity":39,"s:117:6:127:Infinity":40,"s:129:16:129:Infinity":41,"b:134:4:146:Infinity:undefined:undefined:undefined:undefined":13,"s:134:4:146:Infinity":42,"s:135:6:145:Infinity":43,"s:147:18:147:Infinity":44,"s:148:20:148:Infinity":45,"s:149:4:159:Infinity":46,"b:158:40:158:113:158:113:158:Infinity":14,"s:161:4:171:Infinity":47,"b:170:38:170:54:170:54:170:Infinity":15,"s:173:4:173:Infinity":48,"f:177:16:177:32":10,"b:177:69:177:97":16,"s:178:2:178:Infinity":49,"s:179:2:179:Infinity":50,"s:180:2:180:Infinity":51,"f:183:9:183:19":11,"s:184:16:184:Infinity":52,"s:185:32:185:Infinity":53,"s:186:15:186:Infinity":54,"s:187:16:187:Infinity":55,"s:188:2:209:Infinity":56,"s:188:15:188:18":57,"s:189:18:189:Infinity":58,"s:190:17:190:Infinity":59,"b:191:4:195:Infinity:undefined:undefined:undefined:undefined":17,"s:191:4:195:Infinity":60,"b:191:8:191:34:191:34:191:40":18,"s:192:6:192:Infinity":61,"s:193:6:193:Infinity":62,"s:194:6:194:Infinity":63,"b:196:4:200:Infinity:undefined:undefined:undefined:undefined":19,"s:196:4:200:Infinity":64,"b:196:8:196:33:196:33:196:39":20,"s:197:6:197:Infinity":65,"f:197:38:197:43":12,"s:197:53:197:65":66,"s:198:6:198:Infinity":67,"s:199:6:199:Infinity":68,"b:201:4:205:Infinity:undefined:undefined:undefined:undefined":21,"s:201:4:205:Infinity":69,"b:201:8:201:32:201:32:201:38":22,"s:202:6:202:Infinity":70,"s:203:6:203:Infinity":71,"s:204:6:204:Infinity":72,"b:206:4:208:Infinity:undefined:undefined:undefined:undefined":23,"s:206:4:208:Infinity":73,"s:207:6:207:Infinity":74,"s:210:2:210:Infinity":75,"f:213:15:213:37":13,"s:214:15:214:Infinity":76,"s:215:17:215:Infinity":77,"b:216:2:218:Infinity:undefined:undefined:undefined:undefined":24,"s:216:2:218:Infinity":78,"s:217:4:217:Infinity":79,"s:219:2:219:Infinity":80,"b:222:0:227:Infinity:undefined:undefined:undefined:undefined":25,"s:222:0:227:Infinity":81,"b:222:66:222:85:222:85:222:87":26,"s:223:2:226:Infinity":82,"f:223:9:223:16":14,"s:224:4:224:Infinity":83,"b:224:57:224:73:224:73:224:88":27,"s:225:4:225:Infinity":84}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/article-meta.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/article-meta.ts","statementMap":{"0":{"start":{"line":35,"column":23},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":2},"end":{"line":59,"column":null}},"2":{"start":{"line":37,"column":20},"end":{"line":37,"column":null}},"3":{"start":{"line":38,"column":23},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":25},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":24},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":25},"end":{"line":42,"column":null}},"8":{"start":{"line":44,"column":4},"end":{"line":50,"column":null}},"9":{"start":{"line":52,"column":4},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"extractArticleMeta","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":66},"end":{"line":60,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":13},"end":{"line":45,"column":null}},"type":"cond-expr","locations":[{"start":{"line":45,"column":26},"end":{"line":45,"column":50}},{"start":{"line":45,"column":50},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":31},"end":{"line":46,"column":54}},{"start":{"line":46,"column":54},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":30},"end":{"line":47,"column":56}},{"start":{"line":47,"column":56},"end":{"line":47,"column":null}}],"line":47},"3":{"loc":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":28},"end":{"line":48,"column":53}},{"start":{"line":48,"column":53},"end":{"line":48,"column":null}}],"line":48},"4":{"loc":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":31},"end":{"line":49,"column":57}},{"start":{"line":49,"column":57},"end":{"line":49,"column":null}}],"line":49}},"s":{"0":8141,"1":8141,"2":8141,"3":8141,"4":8141,"5":8141,"6":8141,"7":8141,"8":8141,"9":3},"f":{"0":8141},"b":{"0":[8138,0],"1":[8138,0],"2":[7966,172],"3":[8040,98],"4":[7954,184]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":10,"seen":{"f:34:16:34:35":0,"s:35:23:35:Infinity":0,"s:36:2:59:Infinity":1,"s:37:20:37:Infinity":2,"s:38:23:38:Infinity":3,"s:39:22:39:Infinity":4,"s:40:25:40:Infinity":5,"s:41:24:41:Infinity":6,"s:42:25:42:Infinity":7,"s:44:4:50:Infinity":8,"b:45:26:45:50:45:50:45:Infinity":0,"b:46:31:46:54:46:54:46:Infinity":1,"b:47:30:47:56:47:56:47:Infinity":2,"b:48:28:48:53:48:53:48:Infinity":3,"b:49:31:49:57:49:57:49:Infinity":4,"s:52:4:58:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/hreflang.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"hreflangCode","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":29}},"loc":{"start":{"line":23,"column":51},"end":{"line":26,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":24}},"s":{"0":3434,"1":245,"2":3189},"f":{"0":3434},"b":{"0":[245,3189]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:23:16:23:29":0,"b:24:2:24:Infinity:undefined:undefined:undefined:undefined":0,"s:24:2:24:Infinity":0,"s:24:21:24:Infinity":1,"s:25:2:25:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/escape.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/escape.ts","statementMap":{"0":{"start":{"line":22,"column":2},"end":{"line":27,"column":null}}},"fnMap":{"0":{"name":"escapeXml","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":26}},"loc":{"start":{"line":21,"column":48},"end":{"line":28,"column":null}},"line":21}},"branchMap":{},"s":{"0":4981},"f":{"0":4981},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:21:16:21:26":0,"s:22:2:27:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/pub-date.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/pub-date.ts","statementMap":{"0":{"start":{"line":28,"column":19},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"4":{"start":{"line":33,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"stablePubDate","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":30}},"loc":{"start":{"line":27,"column":56},"end":{"line":38,"column":null}},"line":27}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30}},"s":{"0":8145,"1":8145,"2":8145,"3":8073,"4":72,"5":72,"6":1},"f":{"0":8145},"b":{"0":[8073,72]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:27:16:27:30":0,"s:28:19:28:Infinity":0,"s:29:20:29:Infinity":1,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:32:Infinity":2,"s:31:4:31:Infinity":3,"s:33:2:37:Infinity":4,"s:34:4:34:Infinity":5,"s:36:4:36:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/render/feed.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/render/feed.ts","statementMap":{"0":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"1":{"start":{"line":34,"column":12},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},"4":{"start":{"line":54,"column":4},"end":{"line":60,"column":null}},"5":{"start":{"line":63,"column":15},"end":{"line":63,"column":null}},"6":{"start":{"line":64,"column":12},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":2},"end":{"line":70,"column":null}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"9":{"start":{"line":81,"column":18},"end":{"line":81,"column":null}},"10":{"start":{"line":82,"column":19},"end":{"line":82,"column":null}},"11":{"start":{"line":83,"column":14},"end":{"line":83,"column":null}},"12":{"start":{"line":85,"column":24},"end":{"line":87,"column":null}},"13":{"start":{"line":89,"column":12},"end":{"line":115,"column":null}},"14":{"start":{"line":117,"column":28},"end":{"line":120,"column":null}},"15":{"start":{"line":121,"column":2},"end":{"line":124,"column":null}},"16":{"start":{"line":122,"column":4},"end":{"line":123,"column":null}},"17":{"start":{"line":126,"column":2},"end":{"line":151,"column":null}},"18":{"start":{"line":127,"column":22},"end":{"line":127,"column":null}},"19":{"start":{"line":128,"column":22},"end":{"line":128,"column":null}},"20":{"start":{"line":129,"column":26},"end":{"line":131,"column":null}},"21":{"start":{"line":133,"column":4},"end":{"line":142,"column":null}},"22":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"23":{"start":{"line":145,"column":6},"end":{"line":146,"column":null}},"24":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"25":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"26":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}}},"fnMap":{"0":{"name":"subfolderFromBaseSlug","decl":{"start":{"line":33,"column":9},"end":{"line":33,"column":31}},"loc":{"start":{"line":33,"column":64},"end":{"line":36,"column":null}},"line":33},"1":{"name":"channelStrings","decl":{"start":{"line":52,"column":9},"end":{"line":52,"column":24}},"loc":{"start":{"line":52,"column":60},"end":{"line":71,"column":null}},"line":52},"2":{"name":"generateRss","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":28}},"loc":{"start":{"line":78,"column":63},"end":{"line":158,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":9},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":13},"end":{"line":35,"column":21}},{"start":{"line":35,"column":21},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":78,"column":28},"end":{"line":78,"column":63}},"type":"default-arg","locations":[{"start":{"line":78,"column":49},"end":{"line":78,"column":63}}],"line":78},"3":{"loc":{"start":{"line":85,"column":24},"end":{"line":87,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{"line":87,"column":6},"end":{"line":87,"column":null}}],"line":85},"4":{"loc":{"start":{"line":102,"column":27},"end":{"line":102,"column":140}},"type":"cond-expr","locations":[{"start":{"line":102,"column":49},"end":{"line":102,"column":99}},{"start":{"line":102,"column":99},"end":{"line":102,"column":140}}],"line":102},"5":{"loc":{"start":{"line":128,"column":22},"end":{"line":128,"column":null}},"type":"cond-expr","locations":[{"start":{"line":128,"column":34},"end":{"line":128,"column":62}},{"start":{"line":128,"column":62},"end":{"line":128,"column":null}}],"line":128},"6":{"loc":{"start":{"line":129,"column":26},"end":{"line":131,"column":null}},"type":"cond-expr","locations":[{"start":{"line":130,"column":8},"end":{"line":130,"column":null}},{"start":{"line":131,"column":8},"end":{"line":131,"column":null}}],"line":129}},"s":{"0":1,"1":250,"2":250,"3":5,"4":1,"5":4,"6":4,"7":4,"8":5,"9":5,"10":5,"11":5,"12":5,"13":5,"14":5,"15":5,"16":30,"17":5,"18":250,"19":250,"20":250,"21":250,"22":250,"23":3178,"24":250,"25":5,"26":5},"f":{"0":250,"1":5,"2":5},"b":{"0":[244,6],"1":[1,4],"2":[5],"3":[5,0],"4":[5,0],"5":[244,6],"6":[214,36]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":27,"seen":{"s:27:17:27:Infinity":0,"f:33:9:33:31":0,"s:34:12:34:Infinity":1,"s:35:2:35:Infinity":2,"b:35:13:35:21:35:21:35:Infinity":0,"f:52:9:52:24":1,"b:53:2:61:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:61:Infinity":3,"s:54:4:60:Infinity":4,"s:63:15:63:Infinity":5,"s:64:12:64:Infinity":6,"s:65:2:70:Infinity":7,"f:78:16:78:28":2,"b:78:49:78:63":2,"s:79:2:79:Infinity":8,"s:81:18:81:Infinity":9,"s:82:19:82:Infinity":10,"s:83:14:83:Infinity":11,"s:85:24:87:Infinity":12,"b:86:6:86:Infinity:87:6:87:Infinity":3,"s:89:12:115:Infinity":13,"b:102:49:102:99:102:99:102:140":4,"s:117:28:120:Infinity":14,"s:121:2:124:Infinity":15,"s:122:4:123:Infinity":16,"s:126:2:151:Infinity":17,"s:127:22:127:Infinity":18,"s:128:22:128:Infinity":19,"b:128:34:128:62:128:62:128:Infinity":5,"s:129:26:131:Infinity":20,"b:130:8:130:Infinity:131:8:131:Infinity":6,"s:133:4:142:Infinity":21,"s:144:4:147:Infinity":22,"s:145:6:146:Infinity":23,"s:149:4:149:Infinity":24,"s:153:2:153:Infinity":25,"s:157:2:157:Infinity":26}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/scanner.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/scanner.ts","statementMap":{"0":{"start":{"line":30,"column":19},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":18},"end":{"line":31,"column":null}},"2":{"start":{"line":33,"column":17},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"5":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"6":{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},"7":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"8":{"start":{"line":69,"column":4},"end":{"line":69,"column":null}},"9":{"start":{"line":72,"column":16},"end":{"line":74,"column":null}},"10":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"11":{"start":{"line":76,"column":24},"end":{"line":76,"column":null}},"12":{"start":{"line":77,"column":2},"end":{"line":87,"column":null}},"13":{"start":{"line":78,"column":18},"end":{"line":78,"column":null}},"14":{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":80,"column":23},"end":{"line":80,"column":null}},"16":{"start":{"line":81,"column":19},"end":{"line":81,"column":null}},"17":{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},"18":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"19":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"20":{"start":{"line":89,"column":33},"end":{"line":89,"column":null}},"21":{"start":{"line":91,"column":2},"end":{"line":122,"column":null}},"22":{"start":{"line":92,"column":24},"end":{"line":92,"column":null}},"23":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"24":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"25":{"start":{"line":97,"column":21},"end":{"line":97,"column":null}},"26":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"27":{"start":{"line":100,"column":64},"end":{"line":100,"column":null}},"28":{"start":{"line":101,"column":4},"end":{"line":108,"column":null}},"29":{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},"30":{"start":{"line":103,"column":8},"end":{"line":106,"column":null}},"31":{"start":{"line":110,"column":4},"end":{"line":121,"column":null}},"32":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"33":{"start":{"line":124,"column":26},"end":{"line":124,"column":87}},"34":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"35":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}}},"fnMap":{"0":{"name":"getRssArticles","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":31}},"loc":{"start":{"line":64,"column":72},"end":{"line":129,"column":null}},"line":64},"1":{"name":"(anonymous_1)","decl":{"start":{"line":74,"column":5},"end":{"line":74,"column":13}},"loc":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"line":74},"2":{"name":"(anonymous_2)","decl":{"start":{"line":124,"column":11},"end":{"line":124,"column":17}},"loc":{"start":{"line":124,"column":26},"end":{"line":124,"column":87}},"line":124}},"branchMap":{"0":{"loc":{"start":{"line":64,"column":31},"end":{"line":64,"column":72}},"type":"default-arg","locations":[{"start":{"line":64,"column":52},"end":{"line":64,"column":72}}],"line":64},"1":{"loc":{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":67},"2":{"loc":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"type":"binary-expr","locations":[{"start":{"line":74,"column":22},"end":{"line":74,"column":48}},{"start":{"line":74,"column":48},"end":{"line":74,"column":73}},{"start":{"line":74,"column":73},"end":{"line":74,"column":99}}],"line":74},"3":{"loc":{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":79},"4":{"loc":{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":82},"5":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"6":{"loc":{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":102}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":16,"6":16,"7":0,"8":0,"9":16,"10":97456,"11":16,"12":16,"13":97392,"14":97392,"15":97360,"16":97360,"17":97360,"18":8384,"19":97360,"20":16,"21":16,"22":8384,"23":8384,"24":246,"25":8138,"26":8138,"27":8138,"28":8138,"29":96441,"30":88303,"31":8138,"32":16,"33":37006,"34":16,"35":16},"f":{"0":16,"1":97456,"2":37006},"b":{"0":[16],"1":[0,16],"2":[97456,97392,97392],"3":[97360,32],"4":[8384,88976],"5":[246,8138],"6":[88303,8138]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":36,"seen":{"s:30:19:30:Infinity":0,"s:31:18:31:Infinity":1,"s:33:17:33:Infinity":2,"s:34:17:34:Infinity":3,"s:35:18:35:Infinity":4,"f:64:16:64:31":0,"b:64:52:64:72":0,"s:65:2:65:Infinity":5,"b:67:2:70:Infinity:undefined:undefined:undefined:undefined":1,"s:67:2:70:Infinity":6,"s:68:4:68:Infinity":7,"s:69:4:69:Infinity":8,"s:72:16:74:Infinity":9,"f:74:5:74:13":1,"s:74:22:74:99":10,"b:74:22:74:48:74:48:74:73:74:73:74:99":2,"s:76:24:76:Infinity":11,"s:77:2:87:Infinity":12,"s:78:18:78:Infinity":13,"b:79:4:86:Infinity:undefined:undefined:undefined:undefined":3,"s:79:4:86:Infinity":14,"s:80:23:80:Infinity":15,"s:81:19:81:Infinity":16,"b:82:6:84:Infinity:undefined:undefined:undefined:undefined":4,"s:82:6:84:Infinity":17,"s:83:8:83:Infinity":18,"s:85:6:85:Infinity":19,"s:89:33:89:Infinity":20,"s:91:2:122:Infinity":21,"s:92:24:92:Infinity":22,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":5,"s:95:4:95:Infinity":23,"s:95:22:95:Infinity":24,"s:97:21:97:Infinity":25,"s:98:17:98:Infinity":26,"s:100:64:100:Infinity":27,"s:101:4:108:Infinity":28,"b:102:6:107:Infinity:undefined:undefined:undefined:undefined":6,"s:102:6:107:Infinity":29,"s:103:8:106:Infinity":30,"s:110:4:121:Infinity":31,"s:124:2:124:Infinity":32,"f:124:11:124:17":2,"s:124:26:124:87":33,"s:126:2:126:Infinity":34,"s:128:2:128:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/validator.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"9":{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"11":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"12":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"13":{"start":{"line":50,"column":8},"end":{"line":50,"column":null}},"14":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"15":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"16":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"17":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"18":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"19":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"20":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"21":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"22":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"23":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"24":{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},"25":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"26":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"27":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}}},"fnMap":{"0":{"name":"validateRss","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":28}},"loc":{"start":{"line":23,"column":50},"end":{"line":75,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":26},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"2":{"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":38},"4":{"loc":{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":42},"5":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"6":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":47}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":45}},{"start":{"line":50,"column":45},"end":{"line":50,"column":47}}],"line":50},"7":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":57,"column":22},"end":{"line":57,"column":63}},"type":"binary-expr","locations":[{"start":{"line":57,"column":22},"end":{"line":57,"column":61}},{"start":{"line":57,"column":61},"end":{"line":57,"column":63}}],"line":57},"9":{"loc":{"start":{"line":58,"column":21},"end":{"line":58,"column":61}},"type":"binary-expr","locations":[{"start":{"line":58,"column":21},"end":{"line":58,"column":59}},{"start":{"line":58,"column":59},"end":{"line":58,"column":61}}],"line":58},"10":{"loc":{"start":{"line":59,"column":21},"end":{"line":59,"column":46}},"type":"binary-expr","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":44}},{"start":{"line":59,"column":44},"end":{"line":59,"column":46}}],"line":59},"11":{"loc":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"12":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65},"13":{"loc":{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69}},"s":{"0":13,"1":13,"2":2,"3":11,"4":2,"5":9,"6":2,"7":7,"8":0,"9":7,"10":0,"11":7,"12":0,"13":7,"14":13,"15":13,"16":2,"17":5,"18":13,"19":13,"20":13,"21":0,"22":5,"23":0,"24":5,"25":1,"26":4,"27":4},"f":{"0":13},"b":{"0":[2,11],"1":[2,9],"2":[2,7],"3":[0,7],"4":[0,7],"5":[0,7],"6":[7,2],"7":[2,11],"8":[5,0],"9":[13,0],"10":[13,1],"11":[0,13],"12":[0,5],"13":[1,4]},"meta":{"lastBranch":14,"lastFunction":1,"lastStatement":28,"seen":{"f:23:16:23:28":0,"s:24:2:24:Infinity":0,"b:26:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:26:2:28:Infinity":1,"s:27:4:27:Infinity":2,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":1,"s:30:2:32:Infinity":3,"s:31:4:31:Infinity":4,"b:34:2:36:Infinity:undefined:undefined:undefined:undefined":2,"s:34:2:36:Infinity":5,"s:35:4:35:Infinity":6,"b:38:2:40:Infinity:undefined:undefined:undefined:undefined":3,"s:38:2:40:Infinity":7,"s:39:4:39:Infinity":8,"b:42:2:44:Infinity:undefined:undefined:undefined:undefined":4,"s:42:2:44:Infinity":9,"s:43:4:43:Infinity":10,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":5,"s:46:2:48:Infinity":11,"s:47:4:47:Infinity":12,"s:50:8:50:Infinity":13,"b:50:21:50:45:50:45:50:47":6,"s:51:2:51:Infinity":14,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":7,"s:53:2:55:Infinity":15,"s:54:4:54:Infinity":16,"s:57:8:57:Infinity":17,"b:57:22:57:61:57:61:57:63":8,"s:58:8:58:Infinity":18,"b:58:21:58:59:58:59:58:61":9,"s:59:8:59:Infinity":19,"b:59:21:59:44:59:44:59:46":10,"b:61:2:63:Infinity:undefined:undefined:undefined:undefined":11,"s:61:2:63:Infinity":20,"s:62:4:62:Infinity":21,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":12,"s:65:2:67:Infinity":22,"s:66:4:66:Infinity":23,"b:69:2:71:Infinity:undefined:undefined:undefined:undefined":13,"s:69:2:71:Infinity":24,"s:70:4:70:Infinity":25,"s:73:2:73:Infinity":26,"s:74:2:74:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/scb-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/scb-context.ts","statementMap":{"0":{"start":{"line":54,"column":70},"end":{"line":175,"column":null}},"1":{"start":{"line":185,"column":84},"end":{"line":256,"column":null}},"2":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"3":{"start":{"line":274,"column":2},"end":{"line":274,"column":null}},"4":{"start":{"line":284,"column":12},"end":{"line":284,"column":null}},"5":{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},"6":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"7":{"start":{"line":288,"column":2},"end":{"line":294,"column":null}},"8":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"9":{"start":{"line":293,"column":35},"end":{"line":293,"column":64}},"10":{"start":{"line":304,"column":12},"end":{"line":304,"column":null}},"11":{"start":{"line":305,"column":2},"end":{"line":313,"column":null}},"12":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"13":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"14":{"start":{"line":311,"column":40},"end":{"line":311,"column":64}},"15":{"start":{"line":324,"column":15},"end":{"line":324,"column":null}},"16":{"start":{"line":325,"column":38},"end":{"line":340,"column":null}},"17":{"start":{"line":342,"column":2},"end":{"line":342,"column":null}},"18":{"start":{"line":342,"column":36},"end":{"line":342,"column":54}},"19":{"start":{"line":352,"column":2},"end":{"line":358,"column":null}},"20":{"start":{"line":353,"column":19},"end":{"line":353,"column":38}},"21":{"start":{"line":354,"column":17},"end":{"line":358,"column":6}}},"fnMap":{"0":{"name":"getSCBHeading","decl":{"start":{"line":269,"column":16},"end":{"line":269,"column":null}},"loc":{"start":{"line":272,"column":10},"end":{"line":275,"column":null}},"line":272},"1":{"name":"findRelevantSCBIndicators","decl":{"start":{"line":283,"column":16},"end":{"line":283,"column":42}},"loc":{"start":{"line":283,"column":89},"end":{"line":295,"column":null}},"line":283},"2":{"name":"(anonymous_2)","decl":{"start":{"line":288,"column":32},"end":{"line":288,"column":null}},"loc":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"line":290},"3":{"name":"(anonymous_3)","decl":{"start":{"line":293,"column":21},"end":{"line":293,"column":27}},"loc":{"start":{"line":293,"column":35},"end":{"line":293,"column":64}},"line":293},"4":{"name":"getSCBTablesForCommittee","decl":{"start":{"line":303,"column":16},"end":{"line":303,"column":41}},"loc":{"start":{"line":303,"column":88},"end":{"line":314,"column":null}},"line":303},"5":{"name":"(anonymous_5)","decl":{"start":{"line":305,"column":21},"end":{"line":305,"column":null}},"loc":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"line":307},"6":{"name":"(anonymous_6)","decl":{"start":{"line":308,"column":29},"end":{"line":308,"column":null}},"loc":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"line":310},"7":{"name":"(anonymous_7)","decl":{"start":{"line":311,"column":25},"end":{"line":311,"column":31}},"loc":{"start":{"line":311,"column":40},"end":{"line":311,"column":64}},"line":311},"8":{"name":"hasSCBContext","decl":{"start":{"line":323,"column":16},"end":{"line":323,"column":30}},"loc":{"start":{"line":323,"column":56},"end":{"line":343,"column":null}},"line":323},"9":{"name":"(anonymous_9)","decl":{"start":{"line":342,"column":18},"end":{"line":342,"column":24}},"loc":{"start":{"line":342,"column":36},"end":{"line":342,"column":54}},"line":342},"10":{"name":"getSCBQueryParams","decl":{"start":{"line":351,"column":16},"end":{"line":351,"column":111}},"loc":{"start":{"line":351,"column":111},"end":{"line":359,"column":null}},"line":351},"11":{"name":"(anonymous_11)","decl":{"start":{"line":353,"column":5},"end":{"line":353,"column":13}},"loc":{"start":{"line":353,"column":19},"end":{"line":353,"column":38}},"line":353},"12":{"name":"(anonymous_12)","decl":{"start":{"line":354,"column":5},"end":{"line":354,"column":10}},"loc":{"start":{"line":354,"column":17},"end":{"line":358,"column":6}},"line":354}},"branchMap":{"0":{"loc":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"type":"binary-expr","locations":[{"start":{"line":273,"column":19},"end":{"line":273,"column":61}},{"start":{"line":273,"column":61},"end":{"line":273,"column":null}}],"line":273},"1":{"loc":{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":285},"2":{"loc":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"type":"binary-expr","locations":[{"start":{"line":290,"column":6},"end":{"line":290,"column":null}},{"start":{"line":291,"column":6},"end":{"line":291,"column":null}},{"start":{"line":292,"column":6},"end":{"line":292,"column":null}},{"start":{"line":293,"column":6},"end":{"line":293,"column":null}}],"line":290},"3":{"loc":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"type":"binary-expr","locations":[{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},{"start":{"line":308,"column":6},"end":{"line":312,"column":null}}],"line":307},"4":{"loc":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"type":"binary-expr","locations":[{"start":{"line":310,"column":10},"end":{"line":310,"column":null}},{"start":{"line":311,"column":10},"end":{"line":311,"column":null}}],"line":310}},"s":{"0":1,"1":1,"2":4,"3":4,"4":7,"5":7,"6":2,"7":5,"8":75,"9":167,"10":7,"11":7,"12":105,"13":1089,"14":94,"15":8,"16":8,"17":8,"18":58,"19":4,"20":60,"21":44},"f":{"0":4,"1":7,"2":75,"3":167,"4":7,"5":105,"6":1089,"7":94,"8":8,"9":58,"10":4,"11":60,"12":44},"b":{"0":[4,1],"1":[2,5],"2":[75,73,73,72],"3":[105,77],"4":[1089,77]},"meta":{"lastBranch":5,"lastFunction":13,"lastStatement":22,"seen":{"s:54:70:175:Infinity":0,"s:185:84:256:Infinity":1,"f:269:16:269:Infinity":0,"s:273:19:273:Infinity":2,"b:273:19:273:61:273:61:273:Infinity":0,"s:274:2:274:Infinity":3,"f:283:16:283:42":1,"s:284:12:284:Infinity":4,"b:285:2:287:Infinity:undefined:undefined:undefined:undefined":1,"s:285:2:287:Infinity":5,"s:286:4:286:Infinity":6,"s:288:2:294:Infinity":7,"f:288:32:288:Infinity":2,"s:290:6:293:Infinity":8,"b:290:6:290:Infinity:291:6:291:Infinity:292:6:292:Infinity:293:6:293:Infinity":2,"f:293:21:293:27":3,"s:293:35:293:64":9,"f:303:16:303:41":4,"s:304:12:304:Infinity":10,"s:305:2:313:Infinity":11,"f:305:21:305:Infinity":5,"s:307:6:312:Infinity":12,"b:307:6:307:Infinity:308:6:312:Infinity":3,"f:308:29:308:Infinity":6,"s:310:10:311:Infinity":13,"b:310:10:310:Infinity:311:10:311:Infinity":4,"f:311:25:311:31":7,"s:311:40:311:64":14,"f:323:16:323:30":8,"s:324:15:324:Infinity":15,"s:325:38:340:Infinity":16,"s:342:2:342:Infinity":17,"f:342:18:342:24":9,"s:342:36:342:54":18,"f:351:16:351:111":10,"s:352:2:358:Infinity":19,"f:353:5:353:13":11,"s:353:19:353:38":20,"f:354:5:354:10":12,"s:354:17:358:6":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/shared/theme-init.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/shared/theme-init.ts","statementMap":{"0":{"start":{"line":21,"column":19},"end":{"line":21,"column":null}},"1":{"start":{"line":22,"column":18},"end":{"line":22,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":43,"column":null}},"3":{"start":{"line":47,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"7":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"8":{"start":{"line":60,"column":41},"end":{"line":60,"column":null}},"9":{"start":{"line":70,"column":45},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"minifyBootstrap","decl":{"start":{"line":33,"column":9},"end":{"line":33,"column":25}},"loc":{"start":{"line":33,"column":46},"end":{"line":44,"column":null}},"line":33},"1":{"name":"loadBootstrap","decl":{"start":{"line":46,"column":9},"end":{"line":46,"column":33}},"loc":{"start":{"line":46,"column":33},"end":{"line":54,"column":null}},"line":46}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":0,"8":1,"9":1},"f":{"0":1,"1":1},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":10,"seen":{"s:21:19:21:Infinity":0,"s:22:18:22:Infinity":1,"f:33:9:33:25":0,"s:34:2:43:Infinity":2,"f:46:9:46:33":1,"s:47:2:53:Infinity":3,"s:48:17:48:Infinity":4,"s:49:16:49:Infinity":5,"s:50:4:50:Infinity":6,"s:52:4:52:Infinity":7,"s:60:41:60:Infinity":8,"s:70:45:70:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/escape.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/escape.ts","statementMap":{"0":{"start":{"line":22,"column":2},"end":{"line":28,"column":null}}},"fnMap":{"0":{"name":"escapeHtml","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":27}},"loc":{"start":{"line":21,"column":49},"end":{"line":29,"column":null}},"line":21}},"branchMap":{},"s":{"0":970326},"f":{"0":970326},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:21:16:21:27":0,"s:22:2:28:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/scanner.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/scanner.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":63,"column":2},"end":{"line":96,"column":null}},"6":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":25},"end":{"line":65,"column":null}},"8":{"start":{"line":66,"column":23},"end":{"line":66,"column":null}},"9":{"start":{"line":67,"column":24},"end":{"line":67,"column":null}},"10":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"11":{"start":{"line":69,"column":10},"end":{"line":80,"column":null}},"12":{"start":{"line":70,"column":6},"end":{"line":79,"column":null}},"13":{"start":{"line":71,"column":18},"end":{"line":71,"column":null}},"14":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"15":{"start":{"line":72,"column":16},"end":{"line":72,"column":null}},"16":{"start":{"line":73,"column":23},"end":{"line":73,"column":null}},"17":{"start":{"line":74,"column":8},"end":{"line":76,"column":null}},"18":{"start":{"line":78,"column":8},"end":{"line":78,"column":null}},"19":{"start":{"line":82,"column":23},"end":{"line":84,"column":null}},"20":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"21":{"start":{"line":84,"column":22},"end":{"line":84,"column":41}},"22":{"start":{"line":85,"column":24},"end":{"line":85,"column":null}},"23":{"start":{"line":87,"column":10},"end":{"line":87,"column":null}},"24":{"start":{"line":88,"column":18},"end":{"line":88,"column":null}},"25":{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},"26":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"27":{"start":{"line":109,"column":25},"end":{"line":109,"column":null}},"28":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},"29":{"start":{"line":111,"column":32},"end":{"line":111,"column":null}},"30":{"start":{"line":114,"column":20},"end":{"line":114,"column":null}},"31":{"start":{"line":115,"column":4},"end":{"line":148,"column":null}},"32":{"start":{"line":116,"column":23},"end":{"line":116,"column":null}},"33":{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},"34":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"35":{"start":{"line":118,"column":69},"end":{"line":118,"column":null}},"36":{"start":{"line":119,"column":8},"end":{"line":119,"column":null}},"37":{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},"38":{"start":{"line":126,"column":22},"end":{"line":126,"column":null}},"39":{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},"40":{"start":{"line":127,"column":20},"end":{"line":127,"column":null}},"41":{"start":{"line":129,"column":25},"end":{"line":129,"column":null}},"42":{"start":{"line":130,"column":21},"end":{"line":130,"column":null}},"43":{"start":{"line":131,"column":21},"end":{"line":131,"column":null}},"44":{"start":{"line":133,"column":23},"end":{"line":133,"column":null}},"45":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"46":{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},"47":{"start":{"line":137,"column":10},"end":{"line":137,"column":null}},"48":{"start":{"line":139,"column":8},"end":{"line":146,"column":null}},"49":{"start":{"line":151,"column":2},"end":{"line":151,"column":null}},"50":{"start":{"line":153,"column":2},"end":{"line":158,"column":null}},"51":{"start":{"line":154,"column":4},"end":{"line":157,"column":null}},"52":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"53":{"start":{"line":155,"column":29},"end":{"line":155,"column":null}},"54":{"start":{"line":156,"column":6},"end":{"line":156,"column":null}},"55":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}}},"fnMap":{"0":{"name":"extractArticleDate","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":35}},"loc":{"start":{"line":44,"column":61},"end":{"line":47,"column":null}},"line":44},"1":{"name":"extractArticleMeta","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":35}},"loc":{"start":{"line":62,"column":93},"end":{"line":97,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":69,"column":10},"end":{"line":69,"column":30}},"loc":{"start":{"line":69,"column":30},"end":{"line":80,"column":5}},"line":69},"3":{"name":"(anonymous_3)","decl":{"start":{"line":83,"column":7},"end":{"line":83,"column":15}},"loc":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"line":83},"4":{"name":"(anonymous_4)","decl":{"start":{"line":84,"column":7},"end":{"line":84,"column":13}},"loc":{"start":{"line":84,"column":22},"end":{"line":84,"column":41}},"line":84},"5":{"name":"getArticlesByLanguage","decl":{"start":{"line":108,"column":16},"end":{"line":108,"column":70}},"loc":{"start":{"line":108,"column":70},"end":{"line":161,"column":null}},"line":108},"6":{"name":"scanDir","decl":{"start":{"line":113,"column":11},"end":{"line":113,"column":19}},"loc":{"start":{"line":113,"column":38},"end":{"line":149,"column":null}},"line":113},"7":{"name":"(anonymous_7)","decl":{"start":{"line":154,"column":9},"end":{"line":154,"column":15}},"loc":{"start":{"line":154,"column":24},"end":{"line":157,"column":5}},"line":154}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":17},"end":{"line":46,"column":29}},{"start":{"line":46,"column":29},"end":{"line":46,"column":null}}],"line":46},"1":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"2":{"loc":{"start":{"line":74,"column":15},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":75,"column":12},"end":{"line":75,"column":null}},{"start":{"line":76,"column":12},"end":{"line":76,"column":null}}],"line":74},"3":{"loc":{"start":{"line":74,"column":15},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":15},"end":{"line":74,"column":57}},{"start":{"line":74,"column":57},"end":{"line":74,"column":null}}],"line":74},"4":{"loc":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"type":"binary-expr","locations":[{"start":{"line":83,"column":34},"end":{"line":83,"column":41}},{"start":{"line":83,"column":41},"end":{"line":83,"column":53}}],"line":83},"5":{"loc":{"start":{"line":85,"column":24},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":24},"end":{"line":85,"column":41}},{"start":{"line":85,"column":41},"end":{"line":85,"column":null}}],"line":85},"6":{"loc":{"start":{"line":87,"column":22},"end":{"line":87,"column":64}},"type":"binary-expr","locations":[{"start":{"line":87,"column":22},"end":{"line":87,"column":43}},{"start":{"line":87,"column":43},"end":{"line":87,"column":62}},{"start":{"line":87,"column":62},"end":{"line":87,"column":64}}],"line":87},"7":{"loc":{"start":{"line":91,"column":13},"end":{"line":91,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":32},"end":{"line":91,"column":40}},{"start":{"line":91,"column":40},"end":{"line":91,"column":null}}],"line":91},"8":{"loc":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":111},"9":{"loc":{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},{"start":{"line":120,"column":13},"end":{"line":147,"column":null}}],"line":117},"10":{"loc":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},{"start":{},"end":{}}],"line":118},"11":{"loc":{"start":{"line":118,"column":12},"end":{"line":118,"column":69}},"type":"binary-expr","locations":[{"start":{"line":118,"column":12},"end":{"line":118,"column":41}},{"start":{"line":118,"column":41},"end":{"line":118,"column":69}}],"line":118},"12":{"loc":{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":120},"13":{"loc":{"start":{"line":121,"column":8},"end":{"line":124,"column":null}},"type":"binary-expr","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},{"start":{"line":122,"column":8},"end":{"line":122,"column":null}},{"start":{"line":123,"column":8},"end":{"line":123,"column":null}},{"start":{"line":124,"column":8},"end":{"line":124,"column":null}}],"line":121},"14":{"loc":{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},{"start":{},"end":{}}],"line":127},"15":{"loc":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"type":"cond-expr","locations":[{"start":{"line":134,"column":34},"end":{"line":134,"column":62}},{"start":{"line":134,"column":62},"end":{"line":134,"column":null}}],"line":134},"16":{"loc":{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":136},"17":{"loc":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"type":"if","locations":[{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},{"start":{},"end":{}}],"line":155}},"s":{"0":30,"1":30,"2":30,"3":158210,"4":158210,"5":158210,"6":158210,"7":158210,"8":158210,"9":158210,"10":158210,"11":158210,"12":158210,"13":158210,"14":158210,"15":78,"16":158132,"17":158132,"18":598,"19":158210,"20":474630,"21":316732,"22":158210,"23":158210,"24":158210,"25":158210,"26":0,"27":26,"28":26,"29":0,"30":156,"31":156,"32":159172,"33":159172,"34":156,"35":26,"36":130,"37":159016,"38":158262,"39":158262,"40":52,"41":158210,"42":158210,"43":158210,"44":158210,"45":158210,"46":158262,"47":364,"48":158210,"49":26,"50":26,"51":364,"52":159458,"53":36088,"54":123370,"55":26},"f":{"0":158210,"1":158210,"2":158210,"3":474630,"4":316732,"5":26,"6":156,"7":159458},"b":{"0":[157950,260],"1":[78,158132],"2":[156182,1352],"3":[158132,156182],"4":[474630,472342],"5":[158210,0],"6":[158210,0,0],"7":[158210,0],"8":[0,26],"9":[156,159016],"10":[26,130],"11":[156,130],"12":[158262,754],"13":[159016,159016,158626,158600],"14":[52,158210],"15":[0,158210],"16":[364,157898],"17":[36088,123370]},"meta":{"lastBranch":18,"lastFunction":8,"lastStatement":56,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"f:44:16:44:35":0,"s:45:16:45:Infinity":3,"s:46:2:46:Infinity":4,"b:46:17:46:29:46:29:46:Infinity":0,"f:62:16:62:35":1,"s:63:2:96:Infinity":5,"s:64:20:64:Infinity":6,"s:65:25:65:Infinity":7,"s:66:23:66:Infinity":8,"s:67:24:67:Infinity":9,"s:68:22:68:Infinity":10,"s:69:10:80:Infinity":11,"f:69:10:69:30":2,"s:70:6:79:Infinity":12,"s:71:18:71:Infinity":13,"b:72:8:72:Infinity:undefined:undefined:undefined:undefined":1,"s:72:8:72:Infinity":14,"s:72:16:72:Infinity":15,"s:73:23:73:Infinity":16,"s:74:8:76:Infinity":17,"b:75:12:75:Infinity:76:12:76:Infinity":2,"b:74:15:74:57:74:57:74:Infinity":3,"s:78:8:78:Infinity":18,"s:82:23:84:Infinity":19,"f:83:7:83:15":3,"s:83:34:83:53":20,"b:83:34:83:41:83:41:83:53":4,"f:84:7:84:13":4,"s:84:22:84:41":21,"s:85:24:85:Infinity":22,"b:85:24:85:41:85:41:85:Infinity":5,"s:87:10:87:Infinity":23,"b:87:22:87:43:87:43:87:62:87:62:87:64":6,"s:88:18:88:Infinity":24,"s:90:4:93:Infinity":25,"b:91:32:91:40:91:40:91:Infinity":7,"s:95:4:95:Infinity":26,"f:108:16:108:70":5,"s:109:25:109:Infinity":27,"b:111:2:111:Infinity:undefined:undefined:undefined:undefined":8,"s:111:2:111:Infinity":28,"s:111:32:111:Infinity":29,"f:113:11:113:19":6,"s:114:20:114:Infinity":30,"s:115:4:148:Infinity":31,"s:116:23:116:Infinity":32,"b:117:6:147:Infinity:120:13:147:Infinity":9,"s:117:6:147:Infinity":33,"b:118:8:118:Infinity:undefined:undefined:undefined:undefined":10,"s:118:8:118:Infinity":34,"b:118:12:118:41:118:41:118:69":11,"s:118:69:118:Infinity":35,"s:119:8:119:Infinity":36,"b:120:13:147:Infinity:undefined:undefined:undefined:undefined":12,"s:120:13:147:Infinity":37,"b:121:8:121:Infinity:122:8:122:Infinity:123:8:123:Infinity:124:8:124:Infinity":13,"s:126:22:126:Infinity":38,"b:127:8:127:Infinity:undefined:undefined:undefined:undefined":14,"s:127:8:127:Infinity":39,"s:127:20:127:Infinity":40,"s:129:25:129:Infinity":41,"s:130:21:130:Infinity":42,"s:131:21:131:Infinity":43,"s:133:23:133:Infinity":44,"s:134:25:134:Infinity":45,"b:134:34:134:62:134:62:134:Infinity":15,"b:136:8:138:Infinity:undefined:undefined:undefined:undefined":16,"s:136:8:138:Infinity":46,"s:137:10:137:Infinity":47,"s:139:8:146:Infinity":48,"s:151:2:151:Infinity":49,"s:153:2:158:Infinity":50,"s:154:4:157:Infinity":51,"f:154:9:154:15":7,"b:155:6:155:Infinity:undefined:undefined:undefined:undefined":17,"s:155:6:155:Infinity":52,"s:155:29:155:Infinity":53,"s:156:6:156:Infinity":54,"s:160:2:160:Infinity":55}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/docs-sections.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/docs-sections.ts","statementMap":{"0":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":25,"column":17},"end":{"line":25,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"getDocsSections","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":48}},"loc":{"start":{"line":41,"column":48},"end":{"line":49,"column":null}},"line":41}},"branchMap":{},"s":{"0":30,"1":30,"2":30,"3":23},"f":{"0":23},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"s:22:19:22:Infinity":0,"s:23:18:23:Infinity":1,"s:25:17:25:Infinity":2,"f:41:16:41:48":0,"s:42:2:48:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/git-timestamps.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/git-timestamps.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":34,"column":26},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":26},"end":{"line":35,"column":null}},"5":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"6":{"start":{"line":45,"column":27},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":66,"column":null}},"9":{"start":{"line":48,"column":19},"end":{"line":53,"column":null}},"10":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"11":{"start":{"line":55,"column":4},"end":{"line":63,"column":null}},"12":{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},"13":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"14":{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},"15":{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},"17":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"18":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"19":{"start":{"line":77,"column":23},"end":{"line":77,"column":null}},"20":{"start":{"line":78,"column":17},"end":{"line":78,"column":null}},"21":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"22":{"start":{"line":79,"column":14},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":85,"column":null}},"24":{"start":{"line":81,"column":18},"end":{"line":81,"column":null}},"25":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"26":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}}},"fnMap":{"0":{"name":"loadGitTimestamps","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":42}},"loc":{"start":{"line":44,"column":42},"end":{"line":67,"column":null}},"line":44},"1":{"name":"getFileModTime","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":31}},"loc":{"start":{"line":75,"column":57},"end":{"line":86,"column":null}},"line":75}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"1":{"loc":{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},{"start":{"line":58,"column":13},"end":{"line":62,"column":null}}],"line":56},"2":{"loc":{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":50}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":32}},{"start":{"line":58,"column":32},"end":{"line":58,"column":50}}],"line":58},"4":{"loc":{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":199538,"6":199535,"7":3,"8":3,"9":3,"10":3,"11":3,"12":82131,"13":3,"14":82128,"15":82122,"16":82122,"17":0,"18":199538,"19":199538,"20":199538,"21":199538,"22":199002,"23":536,"24":536,"25":536,"26":19},"f":{"0":199538,"1":199538},"b":{"0":[199535,3],"1":[3,82128],"2":[82122,6],"3":[82128,82122],"4":[82122,0],"5":[199002,536]},"meta":{"lastBranch":6,"lastFunction":2,"lastStatement":27,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"s:34:26:34:Infinity":3,"s:35:26:35:Infinity":4,"f:44:16:44:42":0,"b:45:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:45:2:45:Infinity":5,"s:45:27:45:Infinity":6,"s:46:2:46:Infinity":7,"s:47:2:66:Infinity":8,"s:48:19:53:Infinity":9,"s:54:27:54:Infinity":10,"s:55:4:63:Infinity":11,"b:56:6:62:Infinity:58:13:62:Infinity":1,"s:56:6:62:Infinity":12,"s:57:8:57:Infinity":13,"b:58:13:62:Infinity:undefined:undefined:undefined:undefined":2,"s:58:13:62:Infinity":14,"b:58:17:58:32:58:32:58:50":3,"b:59:8:61:Infinity:undefined:undefined:undefined:undefined":4,"s:59:8:61:Infinity":15,"s:60:10:60:Infinity":16,"s:65:4:65:Infinity":17,"f:75:16:75:31":1,"s:76:2:76:Infinity":18,"s:77:23:77:Infinity":19,"s:78:17:78:Infinity":20,"b:79:2:79:Infinity:undefined:undefined:undefined:undefined":5,"s:79:2:79:Infinity":21,"s:79:14:79:Infinity":22,"s:80:2:85:Infinity":23,"s:81:18:81:Infinity":24,"s:82:4:82:Infinity":25,"s:84:4:84:Infinity":26}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/hreflang.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":23,"column":21},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}}},"fnMap":{"0":{"name":"hreflangCode","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":29}},"loc":{"start":{"line":22,"column":51},"end":{"line":25,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23}},"s":{"0":1508993,"1":100199,"2":1408794},"f":{"0":1508993},"b":{"0":[100199,1408794]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:22:16:22:29":0,"b:23:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:23:2:23:Infinity":0,"s:23:21:23:Infinity":1,"s:24:2:24:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/i18n.ts","statementMap":{"0":{"start":{"line":113,"column":61},"end":{"line":548,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":32},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:113:61:548:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/render/page.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/render/page.ts","statementMap":{"0":{"start":{"line":32,"column":19},"end":{"line":32,"column":null}},"1":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"2":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":17},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":39},"end":{"line":38,"column":null}},"5":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":12},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"11":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"12":{"start":{"line":52,"column":25},"end":{"line":52,"column":null}},"13":{"start":{"line":54,"column":23},"end":{"line":54,"column":39}},"14":{"start":{"line":56,"column":29},"end":{"line":65,"column":null}},"15":{"start":{"line":57,"column":19},"end":{"line":57,"column":29}},"16":{"start":{"line":59,"column":17},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":19},"end":{"line":60,"column":null}},"18":{"start":{"line":61,"column":6},"end":{"line":62,"column":null}},"19":{"start":{"line":67,"column":25},"end":{"line":73,"column":null}},"20":{"start":{"line":68,"column":15},"end":{"line":68,"column":null}},"21":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"22":{"start":{"line":70,"column":4},"end":{"line":71,"column":null}},"23":{"start":{"line":75,"column":25},"end":{"line":83,"column":null}},"24":{"start":{"line":76,"column":15},"end":{"line":76,"column":null}},"25":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"26":{"start":{"line":78,"column":21},"end":{"line":78,"column":null}},"27":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"28":{"start":{"line":79,"column":34},"end":{"line":79,"column":null}},"29":{"start":{"line":80,"column":4},"end":{"line":81,"column":null}},"30":{"start":{"line":85,"column":26},"end":{"line":96,"column":null}},"31":{"start":{"line":86,"column":25},"end":{"line":86,"column":null}},"32":{"start":{"line":87,"column":24},"end":{"line":87,"column":null}},"33":{"start":{"line":88,"column":21},"end":{"line":90,"column":null}},"34":{"start":{"line":91,"column":4},"end":{"line":94,"column":null}},"35":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"36":{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},"37":{"start":{"line":100,"column":4},"end":{"line":102,"column":null}},"38":{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},"39":{"start":{"line":105,"column":6},"end":{"line":108,"column":null}},"40":{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},"41":{"start":{"line":112,"column":6},"end":{"line":115,"column":null}},"42":{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},"43":{"start":{"line":119,"column":6},"end":{"line":122,"column":null}},"44":{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},"45":{"start":{"line":126,"column":6},"end":{"line":129,"column":null}},"46":{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},"47":{"start":{"line":133,"column":6},"end":{"line":136,"column":null}},"48":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"49":{"start":{"line":144,"column":64},"end":{"line":144,"column":null}},"50":{"start":{"line":145,"column":2},"end":{"line":147,"column":null}},"51":{"start":{"line":146,"column":4},"end":{"line":146,"column":null}},"52":{"start":{"line":149,"column":43},"end":{"line":149,"column":null}},"53":{"start":{"line":150,"column":43},"end":{"line":150,"column":null}},"54":{"start":{"line":151,"column":18},"end":{"line":151,"column":null}},"55":{"start":{"line":152,"column":18},"end":{"line":152,"column":null}},"56":{"start":{"line":154,"column":23},"end":{"line":154,"column":null}},"57":{"start":{"line":155,"column":26},"end":{"line":155,"column":null}},"58":{"start":{"line":156,"column":25},"end":{"line":156,"column":null}},"59":{"start":{"line":157,"column":23},"end":{"line":157,"column":null}},"60":{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},"61":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"62":{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},"63":{"start":{"line":161,"column":16},"end":{"line":161,"column":null}},"64":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"65":{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},"66":{"start":{"line":164,"column":6},"end":{"line":164,"column":null}},"67":{"start":{"line":167,"column":22},"end":{"line":178,"column":null}},"68":{"start":{"line":179,"column":19},"end":{"line":179,"column":null}},"69":{"start":{"line":181,"column":19},"end":{"line":181,"column":null}},"70":{"start":{"line":183,"column":28},"end":{"line":221,"column":null}},"71":{"start":{"line":223,"column":19},"end":{"line":223,"column":null}},"72":{"start":{"line":224,"column":2},"end":{"line":236,"column":null}},"73":{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},"74":{"start":{"line":239,"column":27},"end":{"line":239,"column":null}},"75":{"start":{"line":240,"column":4},"end":{"line":253,"column":null}},"76":{"start":{"line":247,"column":59},"end":{"line":252,"column":8}},"77":{"start":{"line":256,"column":21},"end":{"line":256,"column":null}},"78":{"start":{"line":399,"column":17},"end":{"line":418,"column":null}},"79":{"start":{"line":420,"column":15},"end":{"line":524,"column":null}},"80":{"start":{"line":521,"column":22},"end":{"line":524,"column":24}},"81":{"start":{"line":528,"column":2},"end":{"line":531,"column":null}}},"fnMap":{"0":{"name":"generateSitemapHtml","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":36}},"loc":{"start":{"line":43,"column":106},"end":{"line":532,"column":null}},"line":43},"1":{"name":"(anonymous_1)","decl":{"start":{"line":57,"column":5},"end":{"line":57,"column":13}},"loc":{"start":{"line":57,"column":19},"end":{"line":57,"column":29}},"line":57},"2":{"name":"(anonymous_2)","decl":{"start":{"line":58,"column":5},"end":{"line":58,"column":10}},"loc":{"start":{"line":58,"column":16},"end":{"line":64,"column":5}},"line":58},"3":{"name":"(anonymous_3)","decl":{"start":{"line":67,"column":35},"end":{"line":67,"column":40}},"loc":{"start":{"line":67,"column":46},"end":{"line":73,"column":3}},"line":67},"4":{"name":"(anonymous_4)","decl":{"start":{"line":75,"column":35},"end":{"line":75,"column":40}},"loc":{"start":{"line":75,"column":46},"end":{"line":83,"column":3}},"line":75},"5":{"name":"(anonymous_5)","decl":{"start":{"line":85,"column":41},"end":{"line":85,"column":46}},"loc":{"start":{"line":85,"column":58},"end":{"line":96,"column":3}},"line":85},"6":{"name":"(anonymous_6)","decl":{"start":{"line":247,"column":38},"end":{"line":247,"column":43}},"loc":{"start":{"line":247,"column":59},"end":{"line":252,"column":8}},"line":247},"7":{"name":"(anonymous_7)","decl":{"start":{"line":521,"column":11},"end":{"line":521,"column":16}},"loc":{"start":{"line":521,"column":22},"end":{"line":524,"column":24}},"line":521}},"branchMap":{"0":{"loc":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":34},"end":{"line":47,"column":51}},{"start":{"line":47,"column":51},"end":{"line":47,"column":null}}],"line":47},"1":{"loc":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":47}},{"start":{"line":48,"column":47},"end":{"line":48,"column":null}}],"line":48},"2":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":36},"end":{"line":49,"column":56}},{"start":{"line":49,"column":56},"end":{"line":49,"column":null}}],"line":49},"3":{"loc":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":19},"end":{"line":51,"column":47}},{"start":{"line":51,"column":47},"end":{"line":51,"column":null}}],"line":51},"4":{"loc":{"start":{"line":60,"column":19},"end":{"line":60,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":32},"end":{"line":60,"column":49}},{"start":{"line":60,"column":49},"end":{"line":60,"column":null}}],"line":60},"5":{"loc":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":69,"column":30},"end":{"line":69,"column":45}},{"start":{"line":69,"column":45},"end":{"line":69,"column":null}}],"line":69},"6":{"loc":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":31},"end":{"line":77,"column":56}},{"start":{"line":77,"column":56},"end":{"line":77,"column":null}}],"line":77},"7":{"loc":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79},"8":{"loc":{"start":{"line":88,"column":21},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},{"start":{"line":90,"column":8},"end":{"line":90,"column":null}}],"line":88},"9":{"loc":{"start":{"line":94,"column":26},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":40},"end":{"line":94,"column":94}},{"start":{"line":94,"column":94},"end":{"line":94,"column":null}}],"line":94},"10":{"loc":{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":99},"11":{"loc":{"start":{"line":99,"column":6},"end":{"line":99,"column":123}},"type":"binary-expr","locations":[{"start":{"line":99,"column":6},"end":{"line":99,"column":28}},{"start":{"line":99,"column":28},"end":{"line":99,"column":48}},{"start":{"line":99,"column":48},"end":{"line":99,"column":73}},{"start":{"line":99,"column":73},"end":{"line":99,"column":101}},{"start":{"line":99,"column":101},"end":{"line":99,"column":123}}],"line":99},"12":{"loc":{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},{"start":{},"end":{}}],"line":104},"13":{"loc":{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":111},"14":{"loc":{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":118},"15":{"loc":{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":125},"16":{"loc":{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":132},"17":{"loc":{"start":{"line":146,"column":28},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":41},"end":{"line":146,"column":58}},{"start":{"line":146,"column":58},"end":{"line":146,"column":null}}],"line":146},"18":{"loc":{"start":{"line":151,"column":18},"end":{"line":151,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":40},"end":{"line":151,"column":45}},{"start":{"line":151,"column":45},"end":{"line":151,"column":null}}],"line":151},"19":{"loc":{"start":{"line":151,"column":45},"end":{"line":151,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":67},"end":{"line":151,"column":73}},{"start":{"line":151,"column":73},"end":{"line":151,"column":null}}],"line":151},"20":{"loc":{"start":{"line":152,"column":18},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":40},"end":{"line":152,"column":46}},{"start":{"line":152,"column":46},"end":{"line":152,"column":null}}],"line":152},"21":{"loc":{"start":{"line":152,"column":46},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":68},"end":{"line":152,"column":74}},{"start":{"line":152,"column":74},"end":{"line":152,"column":null}}],"line":152},"22":{"loc":{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},{"start":{"line":160,"column":9},"end":{"line":166,"column":null}}],"line":158},"23":{"loc":{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":160},"24":{"loc":{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":163},"25":{"loc":{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":238},"26":{"loc":{"start":{"line":408,"column":13},"end":{"line":408,"column":null}},"type":"cond-expr","locations":[{"start":{"line":408,"column":29},"end":{"line":408,"column":42}},{"start":{"line":408,"column":42},"end":{"line":408,"column":null}}],"line":408},"27":{"loc":{"start":{"line":433,"column":82},"end":{"line":434,"column":null}},"type":"cond-expr","locations":[{"start":{"line":433,"column":93},"end":{"line":434,"column":88}},{"start":{"line":434,"column":88},"end":{"line":434,"column":null}}],"line":433},"28":{"loc":{"start":{"line":473,"column":31},"end":{"line":473,"column":117}},"type":"cond-expr","locations":[{"start":{"line":473,"column":47},"end":{"line":473,"column":79}},{"start":{"line":473,"column":79},"end":{"line":473,"column":117}}],"line":473},"29":{"loc":{"start":{"line":477,"column":14},"end":{"line":481,"column":null}},"type":"cond-expr","locations":[{"start":{"line":477,"column":42},"end":{"line":481,"column":null}},{"start":{"line":481,"column":21},"end":{"line":481,"column":null}}],"line":477}},"s":{"0":30,"1":30,"2":30,"3":30,"4":30,"5":23,"6":23,"7":23,"8":23,"9":23,"10":23,"11":23,"12":23,"13":23,"14":23,"15":322,"16":299,"17":299,"18":299,"19":23,"20":322,"21":322,"22":322,"23":23,"24":322,"25":322,"26":322,"27":322,"28":0,"29":322,"30":23,"31":11472,"32":11472,"33":11472,"34":11472,"35":23,"36":23,"37":23,"38":23,"39":23,"40":23,"41":23,"42":23,"43":23,"44":23,"45":0,"46":23,"47":23,"48":23,"49":23,"50":23,"51":322,"52":23,"53":23,"54":23,"55":23,"56":23,"57":23,"58":23,"59":23,"60":23,"61":0,"62":23,"63":0,"64":0,"65":0,"66":0,"67":23,"68":23,"69":23,"70":23,"71":23,"72":23,"73":23,"74":23,"75":23,"76":4600,"77":23,"78":23,"79":23,"80":115,"81":23},"f":{"0":23,"1":322,"2":299,"3":322,"4":322,"5":11472,"6":4600,"7":115},"b":{"0":[13,10],"1":[13,10],"2":[13,10],"3":[23,0],"4":[10,289],"5":[23,299],"6":[23,299],"7":[0,322],"8":[11382,90],"9":[11472,0],"10":[23,0],"11":[23,0,0,0,0],"12":[23,0],"13":[23,0],"14":[23,0],"15":[0,23],"16":[23,0],"17":[23,299],"18":[2,21],"19":[3,18],"20":[2,21],"21":[3,18],"22":[0,23],"23":[0,23],"24":[0,0],"25":[23,0],"26":[13,10],"27":[23,0],"28":[13,10],"29":[23,0]},"meta":{"lastBranch":30,"lastFunction":8,"lastStatement":82,"seen":{"s:32:19:32:Infinity":0,"s:33:18:33:Infinity":1,"s:35:17:35:Infinity":2,"s:36:17:36:Infinity":3,"s:38:39:38:Infinity":4,"f:43:16:43:36":0,"s:44:15:44:Infinity":5,"s:45:12:45:Infinity":6,"s:46:20:46:Infinity":7,"s:47:22:47:Infinity":8,"b:47:34:47:51:47:51:47:Infinity":0,"s:48:20:48:Infinity":9,"b:48:32:48:47:48:47:48:Infinity":1,"s:49:24:49:Infinity":10,"b:49:36:49:56:49:56:49:Infinity":2,"s:51:19:51:Infinity":11,"b:51:19:51:47:51:47:51:Infinity":3,"s:52:25:52:Infinity":12,"s:54:23:54:39":13,"s:56:29:65:Infinity":14,"f:57:5:57:13":1,"s:57:19:57:29":15,"f:58:5:58:10":2,"s:59:17:59:Infinity":16,"s:60:19:60:Infinity":17,"b:60:32:60:49:60:49:60:Infinity":4,"s:61:6:62:Infinity":18,"s:67:25:73:Infinity":19,"f:67:35:67:40":3,"s:68:15:68:Infinity":20,"s:69:17:69:Infinity":21,"b:69:30:69:45:69:45:69:Infinity":5,"s:70:4:71:Infinity":22,"s:75:25:83:Infinity":23,"f:75:35:75:40":4,"s:76:15:76:Infinity":24,"s:77:18:77:Infinity":25,"b:77:31:77:56:77:56:77:Infinity":6,"s:78:21:78:Infinity":26,"b:79:4:79:Infinity:undefined:undefined:undefined:undefined":7,"s:79:4:79:Infinity":27,"s:79:34:79:Infinity":28,"s:80:4:81:Infinity":29,"s:85:26:96:Infinity":30,"f:85:41:85:46":5,"s:86:25:86:Infinity":31,"s:87:24:87:Infinity":32,"s:88:21:90:Infinity":33,"b:89:8:89:Infinity:90:8:90:Infinity":8,"s:91:4:94:Infinity":34,"b:94:40:94:94:94:94:94:Infinity":9,"s:98:17:98:Infinity":35,"b:99:2:142:Infinity:undefined:undefined:undefined:undefined":10,"s:99:2:142:Infinity":36,"b:99:6:99:28:99:28:99:48:99:48:99:73:99:73:99:101:99:101:99:123":11,"s:100:4:102:Infinity":37,"b:104:4:110:Infinity:undefined:undefined:undefined:undefined":12,"s:104:4:110:Infinity":38,"s:105:6:108:Infinity":39,"b:111:4:117:Infinity:undefined:undefined:undefined:undefined":13,"s:111:4:117:Infinity":40,"s:112:6:115:Infinity":41,"b:118:4:124:Infinity:undefined:undefined:undefined:undefined":14,"s:118:4:124:Infinity":42,"s:119:6:122:Infinity":43,"b:125:4:131:Infinity:undefined:undefined:undefined:undefined":15,"s:125:4:131:Infinity":44,"s:126:6:129:Infinity":45,"b:132:4:138:Infinity:undefined:undefined:undefined:undefined":16,"s:132:4:138:Infinity":46,"s:133:6:136:Infinity":47,"s:139:4:139:Infinity":48,"s:144:64:144:Infinity":49,"s:145:2:147:Infinity":50,"s:146:4:146:Infinity":51,"b:146:41:146:58:146:58:146:Infinity":17,"s:149:43:149:Infinity":52,"s:150:43:150:Infinity":53,"s:151:18:151:Infinity":54,"b:151:40:151:45:151:45:151:Infinity":18,"b:151:67:151:73:151:73:151:Infinity":19,"s:152:18:152:Infinity":55,"b:152:40:152:46:152:46:152:Infinity":20,"b:152:68:152:74:152:74:152:Infinity":21,"s:154:23:154:Infinity":56,"s:155:26:155:Infinity":57,"s:156:25:156:Infinity":58,"s:157:23:157:Infinity":59,"b:158:2:166:Infinity:160:9:166:Infinity":22,"s:158:2:166:Infinity":60,"s:159:4:159:Infinity":61,"b:160:9:166:Infinity:undefined:undefined:undefined:undefined":23,"s:160:9:166:Infinity":62,"s:161:16:161:Infinity":63,"s:162:4:162:Infinity":64,"b:163:4:165:Infinity:undefined:undefined:undefined:undefined":24,"s:163:4:165:Infinity":65,"s:164:6:164:Infinity":66,"s:167:22:178:Infinity":67,"s:179:19:179:Infinity":68,"s:181:19:181:Infinity":69,"s:183:28:221:Infinity":70,"s:223:19:223:Infinity":71,"s:224:2:236:Infinity":72,"b:238:2:254:Infinity:undefined:undefined:undefined:undefined":25,"s:238:2:254:Infinity":73,"s:239:27:239:Infinity":74,"s:240:4:253:Infinity":75,"f:247:38:247:43":6,"s:247:59:252:8":76,"s:256:21:256:Infinity":77,"s:399:17:418:Infinity":78,"b:408:29:408:42:408:42:408:Infinity":26,"s:420:15:524:Infinity":79,"b:433:93:434:88:434:88:434:Infinity":27,"b:473:47:473:79:473:79:473:117":28,"b:477:42:481:Infinity:481:21:481:Infinity":29,"f:521:11:521:16":7,"s:521:22:524:24":80,"s:528:2:531:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/url-entry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/url-entry.ts","statementMap":{"0":{"start":{"line":20,"column":17},"end":{"line":20,"column":null}},"1":{"start":{"line":38,"column":12},"end":{"line":43,"column":null}},"2":{"start":{"line":45,"column":2},"end":{"line":48,"column":null}},"3":{"start":{"line":46,"column":4},"end":{"line":47,"column":null}},"4":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"5":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"generateUrlEntry","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":54,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":13},"end":{"line":45,"column":22}},"loc":{"start":{"line":45,"column":30},"end":{"line":48,"column":3}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":36},"end":{"line":36,"column":null}}],"line":36}},"s":{"0":3,"1":199331,"2":199331,"3":1508977,"4":199331,"5":199331},"f":{"0":199331,"1":1508977},"b":{"0":[199331]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":6,"seen":{"s:20:17:20:Infinity":0,"f:31:16:31:Infinity":0,"b:36:36:36:Infinity":0,"s:38:12:43:Infinity":1,"s:45:2:48:Infinity":2,"f:45:13:45:22":1,"s:46:4:47:Infinity":3,"s:50:2:50:Infinity":4,"s:53:2:53:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/sitemap.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/sitemap.ts","statementMap":{"0":{"start":{"line":31,"column":19},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"2":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"4":{"start":{"line":37,"column":39},"end":{"line":37,"column":null}},"5":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"7":{"start":{"line":50,"column":12},"end":{"line":50,"column":null}},"8":{"start":{"line":54,"column":47},"end":{"line":60,"column":null}},"9":{"start":{"line":55,"column":32},"end":{"line":58,"column":6}},"10":{"start":{"line":58,"column":24},"end":{"line":58,"column":46}},"11":{"start":{"line":62,"column":21},"end":{"line":62,"column":null}},"12":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"13":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}},"14":{"start":{"line":65,"column":29},"end":{"line":65,"column":42}},"15":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"17":{"start":{"line":67,"column":28},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":20},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"20":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"21":{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},"22":{"start":{"line":75,"column":37},"end":{"line":75,"column":null}},"23":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"24":{"start":{"line":82,"column":2},"end":{"line":88,"column":null}},"25":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"26":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"27":{"start":{"line":84,"column":28},"end":{"line":84,"column":null}},"28":{"start":{"line":85,"column":21},"end":{"line":85,"column":null}},"29":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"30":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"31":{"start":{"line":90,"column":51},"end":{"line":96,"column":null}},"32":{"start":{"line":91,"column":32},"end":{"line":94,"column":6}},"33":{"start":{"line":94,"column":24},"end":{"line":94,"column":68}},"34":{"start":{"line":98,"column":27},"end":{"line":98,"column":null}},"35":{"start":{"line":99,"column":2},"end":{"line":99,"column":null}},"36":{"start":{"line":101,"column":2},"end":{"line":109,"column":null}},"37":{"start":{"line":101,"column":29},"end":{"line":101,"column":42}},"38":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"39":{"start":{"line":103,"column":26},"end":{"line":103,"column":null}},"40":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"41":{"start":{"line":105,"column":22},"end":{"line":105,"column":null}},"42":{"start":{"line":106,"column":23},"end":{"line":106,"column":null}},"43":{"start":{"line":107,"column":6},"end":{"line":107,"column":null}},"44":{"start":{"line":111,"column":33},"end":{"line":121,"column":null}},"45":{"start":{"line":123,"column":2},"end":{"line":148,"column":null}},"46":{"start":{"line":124,"column":19},"end":{"line":124,"column":null}},"47":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"48":{"start":{"line":125,"column":32},"end":{"line":125,"column":null}},"49":{"start":{"line":126,"column":22},"end":{"line":126,"column":null}},"50":{"start":{"line":127,"column":44},"end":{"line":135,"column":null}},"51":{"start":{"line":128,"column":34},"end":{"line":133,"column":8}},"52":{"start":{"line":133,"column":26},"end":{"line":133,"column":70}},"53":{"start":{"line":136,"column":4},"end":{"line":138,"column":null}},"54":{"start":{"line":139,"column":4},"end":{"line":147,"column":null}},"55":{"start":{"line":139,"column":31},"end":{"line":139,"column":44}},"56":{"start":{"line":140,"column":23},"end":{"line":140,"column":null}},"57":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"58":{"start":{"line":141,"column":36},"end":{"line":141,"column":null}},"59":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"60":{"start":{"line":143,"column":23},"end":{"line":143,"column":null}},"61":{"start":{"line":144,"column":6},"end":{"line":146,"column":null}},"62":{"start":{"line":150,"column":49},"end":{"line":156,"column":null}},"63":{"start":{"line":151,"column":32},"end":{"line":154,"column":6}},"64":{"start":{"line":154,"column":24},"end":{"line":154,"column":46}},"65":{"start":{"line":158,"column":25},"end":{"line":158,"column":null}},"66":{"start":{"line":159,"column":2},"end":{"line":159,"column":null}},"67":{"start":{"line":161,"column":2},"end":{"line":167,"column":null}},"68":{"start":{"line":161,"column":29},"end":{"line":161,"column":42}},"69":{"start":{"line":162,"column":17},"end":{"line":162,"column":null}},"70":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"71":{"start":{"line":163,"column":29},"end":{"line":163,"column":null}},"72":{"start":{"line":164,"column":20},"end":{"line":164,"column":null}},"73":{"start":{"line":165,"column":21},"end":{"line":165,"column":null}},"74":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"75":{"start":{"line":169,"column":23},"end":{"line":175,"column":null}},"76":{"start":{"line":170,"column":32},"end":{"line":173,"column":6}},"77":{"start":{"line":173,"column":24},"end":{"line":173,"column":46}},"78":{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},"79":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"80":{"start":{"line":178,"column":4},"end":{"line":178,"column":null}},"81":{"start":{"line":181,"column":2},"end":{"line":187,"column":null}},"82":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"83":{"start":{"line":182,"column":23},"end":{"line":182,"column":null}},"84":{"start":{"line":183,"column":17},"end":{"line":183,"column":null}},"85":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"86":{"start":{"line":184,"column":29},"end":{"line":184,"column":null}},"87":{"start":{"line":185,"column":20},"end":{"line":185,"column":null}},"88":{"start":{"line":186,"column":4},"end":{"line":186,"column":null}},"89":{"start":{"line":189,"column":8},"end":{"line":190,"column":null}},"90":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"91":{"start":{"line":192,"column":24},"end":{"line":194,"column":null}},"92":{"start":{"line":194,"column":22},"end":{"line":194,"column":62}},"93":{"start":{"line":195,"column":26},"end":{"line":201,"column":null}},"94":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"95":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"96":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"97":{"start":{"line":202,"column":28},"end":{"line":204,"column":null}},"98":{"start":{"line":203,"column":54},"end":{"line":203,"column":65}},"99":{"start":{"line":206,"column":51},"end":{"line":214,"column":null}},"100":{"start":{"line":208,"column":24},"end":{"line":208,"column":82}},"101":{"start":{"line":209,"column":22},"end":{"line":212,"column":8}},"102":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"103":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"104":{"start":{"line":220,"column":2},"end":{"line":226,"column":null}},"105":{"start":{"line":220,"column":29},"end":{"line":220,"column":42}},"106":{"start":{"line":221,"column":17},"end":{"line":221,"column":null}},"107":{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},"108":{"start":{"line":222,"column":51},"end":{"line":222,"column":null}},"109":{"start":{"line":223,"column":20},"end":{"line":223,"column":null}},"110":{"start":{"line":224,"column":21},"end":{"line":224,"column":null}},"111":{"start":{"line":225,"column":4},"end":{"line":225,"column":null}},"112":{"start":{"line":228,"column":19},"end":{"line":228,"column":35}},"113":{"start":{"line":229,"column":2},"end":{"line":229,"column":null}},"114":{"start":{"line":231,"column":2},"end":{"line":252,"column":null}},"115":{"start":{"line":232,"column":28},"end":{"line":236,"column":null}},"116":{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},"117":{"start":{"line":233,"column":22},"end":{"line":233,"column":null}},"118":{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},"119":{"start":{"line":234,"column":22},"end":{"line":234,"column":null}},"120":{"start":{"line":235,"column":6},"end":{"line":235,"column":null}},"121":{"start":{"line":238,"column":44},"end":{"line":241,"column":null}},"122":{"start":{"line":238,"column":78},"end":{"line":241,"column":6}},"123":{"start":{"line":243,"column":4},"end":{"line":246,"column":null}},"124":{"start":{"line":248,"column":4},"end":{"line":251,"column":null}},"125":{"start":{"line":249,"column":18},"end":{"line":249,"column":null}},"126":{"start":{"line":250,"column":6},"end":{"line":250,"column":null}},"127":{"start":{"line":254,"column":18},"end":{"line":254,"column":29}},"128":{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},"129":{"start":{"line":256,"column":4},"end":{"line":256,"column":null}},"130":{"start":{"line":258,"column":4},"end":{"line":262,"column":null}},"131":{"start":{"line":259,"column":18},"end":{"line":259,"column":null}},"132":{"start":{"line":260,"column":23},"end":{"line":260,"column":null}},"133":{"start":{"line":261,"column":6},"end":{"line":261,"column":null}},"134":{"start":{"line":265,"column":19},"end":{"line":265,"column":31}},"135":{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},"136":{"start":{"line":267,"column":4},"end":{"line":267,"column":null}},"137":{"start":{"line":269,"column":4},"end":{"line":273,"column":null}},"138":{"start":{"line":270,"column":18},"end":{"line":270,"column":null}},"139":{"start":{"line":271,"column":23},"end":{"line":271,"column":null}},"140":{"start":{"line":272,"column":6},"end":{"line":272,"column":null}},"141":{"start":{"line":276,"column":2},"end":{"line":276,"column":null}},"142":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}}},"fnMap":{"0":{"name":"existsAtRoot","decl":{"start":{"line":40,"column":9},"end":{"line":40,"column":22}},"loc":{"start":{"line":40,"column":48},"end":{"line":42,"column":null}},"line":40},"1":{"name":"generateSitemap","decl":{"start":{"line":47,"column":16},"end":{"line":47,"column":42}},"loc":{"start":{"line":47,"column":42},"end":{"line":281,"column":null}},"line":47},"2":{"name":"(anonymous_2)","decl":{"start":{"line":55,"column":17},"end":{"line":55,"column":22}},"loc":{"start":{"line":55,"column":32},"end":{"line":58,"column":6}},"line":55},"3":{"name":"(anonymous_3)","decl":{"start":{"line":58,"column":8},"end":{"line":58,"column":16}},"loc":{"start":{"line":58,"column":24},"end":{"line":58,"column":46}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":65,"column":12},"end":{"line":65,"column":20}},"loc":{"start":{"line":65,"column":29},"end":{"line":65,"column":42}},"line":65},"5":{"name":"(anonymous_5)","decl":{"start":{"line":65,"column":44},"end":{"line":65,"column":53}},"loc":{"start":{"line":65,"column":62},"end":{"line":72,"column":3}},"line":65},"6":{"name":"(anonymous_6)","decl":{"start":{"line":91,"column":17},"end":{"line":91,"column":22}},"loc":{"start":{"line":91,"column":32},"end":{"line":94,"column":6}},"line":91},"7":{"name":"(anonymous_7)","decl":{"start":{"line":94,"column":8},"end":{"line":94,"column":16}},"loc":{"start":{"line":94,"column":24},"end":{"line":94,"column":68}},"line":94},"8":{"name":"(anonymous_8)","decl":{"start":{"line":101,"column":12},"end":{"line":101,"column":20}},"loc":{"start":{"line":101,"column":29},"end":{"line":101,"column":42}},"line":101},"9":{"name":"(anonymous_9)","decl":{"start":{"line":101,"column":44},"end":{"line":101,"column":53}},"loc":{"start":{"line":101,"column":62},"end":{"line":109,"column":3}},"line":101},"10":{"name":"(anonymous_10)","decl":{"start":{"line":123,"column":25},"end":{"line":123,"column":34}},"loc":{"start":{"line":123,"column":43},"end":{"line":148,"column":3}},"line":123},"11":{"name":"(anonymous_11)","decl":{"start":{"line":128,"column":19},"end":{"line":128,"column":24}},"loc":{"start":{"line":128,"column":34},"end":{"line":133,"column":8}},"line":128},"12":{"name":"(anonymous_12)","decl":{"start":{"line":133,"column":10},"end":{"line":133,"column":18}},"loc":{"start":{"line":133,"column":26},"end":{"line":133,"column":70}},"line":133},"13":{"name":"(anonymous_13)","decl":{"start":{"line":139,"column":14},"end":{"line":139,"column":22}},"loc":{"start":{"line":139,"column":31},"end":{"line":139,"column":44}},"line":139},"14":{"name":"(anonymous_14)","decl":{"start":{"line":139,"column":46},"end":{"line":139,"column":55}},"loc":{"start":{"line":139,"column":64},"end":{"line":147,"column":5}},"line":139},"15":{"name":"(anonymous_15)","decl":{"start":{"line":151,"column":17},"end":{"line":151,"column":22}},"loc":{"start":{"line":151,"column":32},"end":{"line":154,"column":6}},"line":151},"16":{"name":"(anonymous_16)","decl":{"start":{"line":154,"column":8},"end":{"line":154,"column":16}},"loc":{"start":{"line":154,"column":24},"end":{"line":154,"column":46}},"line":154},"17":{"name":"(anonymous_17)","decl":{"start":{"line":161,"column":12},"end":{"line":161,"column":20}},"loc":{"start":{"line":161,"column":29},"end":{"line":161,"column":42}},"line":161},"18":{"name":"(anonymous_18)","decl":{"start":{"line":161,"column":44},"end":{"line":161,"column":53}},"loc":{"start":{"line":161,"column":62},"end":{"line":167,"column":3}},"line":161},"19":{"name":"(anonymous_19)","decl":{"start":{"line":170,"column":17},"end":{"line":170,"column":22}},"loc":{"start":{"line":170,"column":32},"end":{"line":173,"column":6}},"line":170},"20":{"name":"(anonymous_20)","decl":{"start":{"line":173,"column":8},"end":{"line":173,"column":16}},"loc":{"start":{"line":173,"column":24},"end":{"line":173,"column":46}},"line":173},"21":{"name":"(anonymous_21)","decl":{"start":{"line":189,"column":8},"end":{"line":189,"column":28}},"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"line":190},"22":{"name":"(anonymous_22)","decl":{"start":{"line":194,"column":5},"end":{"line":194,"column":13}},"loc":{"start":{"line":194,"column":22},"end":{"line":194,"column":62}},"line":194},"23":{"name":"(anonymous_23)","decl":{"start":{"line":195,"column":40},"end":{"line":195,"column":45}},"loc":{"start":{"line":195,"column":54},"end":{"line":201,"column":3}},"line":195},"24":{"name":"(anonymous_24)","decl":{"start":{"line":203,"column":43},"end":{"line":203,"column":48}},"loc":{"start":{"line":203,"column":54},"end":{"line":203,"column":65}},"line":203},"25":{"name":"(anonymous_25)","decl":{"start":{"line":208,"column":7},"end":{"line":208,"column":15}},"loc":{"start":{"line":208,"column":24},"end":{"line":208,"column":82}},"line":208},"26":{"name":"(anonymous_26)","decl":{"start":{"line":209,"column":7},"end":{"line":209,"column":12}},"loc":{"start":{"line":209,"column":22},"end":{"line":212,"column":8}},"line":209},"27":{"name":"(anonymous_27)","decl":{"start":{"line":220,"column":12},"end":{"line":220,"column":20}},"loc":{"start":{"line":220,"column":29},"end":{"line":220,"column":42}},"line":220},"28":{"name":"(anonymous_28)","decl":{"start":{"line":220,"column":44},"end":{"line":220,"column":53}},"loc":{"start":{"line":220,"column":62},"end":{"line":226,"column":3}},"line":220},"29":{"name":"(anonymous_29)","decl":{"start":{"line":231,"column":11},"end":{"line":231,"column":20}},"loc":{"start":{"line":231,"column":32},"end":{"line":252,"column":3}},"line":231},"30":{"name":"(anonymous_30)","decl":{"start":{"line":232,"column":51},"end":{"line":232,"column":57}},"loc":{"start":{"line":232,"column":66},"end":{"line":236,"column":5}},"line":232},"31":{"name":"(anonymous_31)","decl":{"start":{"line":238,"column":60},"end":{"line":238,"column":65}},"loc":{"start":{"line":238,"column":78},"end":{"line":241,"column":6}},"line":238},"32":{"name":"(anonymous_32)","decl":{"start":{"line":248,"column":20},"end":{"line":248,"column":29}},"loc":{"start":{"line":248,"column":38},"end":{"line":251,"column":5}},"line":248},"33":{"name":"(anonymous_33)","decl":{"start":{"line":258,"column":12},"end":{"line":258,"column":21}},"loc":{"start":{"line":258,"column":29},"end":{"line":262,"column":5}},"line":258},"34":{"name":"(anonymous_34)","decl":{"start":{"line":269,"column":13},"end":{"line":269,"column":22}},"loc":{"start":{"line":269,"column":30},"end":{"line":273,"column":5}},"line":269}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":12},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":28},"end":{"line":57,"column":43}},{"start":{"line":57,"column":43},"end":{"line":57,"column":null}}],"line":57},"1":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"2":{"loc":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":69,"column":37},"end":{"line":69,"column":45}},{"start":{"line":69,"column":45},"end":{"line":69,"column":null}}],"line":69},"3":{"loc":{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":74},"4":{"loc":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":32},"end":{"line":83,"column":44}},{"start":{"line":83,"column":44},"end":{"line":83,"column":null}}],"line":83},"5":{"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"6":{"loc":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":37},"end":{"line":86,"column":45}},{"start":{"line":86,"column":45},"end":{"line":86,"column":null}}],"line":86},"7":{"loc":{"start":{"line":93,"column":12},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":28},"end":{"line":93,"column":53}},{"start":{"line":93,"column":53},"end":{"line":93,"column":null}}],"line":93},"8":{"loc":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":104},"9":{"loc":{"start":{"line":106,"column":23},"end":{"line":106,"column":null}},"type":"cond-expr","locations":[{"start":{"line":106,"column":39},"end":{"line":106,"column":47}},{"start":{"line":106,"column":47},"end":{"line":106,"column":null}}],"line":106},"10":{"loc":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":125},"11":{"loc":{"start":{"line":130,"column":14},"end":{"line":132,"column":null}},"type":"cond-expr","locations":[{"start":{"line":131,"column":12},"end":{"line":131,"column":null}},{"start":{"line":132,"column":12},"end":{"line":132,"column":null}}],"line":130},"12":{"loc":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"13":{"loc":{"start":{"line":143,"column":23},"end":{"line":143,"column":null}},"type":"cond-expr","locations":[{"start":{"line":143,"column":39},"end":{"line":143,"column":47}},{"start":{"line":143,"column":47},"end":{"line":143,"column":null}}],"line":143},"14":{"loc":{"start":{"line":153,"column":12},"end":{"line":153,"column":null}},"type":"cond-expr","locations":[{"start":{"line":153,"column":28},"end":{"line":153,"column":45}},{"start":{"line":153,"column":45},"end":{"line":153,"column":null}}],"line":153},"15":{"loc":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"16":{"loc":{"start":{"line":165,"column":21},"end":{"line":165,"column":null}},"type":"cond-expr","locations":[{"start":{"line":165,"column":37},"end":{"line":165,"column":45}},{"start":{"line":165,"column":45},"end":{"line":165,"column":null}}],"line":165},"17":{"loc":{"start":{"line":171,"column":12},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":171,"column":28},"end":{"line":171,"column":35}},{"start":{"line":171,"column":35},"end":{"line":171,"column":null}}],"line":171},"18":{"loc":{"start":{"line":172,"column":12},"end":{"line":172,"column":null}},"type":"cond-expr","locations":[{"start":{"line":172,"column":28},"end":{"line":172,"column":60}},{"start":{"line":172,"column":60},"end":{"line":172,"column":null}}],"line":172},"19":{"loc":{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":176},"20":{"loc":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"21":{"loc":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},{"start":{},"end":{}}],"line":184},"22":{"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"type":"cond-expr","locations":[{"start":{"line":190,"column":20},"end":{"line":190,"column":35}},{"start":{"line":190,"column":35},"end":{"line":190,"column":null}}],"line":190},"23":{"loc":{"start":{"line":202,"column":28},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":203,"column":6},"end":{"line":203,"column":null}},{"start":{"line":204,"column":6},"end":{"line":204,"column":null}}],"line":202},"24":{"loc":{"start":{"line":211,"column":14},"end":{"line":211,"column":null}},"type":"cond-expr","locations":[{"start":{"line":211,"column":30},"end":{"line":211,"column":40}},{"start":{"line":211,"column":40},"end":{"line":211,"column":null}}],"line":211},"25":{"loc":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},{"start":{},"end":{}}],"line":216},"26":{"loc":{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},{"start":{},"end":{}}],"line":222},"27":{"loc":{"start":{"line":224,"column":21},"end":{"line":224,"column":null}},"type":"cond-expr","locations":[{"start":{"line":224,"column":37},"end":{"line":224,"column":45}},{"start":{"line":224,"column":45},"end":{"line":224,"column":null}}],"line":224},"28":{"loc":{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},"type":"if","locations":[{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},{"start":{},"end":{}}],"line":233},"29":{"loc":{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},"type":"if","locations":[{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},{"start":{},"end":{}}],"line":234},"30":{"loc":{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},"type":"if","locations":[{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},{"start":{},"end":{}}],"line":255},"31":{"loc":{"start":{"line":260,"column":23},"end":{"line":260,"column":null}},"type":"cond-expr","locations":[{"start":{"line":260,"column":51},"end":{"line":260,"column":59}},{"start":{"line":260,"column":59},"end":{"line":260,"column":null}}],"line":260},"32":{"loc":{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},"type":"if","locations":[{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},{"start":{},"end":{}}],"line":266},"33":{"loc":{"start":{"line":271,"column":23},"end":{"line":271,"column":null}},"type":"cond-expr","locations":[{"start":{"line":271,"column":87},"end":{"line":271,"column":95}},{"start":{"line":271,"column":95},"end":{"line":271,"column":null}}],"line":271},"34":{"loc":{"start":{"line":271,"column":23},"end":{"line":271,"column":87}},"type":"binary-expr","locations":[{"start":{"line":271,"column":23},"end":{"line":271,"column":52}},{"start":{"line":271,"column":52},"end":{"line":271,"column":87}}],"line":271}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":1649,"6":17,"7":17,"8":17,"9":238,"10":238,"11":17,"12":17,"13":17,"14":238,"15":221,"16":221,"17":0,"18":221,"19":221,"20":221,"21":17,"22":17,"23":17,"24":17,"25":238,"26":238,"27":17,"28":221,"29":221,"30":238,"31":17,"32":238,"33":238,"34":17,"35":17,"36":17,"37":238,"38":221,"39":221,"40":221,"41":221,"42":221,"43":221,"44":17,"45":17,"46":153,"47":153,"48":0,"49":153,"50":153,"51":2142,"52":2142,"53":153,"54":153,"55":2142,"56":1989,"57":1989,"58":0,"59":1989,"60":1989,"61":1989,"62":17,"63":238,"64":238,"65":17,"66":17,"67":17,"68":238,"69":221,"70":221,"71":221,"72":0,"73":0,"74":221,"75":17,"76":238,"77":238,"78":17,"79":17,"80":17,"81":17,"82":238,"83":17,"84":221,"85":221,"86":0,"87":221,"88":221,"89":17,"90":697,"91":17,"92":238,"93":17,"94":224,"95":224,"96":0,"97":17,"98":224,"99":17,"100":238,"101":224,"102":17,"103":16,"104":17,"105":238,"106":221,"107":221,"108":13,"109":208,"110":208,"111":221,"112":17,"113":17,"114":17,"115":8908,"116":229143,"117":21335,"118":207808,"119":1717,"120":206091,"121":8908,"122":103445,"123":8908,"124":8908,"125":103445,"126":103445,"127":17,"128":17,"129":0,"130":0,"131":0,"132":0,"133":0,"134":17,"135":17,"136":17,"137":17,"138":92548,"139":92548,"140":92548,"141":17,"142":17},"f":{"0":1649,"1":17,"2":238,"3":238,"4":238,"5":221,"6":238,"7":238,"8":238,"9":221,"10":153,"11":2142,"12":2142,"13":2142,"14":1989,"15":238,"16":238,"17":238,"18":221,"19":238,"20":238,"21":697,"22":238,"23":224,"24":224,"25":238,"26":224,"27":238,"28":221,"29":8908,"30":229143,"31":103445,"32":103445,"33":0,"34":92548},"b":{"0":[17,221],"1":[0,221],"2":[17,204],"3":[17,0],"4":[17,221],"5":[17,221],"6":[0,221],"7":[17,221],"8":[221,0],"9":[17,204],"10":[0,153],"11":[153,1989],"12":[0,1989],"13":[153,1836],"14":[17,221],"15":[221,0],"16":[0,0],"17":[17,221],"18":[17,221],"19":[17,0],"20":[17,221],"21":[0,221],"22":[34,663],"23":[16,1],"24":[16,208],"25":[16,1],"26":[13,208],"27":[16,192],"28":[21335,207808],"29":[1717,206091],"30":[0,17],"31":[0,0],"32":[17,0],"33":[5593,86955],"34":[92548,92531]},"meta":{"lastBranch":35,"lastFunction":35,"lastStatement":143,"seen":{"s:31:19:31:Infinity":0,"s:32:18:32:Infinity":1,"s:34:17:34:Infinity":2,"s:35:17:35:Infinity":3,"s:37:39:37:Infinity":4,"f:40:9:40:22":0,"s:41:2:41:Infinity":5,"f:47:16:47:42":1,"s:48:2:48:Infinity":6,"s:50:12:50:Infinity":7,"s:54:47:60:Infinity":8,"f:55:17:55:22":2,"s:55:32:58:6":9,"b:57:28:57:43:57:43:57:Infinity":0,"f:58:8:58:16":3,"s:58:24:58:46":10,"s:62:21:62:Infinity":11,"s:63:2:63:Infinity":12,"s:65:2:72:Infinity":13,"f:65:12:65:20":4,"s:65:29:65:42":14,"f:65:44:65:53":5,"s:66:16:66:Infinity":15,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":1,"s:67:4:67:Infinity":16,"s:67:28:67:Infinity":17,"s:68:20:68:Infinity":18,"s:69:21:69:Infinity":19,"b:69:37:69:45:69:45:69:Infinity":2,"s:71:4:71:Infinity":20,"b:74:2:77:Infinity:undefined:undefined:undefined:undefined":3,"s:74:2:77:Infinity":21,"s:75:37:75:Infinity":22,"s:76:4:76:Infinity":23,"s:82:2:88:Infinity":24,"s:83:16:83:Infinity":25,"b:83:32:83:44:83:44:83:Infinity":4,"b:84:4:84:Infinity:undefined:undefined:undefined:undefined":5,"s:84:4:84:Infinity":26,"s:84:28:84:Infinity":27,"s:85:21:85:Infinity":28,"s:86:21:86:Infinity":29,"b:86:37:86:45:86:45:86:Infinity":6,"s:87:4:87:Infinity":30,"s:90:51:96:Infinity":31,"f:91:17:91:22":6,"s:91:32:94:6":32,"b:93:28:93:53:93:53:93:Infinity":7,"f:94:8:94:16":7,"s:94:24:94:68":33,"s:98:27:98:Infinity":34,"s:99:2:99:Infinity":35,"s:101:2:109:Infinity":36,"f:101:12:101:20":8,"s:101:29:101:42":37,"f:101:44:101:53":9,"s:102:16:102:Infinity":38,"s:103:26:103:Infinity":39,"b:104:4:108:Infinity:undefined:undefined:undefined:undefined":8,"s:104:4:108:Infinity":40,"s:105:22:105:Infinity":41,"s:106:23:106:Infinity":42,"b:106:39:106:47:106:47:106:Infinity":9,"s:107:6:107:Infinity":43,"s:111:33:121:Infinity":44,"s:123:2:148:Infinity":45,"f:123:25:123:34":10,"s:124:19:124:Infinity":46,"b:125:4:125:Infinity:undefined:undefined:undefined:undefined":10,"s:125:4:125:Infinity":47,"s:125:32:125:Infinity":48,"s:126:22:126:Infinity":49,"s:127:44:135:Infinity":50,"f:128:19:128:24":11,"s:128:34:133:8":51,"b:131:12:131:Infinity:132:12:132:Infinity":11,"f:133:10:133:18":12,"s:133:26:133:70":52,"s:136:4:138:Infinity":53,"s:139:4:147:Infinity":54,"f:139:14:139:22":13,"s:139:31:139:44":55,"f:139:46:139:55":14,"s:140:23:140:Infinity":56,"b:141:6:141:Infinity:undefined:undefined:undefined:undefined":12,"s:141:6:141:Infinity":57,"s:141:36:141:Infinity":58,"s:142:22:142:Infinity":59,"s:143:23:143:Infinity":60,"b:143:39:143:47:143:47:143:Infinity":13,"s:144:6:146:Infinity":61,"s:150:49:156:Infinity":62,"f:151:17:151:22":15,"s:151:32:154:6":63,"b:153:28:153:45:153:45:153:Infinity":14,"f:154:8:154:16":16,"s:154:24:154:46":64,"s:158:25:158:Infinity":65,"s:159:2:159:Infinity":66,"s:161:2:167:Infinity":67,"f:161:12:161:20":17,"s:161:29:161:42":68,"f:161:44:161:53":18,"s:162:17:162:Infinity":69,"b:163:4:163:Infinity:undefined:undefined:undefined:undefined":15,"s:163:4:163:Infinity":70,"s:163:29:163:Infinity":71,"s:164:20:164:Infinity":72,"s:165:21:165:Infinity":73,"b:165:37:165:45:165:45:165:Infinity":16,"s:166:4:166:Infinity":74,"s:169:23:175:Infinity":75,"f:170:17:170:22":19,"s:170:32:173:6":76,"b:171:28:171:35:171:35:171:Infinity":17,"b:172:28:172:60:172:60:172:Infinity":18,"f:173:8:173:16":20,"s:173:24:173:46":77,"b:176:2:179:Infinity:undefined:undefined:undefined:undefined":19,"s:176:2:179:Infinity":78,"s:177:22:177:Infinity":79,"s:178:4:178:Infinity":80,"s:181:2:187:Infinity":81,"b:182:4:182:Infinity:undefined:undefined:undefined:undefined":20,"s:182:4:182:Infinity":82,"s:182:23:182:Infinity":83,"s:183:17:183:Infinity":84,"b:184:4:184:Infinity:undefined:undefined:undefined:undefined":21,"s:184:4:184:Infinity":85,"s:184:29:184:Infinity":86,"s:185:20:185:Infinity":87,"s:186:4:186:Infinity":88,"s:189:8:190:Infinity":89,"f:189:8:189:28":21,"s:190:4:190:Infinity":90,"b:190:20:190:35:190:35:190:Infinity":22,"s:192:24:194:Infinity":91,"f:194:5:194:13":22,"s:194:22:194:62":92,"s:195:26:201:Infinity":93,"f:195:40:195:45":23,"s:196:4:200:Infinity":94,"s:197:6:197:Infinity":95,"s:199:6:199:Infinity":96,"s:202:28:204:Infinity":97,"b:203:6:203:Infinity:204:6:204:Infinity":23,"f:203:43:203:48":24,"s:203:54:203:65":98,"s:206:51:214:Infinity":99,"f:208:7:208:15":25,"s:208:24:208:82":100,"f:209:7:209:12":26,"s:209:22:212:8":101,"b:211:30:211:40:211:40:211:Infinity":24,"b:216:2:218:Infinity:undefined:undefined:undefined:undefined":25,"s:216:2:218:Infinity":102,"s:217:4:217:Infinity":103,"s:220:2:226:Infinity":104,"f:220:12:220:20":27,"s:220:29:220:42":105,"f:220:44:220:53":28,"s:221:17:221:Infinity":106,"b:222:4:222:Infinity:undefined:undefined:undefined:undefined":26,"s:222:4:222:Infinity":107,"s:222:51:222:Infinity":108,"s:223:20:223:Infinity":109,"s:224:21:224:Infinity":110,"b:224:37:224:45:224:45:224:Infinity":27,"s:225:4:225:Infinity":111,"s:228:19:228:35":112,"s:229:2:229:Infinity":113,"s:231:2:252:Infinity":114,"f:231:11:231:20":29,"s:232:28:236:Infinity":115,"f:232:51:232:57":30,"b:233:6:233:Infinity:undefined:undefined:undefined:undefined":28,"s:233:6:233:Infinity":116,"s:233:22:233:Infinity":117,"b:234:6:234:Infinity:undefined:undefined:undefined:undefined":29,"s:234:6:234:Infinity":118,"s:234:22:234:Infinity":119,"s:235:6:235:Infinity":120,"s:238:44:241:Infinity":121,"f:238:60:238:65":31,"s:238:78:241:6":122,"s:243:4:246:Infinity":123,"s:248:4:251:Infinity":124,"f:248:20:248:29":32,"s:249:18:249:Infinity":125,"s:250:6:250:Infinity":126,"s:254:18:254:29":127,"b:255:2:263:Infinity:undefined:undefined:undefined:undefined":30,"s:255:2:263:Infinity":128,"s:256:4:256:Infinity":129,"s:258:4:262:Infinity":130,"f:258:12:258:21":33,"s:259:18:259:Infinity":131,"s:260:23:260:Infinity":132,"b:260:51:260:59:260:59:260:Infinity":31,"s:261:6:261:Infinity":133,"s:265:19:265:31":134,"b:266:2:274:Infinity:undefined:undefined:undefined:undefined":32,"s:266:2:274:Infinity":135,"s:267:4:267:Infinity":136,"s:269:4:273:Infinity":137,"f:269:13:269:22":34,"s:270:18:270:Infinity":138,"s:271:23:271:Infinity":139,"b:271:87:271:95:271:95:271:Infinity":33,"b:271:23:271:52:271:52:271:87":34,"s:272:6:272:Infinity":140,"s:276:2:276:Infinity":141,"s:280:2:280:Infinity":142}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/docs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/docs.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":4},"end":{"line":63,"column":null}},"10":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"11":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"12":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":29},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":68,"column":25},"end":{"line":68,"column":53}},"19":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"20":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"getDocFiles","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":41}},"loc":{"start":{"line":39,"column":41},"end":{"line":73,"column":null}},"line":39},"1":{"name":"scanDir","decl":{"start":{"line":49,"column":11},"end":{"line":49,"column":19}},"loc":{"start":{"line":49,"column":38},"end":{"line":64,"column":null}},"line":49},"2":{"name":"(anonymous_2)","decl":{"start":{"line":68,"column":10},"end":{"line":68,"column":16}},"loc":{"start":{"line":68,"column":25},"end":{"line":68,"column":53}},"line":68}},"branchMap":{"0":{"loc":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":42},"1":{"loc":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},{"start":{"line":55,"column":13},"end":{"line":62,"column":null}}],"line":53},"2":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":91}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":33}},{"start":{"line":53,"column":33},"end":{"line":53,"column":60}},{"start":{"line":53,"column":60},"end":{"line":53,"column":91}}],"line":53},"3":{"loc":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":55,"column":17},"end":{"line":55,"column":65}},"type":"binary-expr","locations":[{"start":{"line":55,"column":17},"end":{"line":55,"column":35}},{"start":{"line":55,"column":35},"end":{"line":55,"column":65}}],"line":55}},"s":{"0":2,"1":2,"2":2,"3":17,"4":17,"5":0,"6":0,"7":17,"8":5967,"9":5967,"10":100266,"11":100266,"12":5950,"13":94316,"14":92548,"15":92548,"16":17,"17":17,"18":256887,"19":17,"20":17},"f":{"0":17,"1":5967,"2":256887},"b":{"0":[0,17],"1":[5950,94316],"2":[100266,5984,5950],"3":[92548,1768],"4":[94316,94282]},"meta":{"lastBranch":5,"lastFunction":3,"lastStatement":21,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"f:39:16:39:41":0,"s:40:2:40:Infinity":3,"b:42:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:42:2:45:Infinity":4,"s:43:4:43:Infinity":5,"s:44:4:44:Infinity":6,"s:47:29:47:Infinity":7,"f:49:11:49:19":1,"s:50:20:50:Infinity":8,"s:51:4:63:Infinity":9,"s:52:23:52:Infinity":10,"b:53:6:62:Infinity:55:13:62:Infinity":1,"s:53:6:62:Infinity":11,"b:53:10:53:33:53:33:53:60:53:60:53:91":2,"s:54:8:54:Infinity":12,"b:55:13:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:13:62:Infinity":13,"b:55:17:55:35:55:35:55:65":4,"s:56:29:56:Infinity":14,"s:57:8:61:Infinity":15,"s:66:2:66:Infinity":16,"s:68:2:68:Infinity":17,"f:68:10:68:16":2,"s:68:25:68:53":18,"s:70:2:70:Infinity":19,"s:72:2:72:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/api.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/api.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":47,"column":28},"end":{"line":47,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":4},"end":{"line":63,"column":null}},"10":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"11":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"12":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":29},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"getApiDocs","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":39}},"loc":{"start":{"line":39,"column":39},"end":{"line":71,"column":null}},"line":39},"1":{"name":"scanDir","decl":{"start":{"line":49,"column":11},"end":{"line":49,"column":19}},"loc":{"start":{"line":49,"column":38},"end":{"line":64,"column":null}},"line":49}},"branchMap":{"0":{"loc":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":42},"1":{"loc":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},{"start":{"line":55,"column":13},"end":{"line":62,"column":null}}],"line":53},"2":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":58}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":33}},{"start":{"line":53,"column":33},"end":{"line":53,"column":58}}],"line":53},"3":{"loc":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":55,"column":17},"end":{"line":55,"column":65}},"type":"binary-expr","locations":[{"start":{"line":55,"column":17},"end":{"line":55,"column":35}},{"start":{"line":55,"column":35},"end":{"line":55,"column":65}}],"line":55}},"s":{"0":3,"1":3,"2":3,"3":19,"4":19,"5":18,"6":18,"7":1,"8":2,"9":2,"10":4,"11":4,"12":1,"13":3,"14":2,"15":2,"16":1,"17":1,"18":1},"f":{"0":19,"1":2},"b":{"0":[18,1],"1":[1,3],"2":[4,2],"3":[2,1],"4":[3,2]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":19,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:16:27:Infinity":2,"f:39:16:39:39":0,"s:40:2:40:Infinity":3,"b:42:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:42:2:45:Infinity":4,"s:43:4:43:Infinity":5,"s:44:4:44:Infinity":6,"s:47:28:47:Infinity":7,"f:49:11:49:19":1,"s:50:20:50:Infinity":8,"s:51:4:63:Infinity":9,"s:52:23:52:Infinity":10,"b:53:6:62:Infinity:55:13:62:Infinity":1,"s:53:6:62:Infinity":11,"b:53:10:53:33:53:33:53:58":2,"s:54:8:54:Infinity":12,"b:55:13:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:13:62:Infinity":13,"b:55:17:55:35:55:35:55:65":4,"s:56:29:56:Infinity":14,"s:57:8:61:Infinity":15,"s:66:2:66:Infinity":16,"s:68:2:68:Infinity":17,"s:70:2:70:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/news.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/news.ts","statementMap":{"0":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":18},"end":{"line":28,"column":null}},"2":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"3":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},"5":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"7":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"8":{"start":{"line":54,"column":20},"end":{"line":54,"column":null}},"9":{"start":{"line":54,"column":80},"end":{"line":54,"column":108}},"10":{"start":{"line":55,"column":4},"end":{"line":86,"column":null}},"11":{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},"12":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"13":{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},"14":{"start":{"line":59,"column":21},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":22},"end":{"line":60,"column":null}},"16":{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},"17":{"start":{"line":62,"column":27},"end":{"line":62,"column":null}},"18":{"start":{"line":63,"column":23},"end":{"line":63,"column":null}},"19":{"start":{"line":64,"column":27},"end":{"line":64,"column":null}},"20":{"start":{"line":65,"column":30},"end":{"line":65,"column":null}},"21":{"start":{"line":67,"column":25},"end":{"line":67,"column":null}},"22":{"start":{"line":68,"column":31},"end":{"line":68,"column":null}},"23":{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},"24":{"start":{"line":71,"column":12},"end":{"line":75,"column":null}},"25":{"start":{"line":77,"column":28},"end":{"line":77,"column":null}},"26":{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},"27":{"start":{"line":79,"column":14},"end":{"line":79,"column":null}},"28":{"start":{"line":83,"column":10},"end":{"line":83,"column":null}},"29":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"30":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"31":{"start":{"line":93,"column":2},"end":{"line":103,"column":null}},"32":{"start":{"line":94,"column":20},"end":{"line":94,"column":null}},"33":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"34":{"start":{"line":95,"column":23},"end":{"line":95,"column":null}},"35":{"start":{"line":96,"column":17},"end":{"line":96,"column":null}},"36":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"37":{"start":{"line":98,"column":19},"end":{"line":98,"column":null}},"38":{"start":{"line":99,"column":19},"end":{"line":99,"column":null}},"39":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"40":{"start":{"line":101,"column":21},"end":{"line":101,"column":null}},"41":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}}},"fnMap":{"0":{"name":"getNewsArticles","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":50}},"loc":{"start":{"line":43,"column":50},"end":{"line":104,"column":null}},"line":43},"1":{"name":"scanDir","decl":{"start":{"line":53,"column":11},"end":{"line":53,"column":19}},"loc":{"start":{"line":53,"column":38},"end":{"line":87,"column":null}},"line":53},"2":{"name":"(anonymous_2)","decl":{"start":{"line":54,"column":65},"end":{"line":54,"column":71}},"loc":{"start":{"line":54,"column":80},"end":{"line":54,"column":108}},"line":54},"3":{"name":"(anonymous_3)","decl":{"start":{"line":93,"column":39},"end":{"line":93,"column":45}},"loc":{"start":{"line":93,"column":54},"end":{"line":103,"column":3}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":46},"1":{"loc":{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},{"start":{"line":58,"column":13},"end":{"line":85,"column":null}}],"line":56},"2":{"loc":{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":132}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":35}},{"start":{"line":58,"column":35},"end":{"line":58,"column":66}},{"start":{"line":58,"column":66},"end":{"line":58,"column":102}},{"start":{"line":58,"column":102},"end":{"line":58,"column":132}}],"line":58},"4":{"loc":{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":61},"5":{"loc":{"start":{"line":68,"column":31},"end":{"line":68,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":40},"end":{"line":68,"column":66}},{"start":{"line":68,"column":66},"end":{"line":68,"column":null}}],"line":68},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},{"start":{"line":76,"column":17},"end":{"line":81,"column":null}}],"line":70},"7":{"loc":{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"8":{"loc":{"start":{"line":78,"column":16},"end":{"line":78,"column":87}},"type":"binary-expr","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":36}},{"start":{"line":78,"column":36},"end":{"line":78,"column":87}}],"line":78},"9":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"10":{"loc":{"start":{"line":96,"column":17},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":96,"column":17},"end":{"line":96,"column":68}},{"start":{"line":96,"column":68},"end":{"line":96,"column":null}}],"line":96},"11":{"loc":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":17},"end":{"line":97,"column":68}},{"start":{"line":97,"column":68},"end":{"line":97,"column":null}}],"line":97},"12":{"loc":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"type":"binary-expr","locations":[{"start":{"line":100,"column":21},"end":{"line":100,"column":44}},{"start":{"line":100,"column":44},"end":{"line":100,"column":null}}],"line":100},"13":{"loc":{"start":{"line":101,"column":21},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":101,"column":21},"end":{"line":101,"column":44}},{"start":{"line":101,"column":44},"end":{"line":101,"column":null}}],"line":101}},"s":{"0":2,"1":2,"2":2,"3":17,"4":17,"5":0,"6":0,"7":17,"8":136,"9":106617,"10":136,"11":104519,"12":119,"13":104400,"14":103479,"15":103479,"16":103479,"17":103445,"18":103445,"19":103445,"20":103445,"21":103445,"22":103445,"23":103445,"24":8908,"25":94537,"26":94537,"27":0,"28":103445,"29":17,"30":17,"31":17,"32":33201,"33":33201,"34":0,"35":33201,"36":33201,"37":33201,"38":33201,"39":33201,"40":33201,"41":33201},"f":{"0":17,"1":136,"2":106617,"3":33201},"b":{"0":[0,17],"1":[119,104400],"2":[103479,921],"3":[104400,104400,104367,103938],"4":[103445,34],"5":[0,103445],"6":[8908,94537],"7":[0,94537],"8":[94537,94537],"9":[0,33201],"10":[33201,102],"11":[33201,119],"12":[33201,11815],"13":[33201,15504]},"meta":{"lastBranch":14,"lastFunction":4,"lastStatement":42,"seen":{"s:27:19:27:Infinity":0,"s:28:18:28:Infinity":1,"s:30:17:30:Infinity":2,"f:43:16:43:50":0,"s:44:2:44:Infinity":3,"b:46:2:49:Infinity:undefined:undefined:undefined:undefined":0,"s:46:2:49:Infinity":4,"s:47:4:47:Infinity":5,"s:48:4:48:Infinity":6,"s:51:19:51:Infinity":7,"f:53:11:53:19":1,"s:54:20:54:Infinity":8,"f:54:65:54:71":2,"s:54:80:54:108":9,"s:55:4:86:Infinity":10,"b:56:6:85:Infinity:58:13:85:Infinity":1,"s:56:6:85:Infinity":11,"s:57:8:57:Infinity":12,"b:58:13:85:Infinity:undefined:undefined:undefined:undefined":2,"s:58:13:85:Infinity":13,"b:58:17:58:35:58:35:58:66:58:66:58:102:58:102:58:132":3,"s:59:21:59:Infinity":14,"s:60:22:60:Infinity":15,"b:61:8:84:Infinity:undefined:undefined:undefined:undefined":4,"s:61:8:84:Infinity":16,"s:62:27:62:Infinity":17,"s:63:23:63:Infinity":18,"s:64:27:64:Infinity":19,"s:65:30:65:Infinity":20,"s:67:25:67:Infinity":21,"s:68:31:68:Infinity":22,"b:68:40:68:66:68:66:68:Infinity":5,"b:70:10:81:Infinity:76:17:81:Infinity":6,"s:70:10:81:Infinity":23,"s:71:12:75:Infinity":24,"s:77:28:77:Infinity":25,"b:78:12:80:Infinity:undefined:undefined:undefined:undefined":7,"s:78:12:80:Infinity":26,"b:78:16:78:36:78:36:78:87":8,"s:79:14:79:Infinity":27,"s:83:10:83:Infinity":28,"s:89:2:89:Infinity":29,"s:91:2:91:Infinity":30,"s:93:2:103:Infinity":31,"f:93:39:93:45":3,"s:94:20:94:Infinity":32,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":9,"s:95:4:95:Infinity":33,"s:95:23:95:Infinity":34,"s:96:17:96:Infinity":35,"b:96:17:96:68:96:68:96:Infinity":10,"s:97:17:97:Infinity":36,"b:97:17:97:68:97:68:97:Infinity":11,"s:98:19:98:Infinity":37,"s:99:19:99:Infinity":38,"s:100:21:100:Infinity":39,"b:100:21:100:44:100:44:100:Infinity":12,"s:101:21:101:Infinity":40,"b:101:21:101:44:101:44:101:Infinity":13,"s:102:4:102:Infinity":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/client.ts","statementMap":{"0":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"1":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":47,"column":19},"end":{"line":47,"column":null}},"5":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"6":{"start":{"line":49,"column":17},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"8":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"10":{"start":{"line":59,"column":19},"end":{"line":59,"column":null}},"11":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"12":{"start":{"line":64,"column":21},"end":{"line":64,"column":null}},"13":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"14":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"15":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"16":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"17":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"18":{"start":{"line":76,"column":23},"end":{"line":76,"column":null}},"19":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"20":{"start":{"line":77,"column":39},"end":{"line":77,"column":59}},"21":{"start":{"line":79,"column":4},"end":{"line":96,"column":null}},"22":{"start":{"line":80,"column":6},"end":{"line":86,"column":null}},"23":{"start":{"line":88,"column":21},"end":{"line":88,"column":null}},"24":{"start":{"line":89,"column":6},"end":{"line":93,"column":null}},"25":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"26":{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},"27":{"start":{"line":98,"column":6},"end":{"line":101,"column":null}},"28":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":40,"column":2},"end":{"line":40,"column":14}},"loc":{"start":{"line":40,"column":54},"end":{"line":44,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":46,"column":8},"end":{"line":46,"column":26}},"loc":{"start":{"line":46,"column":99},"end":{"line":51,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":53,"column":8},"end":{"line":53,"column":22}},"loc":{"start":{"line":53,"column":67},"end":{"line":56,"column":null}},"line":53},"3":{"name":"(anonymous_3)","decl":{"start":{"line":58,"column":8},"end":{"line":58,"column":20}},"loc":{"start":{"line":58,"column":66},"end":{"line":61,"column":null}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":63,"column":8},"end":{"line":63,"column":18}},"loc":{"start":{"line":63,"column":48},"end":{"line":66,"column":null}},"line":63},"5":{"name":"(anonymous_5)","decl":{"start":{"line":68,"column":8},"end":{"line":68,"column":25}},"loc":{"start":{"line":68,"column":60},"end":{"line":71,"column":null}},"line":68},"6":{"name":"(anonymous_6)","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":33}},"loc":{"start":{"line":73,"column":65},"end":{"line":104,"column":null}},"line":73},"7":{"name":"(anonymous_7)","decl":{"start":{"line":77,"column":22},"end":{"line":77,"column":39}},"loc":{"start":{"line":77,"column":39},"end":{"line":77,"column":59}},"line":77}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":14},"end":{"line":40,"column":54}},"type":"default-arg","locations":[{"start":{"line":40,"column":50},"end":{"line":40,"column":54}}],"line":40},"1":{"loc":{"start":{"line":41,"column":37},"end":{"line":41,"column":77}},"type":"binary-expr","locations":[{"start":{"line":41,"column":37},"end":{"line":41,"column":55}},{"start":{"line":41,"column":55},"end":{"line":41,"column":77}}],"line":41},"2":{"loc":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":19},"end":{"line":42,"column":37}},{"start":{"line":42,"column":37},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":19},"end":{"line":43,"column":37}},{"start":{"line":43,"column":37},"end":{"line":43,"column":null}}],"line":43},"4":{"loc":{"start":{"line":88,"column":21},"end":{"line":88,"column":null}},"type":"cond-expr","locations":[{"start":{"line":88,"column":46},"end":{"line":88,"column":62}},{"start":{"line":88,"column":62},"end":{"line":88,"column":null}}],"line":88},"5":{"loc":{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":97}},"s":{"0":4,"1":7,"2":7,"3":7,"4":3,"5":3,"6":3,"7":1,"8":0,"9":0,"10":0,"11":0,"12":7,"13":2,"14":0,"15":0,"16":7,"17":7,"18":7,"19":7,"20":0,"21":7,"22":7,"23":3,"24":3,"25":6,"26":3,"27":1,"28":2},"f":{"0":7,"1":3,"2":0,"3":0,"4":7,"5":0,"6":7,"7":0},"b":{"0":[7],"1":[7,6],"2":[7,7],"3":[7,1],"4":[3,0],"5":[1,2]},"meta":{"lastBranch":6,"lastFunction":8,"lastStatement":29,"seen":{"s:33:24:33:Infinity":0,"f:40:2:40:14":0,"b:40:50:40:54":0,"s:41:4:41:Infinity":1,"b:41:37:41:55:41:55:41:77":1,"s:42:4:42:Infinity":2,"b:42:19:42:37:42:37:42:Infinity":2,"s:43:4:43:Infinity":3,"b:43:19:43:37:43:37:43:Infinity":3,"f:46:8:46:26":1,"s:47:19:47:Infinity":4,"s:48:20:48:Infinity":5,"s:49:17:49:Infinity":6,"s:50:4:50:Infinity":7,"f:53:8:53:22":2,"s:54:19:54:Infinity":8,"s:55:4:55:Infinity":9,"f:58:8:58:20":3,"s:59:19:59:Infinity":10,"s:60:4:60:Infinity":11,"f:63:8:63:18":4,"s:64:21:64:Infinity":12,"s:65:4:65:Infinity":13,"f:68:8:68:25":5,"s:69:21:69:Infinity":14,"s:70:4:70:Infinity":15,"f:73:16:73:33":6,"s:74:21:74:Infinity":16,"s:75:4:75:Infinity":17,"s:76:23:76:Infinity":18,"s:77:22:77:Infinity":19,"f:77:22:77:39":7,"s:77:39:77:59":20,"s:79:4:96:Infinity":21,"s:80:6:86:Infinity":22,"s:88:21:88:Infinity":23,"b:88:46:88:62:88:62:88:Infinity":4,"s:89:6:93:Infinity":24,"s:95:6:95:Infinity":25,"b:97:4:102:Infinity:undefined:undefined:undefined:undefined":5,"s:97:4:102:Infinity":26,"s:98:6:101:Infinity":27,"s:103:4:103:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/static-pages-seo-head.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/static-pages-seo-head.ts","statementMap":{"0":{"start":{"line":63,"column":53},"end":{"line":67,"column":null}},"1":{"start":{"line":75,"column":54},"end":{"line":79,"column":null}},"2":{"start":{"line":81,"column":39},"end":{"line":84,"column":null}},"3":{"start":{"line":97,"column":89},"end":{"line":146,"column":null}},"4":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"5":{"start":{"line":172,"column":26},"end":{"line":172,"column":null}},"6":{"start":{"line":173,"column":2},"end":{"line":173,"column":null}},"7":{"start":{"line":174,"column":2},"end":{"line":177,"column":null}},"8":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"9":{"start":{"line":175,"column":24},"end":{"line":175,"column":null}},"10":{"start":{"line":176,"column":4},"end":{"line":176,"column":null}},"11":{"start":{"line":178,"column":2},"end":{"line":178,"column":null}},"12":{"start":{"line":195,"column":43},"end":{"line":195,"column":null}},"13":{"start":{"line":196,"column":23},"end":{"line":196,"column":null}},"14":{"start":{"line":197,"column":29},"end":{"line":197,"column":null}},"15":{"start":{"line":198,"column":23},"end":{"line":198,"column":null}},"16":{"start":{"line":199,"column":2},"end":{"line":208,"column":null}},"17":{"start":{"line":227,"column":61},"end":{"line":227,"column":null}},"18":{"start":{"line":228,"column":21},"end":{"line":228,"column":null}},"19":{"start":{"line":229,"column":19},"end":{"line":231,"column":null}},"20":{"start":{"line":232,"column":20},"end":{"line":232,"column":null}},"21":{"start":{"line":233,"column":20},"end":{"line":233,"column":null}},"22":{"start":{"line":245,"column":7},"end":{"line":250,"column":null}},"23":{"start":{"line":251,"column":17},"end":{"line":293,"column":null}},"24":{"start":{"line":294,"column":2},"end":{"line":294,"column":null}},"25":{"start":{"line":304,"column":100},"end":{"line":327,"column":null}},"26":{"start":{"line":328,"column":2},"end":{"line":328,"column":null}},"27":{"start":{"line":337,"column":93},"end":{"line":386,"column":null}},"28":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"29":{"start":{"line":396,"column":2},"end":{"line":401,"column":null}},"30":{"start":{"line":430,"column":33},"end":{"line":430,"column":null}},"31":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"32":{"start":{"line":433,"column":52},"end":{"line":433,"column":null}},"33":{"start":{"line":437,"column":21},"end":{"line":437,"column":null}},"34":{"start":{"line":438,"column":27},"end":{"line":438,"column":null}},"35":{"start":{"line":439,"column":25},"end":{"line":439,"column":null}},"36":{"start":{"line":440,"column":23},"end":{"line":440,"column":null}},"37":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"38":{"start":{"line":443,"column":8},"end":{"line":443,"column":null}},"39":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"40":{"start":{"line":445,"column":8},"end":{"line":445,"column":null}},"41":{"start":{"line":447,"column":13},"end":{"line":447,"column":null}},"42":{"start":{"line":450,"column":28},"end":{"line":450,"column":null}},"43":{"start":{"line":451,"column":22},"end":{"line":451,"column":null}},"44":{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},"45":{"start":{"line":453,"column":4},"end":{"line":453,"column":null}},"46":{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},"47":{"start":{"line":455,"column":4},"end":{"line":455,"column":null}},"48":{"start":{"line":462,"column":24},"end":{"line":462,"column":null}},"49":{"start":{"line":463,"column":2},"end":{"line":463,"column":null}},"50":{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},"51":{"start":{"line":466,"column":4},"end":{"line":466,"column":null}},"52":{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},"53":{"start":{"line":468,"column":4},"end":{"line":468,"column":null}},"54":{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},"55":{"start":{"line":473,"column":25},"end":{"line":478,"column":null}},"56":{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},"57":{"start":{"line":480,"column":6},"end":{"line":480,"column":null}},"58":{"start":{"line":505,"column":24},"end":{"line":505,"column":null}},"59":{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},"60":{"start":{"line":507,"column":25},"end":{"line":507,"column":null}},"61":{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},"62":{"start":{"line":512,"column":6},"end":{"line":515,"column":null}},"63":{"start":{"line":517,"column":24},"end":{"line":523,"column":null}},"64":{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},"65":{"start":{"line":525,"column":6},"end":{"line":525,"column":null}},"66":{"start":{"line":529,"column":2},"end":{"line":529,"column":null}}},"fnMap":{"0":{"name":"buildStaticPageKeywords","decl":{"start":{"line":157,"column":16},"end":{"line":157,"column":40}},"loc":{"start":{"line":157,"column":90},"end":{"line":159,"column":null}},"line":157},"1":{"name":"buildStaticPageOgLocaleBlock","decl":{"start":{"line":171,"column":16},"end":{"line":171,"column":45}},"loc":{"start":{"line":171,"column":69},"end":{"line":179,"column":null}},"line":171},"2":{"name":"buildStaticPageTwitterCardBlock","decl":{"start":{"line":189,"column":16},"end":{"line":189,"column":48}},"loc":{"start":{"line":194,"column":11},"end":{"line":209,"column":null}},"line":194},"3":{"name":"buildStaticPageJsonLd","decl":{"start":{"line":220,"column":16},"end":{"line":220,"column":38}},"loc":{"start":{"line":226,"column":11},"end":{"line":295,"column":null}},"line":226},"4":{"name":"breadcrumbLabel","decl":{"start":{"line":303,"column":9},"end":{"line":303,"column":25}},"loc":{"start":{"line":303,"column":75},"end":{"line":329,"column":null}},"line":303},"5":{"name":"pageAbout","decl":{"start":{"line":336,"column":9},"end":{"line":336,"column":19}},"loc":{"start":{"line":336,"column":69},"end":{"line":388,"column":null}},"line":336},"6":{"name":"escapeHtmlAttribute","decl":{"start":{"line":395,"column":9},"end":{"line":395,"column":29}},"loc":{"start":{"line":395,"column":51},"end":{"line":402,"column":null}},"line":395},"7":{"name":"enhanceStaticPageHead","decl":{"start":{"line":425,"column":16},"end":{"line":425,"column":38}},"loc":{"start":{"line":429,"column":11},"end":{"line":530,"column":null}},"line":429}},"branchMap":{"0":{"loc":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},{"start":{},"end":{}}],"line":175},"1":{"loc":{"start":{"line":229,"column":19},"end":{"line":231,"column":null}},"type":"cond-expr","locations":[{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},{"start":{"line":231,"column":6},"end":{"line":231,"column":null}}],"line":229},"2":{"loc":{"start":{"line":245,"column":7},"end":{"line":250,"column":null}},"type":"cond-expr","locations":[{"start":{"line":246,"column":6},"end":{"line":246,"column":null}},{"start":{"line":247,"column":6},"end":{"line":250,"column":null}}],"line":245},"3":{"loc":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"type":"if","locations":[{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},{"start":{},"end":{}}],"line":433},"4":{"loc":{"start":{"line":442,"column":17},"end":{"line":442,"column":38}},"type":"binary-expr","locations":[{"start":{"line":442,"column":17},"end":{"line":442,"column":36}},{"start":{"line":442,"column":36},"end":{"line":442,"column":38}}],"line":442},"5":{"loc":{"start":{"line":443,"column":23},"end":{"line":443,"column":50}},"type":"binary-expr","locations":[{"start":{"line":443,"column":23},"end":{"line":443,"column":48}},{"start":{"line":443,"column":48},"end":{"line":443,"column":50}}],"line":443},"6":{"loc":{"start":{"line":444,"column":24},"end":{"line":444,"column":49}},"type":"binary-expr","locations":[{"start":{"line":444,"column":24},"end":{"line":444,"column":47}},{"start":{"line":444,"column":47},"end":{"line":444,"column":49}}],"line":444},"7":{"loc":{"start":{"line":445,"column":20},"end":{"line":445,"column":91}},"type":"binary-expr","locations":[{"start":{"line":445,"column":20},"end":{"line":445,"column":41}},{"start":{"line":445,"column":41},"end":{"line":445,"column":91}}],"line":445},"8":{"loc":{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},"type":"if","locations":[{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},{"start":{"line":454,"column":9},"end":{"line":456,"column":null}}],"line":452},"9":{"loc":{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},"type":"if","locations":[{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},{"start":{},"end":{}}],"line":454},"10":{"loc":{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},{"start":{"line":467,"column":9},"end":{"line":469,"column":null}}],"line":465},"11":{"loc":{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},{"start":{},"end":{}}],"line":467},"12":{"loc":{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},"type":"if","locations":[{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},{"start":{},"end":{}}],"line":472},"13":{"loc":{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},{"start":{},"end":{}}],"line":479},"14":{"loc":{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},"type":"if","locations":[{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},{"start":{},"end":{}}],"line":506},"15":{"loc":{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},"type":"if","locations":[{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},{"start":{},"end":{}}],"line":508},"16":{"loc":{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},"type":"if","locations":[{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},{"start":{},"end":{}}],"line":524}},"s":{"0":1,"1":1,"2":1,"3":1,"4":203,"5":53,"6":53,"7":53,"8":742,"9":53,"10":689,"11":53,"12":46,"13":46,"14":46,"15":46,"16":46,"17":51,"18":51,"19":51,"20":51,"21":51,"22":51,"23":51,"24":51,"25":102,"26":102,"27":51,"28":51,"29":183,"30":45,"31":45,"32":0,"33":45,"34":45,"35":45,"36":45,"37":45,"38":45,"39":45,"40":45,"41":45,"42":45,"43":45,"44":45,"45":45,"46":0,"47":0,"48":45,"49":45,"50":45,"51":3,"52":42,"53":42,"54":45,"55":44,"56":44,"57":44,"58":45,"59":45,"60":44,"61":44,"62":0,"63":44,"64":44,"65":44,"66":45},"f":{"0":203,"1":53,"2":46,"3":51,"4":102,"5":51,"6":183,"7":45},"b":{"0":[53,689],"1":[4,47],"2":[16,35],"3":[0,45],"4":[45,0],"5":[45,0],"6":[45,0],"7":[45,0],"8":[45,0],"9":[0,0],"10":[3,42],"11":[42,0],"12":[44,1],"13":[44,0],"14":[44,1],"15":[0,44],"16":[44,0]},"meta":{"lastBranch":17,"lastFunction":8,"lastStatement":67,"seen":{"s:63:53:67:Infinity":0,"s:75:54:79:Infinity":1,"s:81:39:84:Infinity":2,"s:97:89:146:Infinity":3,"f:157:16:157:40":0,"s:158:2:158:Infinity":4,"f:171:16:171:45":1,"s:172:26:172:Infinity":5,"s:173:2:173:Infinity":6,"s:174:2:177:Infinity":7,"b:175:4:175:Infinity:undefined:undefined:undefined:undefined":0,"s:175:4:175:Infinity":8,"s:175:24:175:Infinity":9,"s:176:4:176:Infinity":10,"s:178:2:178:Infinity":11,"f:189:16:189:48":2,"s:195:43:195:Infinity":12,"s:196:23:196:Infinity":13,"s:197:29:197:Infinity":14,"s:198:23:198:Infinity":15,"s:199:2:208:Infinity":16,"f:220:16:220:38":3,"s:227:61:227:Infinity":17,"s:228:21:228:Infinity":18,"s:229:19:231:Infinity":19,"b:230:6:230:Infinity:231:6:231:Infinity":1,"s:232:20:232:Infinity":20,"s:233:20:233:Infinity":21,"s:245:7:250:Infinity":22,"b:246:6:246:Infinity:247:6:250:Infinity":2,"s:251:17:293:Infinity":23,"s:294:2:294:Infinity":24,"f:303:9:303:25":4,"s:304:100:327:Infinity":25,"s:328:2:328:Infinity":26,"f:336:9:336:19":5,"s:337:93:386:Infinity":27,"s:387:2:387:Infinity":28,"f:395:9:395:29":6,"s:396:2:401:Infinity":29,"f:425:16:425:38":7,"s:430:33:430:Infinity":30,"b:433:2:433:Infinity:undefined:undefined:undefined:undefined":3,"s:433:2:433:Infinity":31,"s:433:52:433:Infinity":32,"s:437:21:437:Infinity":33,"s:438:27:438:Infinity":34,"s:439:25:439:Infinity":35,"s:440:23:440:Infinity":36,"s:442:8:442:Infinity":37,"b:442:17:442:36:442:36:442:38":4,"s:443:8:443:Infinity":38,"b:443:23:443:48:443:48:443:50":5,"s:444:8:444:Infinity":39,"b:444:24:444:47:444:47:444:49":6,"s:445:8:445:Infinity":40,"b:445:20:445:41:445:41:445:91":7,"s:447:13:447:Infinity":41,"s:450:28:450:Infinity":42,"s:451:22:451:Infinity":43,"b:452:2:456:Infinity:454:9:456:Infinity":8,"s:452:2:456:Infinity":44,"s:453:4:453:Infinity":45,"b:454:9:456:Infinity:undefined:undefined:undefined:undefined":9,"s:454:9:456:Infinity":46,"s:455:4:455:Infinity":47,"s:462:24:462:Infinity":48,"s:463:2:463:Infinity":49,"b:465:2:469:Infinity:467:9:469:Infinity":10,"s:465:2:469:Infinity":50,"s:466:4:466:Infinity":51,"b:467:9:469:Infinity:undefined:undefined:undefined:undefined":11,"s:467:9:469:Infinity":52,"s:468:4:468:Infinity":53,"b:472:2:482:Infinity:undefined:undefined:undefined:undefined":12,"s:472:2:482:Infinity":54,"s:473:25:478:Infinity":55,"b:479:4:481:Infinity:undefined:undefined:undefined:undefined":13,"s:479:4:481:Infinity":56,"s:480:6:480:Infinity":57,"s:505:24:505:Infinity":58,"b:506:2:527:Infinity:undefined:undefined:undefined:undefined":14,"s:506:2:527:Infinity":59,"s:507:25:507:Infinity":60,"b:508:4:516:Infinity:undefined:undefined:undefined:undefined":15,"s:508:4:516:Infinity":61,"s:512:6:515:Infinity":62,"s:517:24:523:Infinity":63,"b:524:4:526:Infinity:undefined:undefined:undefined:undefined":16,"s:524:4:526:Infinity":64,"s:525:6:525:Infinity":65,"s:529:2:529:Infinity":66}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/validator.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":34,"column":8},"end":{"line":34,"column":null}},"6":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"7":{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"9":{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},"10":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"11":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"validateSitemap","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":32}},"loc":{"start":{"line":23,"column":54},"end":{"line":47,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":26},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"2":{"loc":{"start":{"line":34,"column":20},"end":{"line":34,"column":45}},"type":"binary-expr","locations":[{"start":{"line":34,"column":20},"end":{"line":34,"column":43}},{"start":{"line":34,"column":43},"end":{"line":34,"column":45}}],"line":34},"3":{"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"4":{"loc":{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":41}},"s":{"0":11,"1":11,"2":2,"3":9,"4":2,"5":7,"6":11,"7":11,"8":2,"9":5,"10":2,"11":3,"12":3},"f":{"0":11},"b":{"0":[2,9],"1":[2,7],"2":[7,2],"3":[2,9],"4":[2,3]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":13,"seen":{"f:23:16:23:32":0,"s:24:2:24:Infinity":0,"b:26:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:26:2:28:Infinity":1,"s:27:4:27:Infinity":2,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":1,"s:30:2:32:Infinity":3,"s:31:4:31:Infinity":4,"s:34:8:34:Infinity":5,"b:34:20:34:43:34:43:34:45":2,"s:35:2:35:Infinity":6,"b:37:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:37:2:39:Infinity":7,"s:38:4:38:Infinity":8,"b:41:2:43:Infinity:undefined:undefined:undefined:undefined":4,"s:41:2:43:Infinity":9,"s:42:4:42:Infinity":10,"s:45:2:45:Infinity":11,"s:46:2:46:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/budget.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/budget.ts","statementMap":{"0":{"start":{"line":39,"column":41},"end":{"line":39,"column":null}},"1":{"start":{"line":40,"column":2},"end":{"line":117,"column":null}},"2":{"start":{"line":41,"column":19},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"7":{"start":{"line":46,"column":21},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"9":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"10":{"start":{"line":55,"column":6},"end":{"line":65,"column":null}},"11":{"start":{"line":67,"column":17},"end":{"line":78,"column":null}},"12":{"start":{"line":80,"column":23},"end":{"line":88,"column":null}},"13":{"start":{"line":89,"column":20},"end":{"line":89,"column":null}},"14":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"15":{"start":{"line":90,"column":31},"end":{"line":90,"column":null}},"16":{"start":{"line":92,"column":22},"end":{"line":100,"column":null}},"17":{"start":{"line":101,"column":19},"end":{"line":101,"column":null}},"18":{"start":{"line":103,"column":19},"end":{"line":103,"column":null}},"19":{"start":{"line":104,"column":19},"end":{"line":104,"column":null}},"20":{"start":{"line":106,"column":4},"end":{"line":116,"column":null}},"21":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"22":{"start":{"line":132,"column":41},"end":{"line":132,"column":null}},"23":{"start":{"line":133,"column":2},"end":{"line":140,"column":null}},"24":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"25":{"start":{"line":135,"column":53},"end":{"line":138,"column":null}},"26":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"27":{"start":{"line":141,"column":2},"end":{"line":146,"column":null}},"28":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"29":{"start":{"line":160,"column":17},"end":{"line":170,"column":null}},"30":{"start":{"line":172,"column":2},"end":{"line":193,"column":null}},"31":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"32":{"start":{"line":174,"column":21},"end":{"line":174,"column":null}},"33":{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},"34":{"start":{"line":176,"column":6},"end":{"line":176,"column":null}},"35":{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},"36":{"start":{"line":178,"column":8},"end":{"line":178,"column":null}},"37":{"start":{"line":180,"column":8},"end":{"line":180,"column":null}},"38":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"39":{"start":{"line":184,"column":6},"end":{"line":191,"column":null}},"40":{"start":{"line":195,"column":2},"end":{"line":208,"column":null}},"41":{"start":{"line":196,"column":45},"end":{"line":207,"column":6}},"42":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"43":{"start":{"line":213,"column":12},"end":{"line":213,"column":null}},"44":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"45":{"start":{"line":214,"column":29},"end":{"line":214,"column":null}},"46":{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},"47":{"start":{"line":215,"column":52},"end":{"line":215,"column":null}},"48":{"start":{"line":216,"column":2},"end":{"line":216,"column":null}}},"fnMap":{"0":{"name":"parseBudgetRows","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"loc":{"start":{"line":38,"column":28},"end":{"line":119,"column":null}},"line":38},"1":{"name":"buildBudgetTimeSeries","decl":{"start":{"line":128,"column":16},"end":{"line":128,"column":null}},"loc":{"start":{"line":131,"column":28},"end":{"line":147,"column":null}},"line":131},"2":{"name":"(anonymous_2)","decl":{"start":{"line":141,"column":14},"end":{"line":141,"column":null}},"loc":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"line":143},"3":{"name":"summarizeBudgetOutturn","decl":{"start":{"line":157,"column":16},"end":{"line":157,"column":null}},"loc":{"start":{"line":159,"column":32},"end":{"line":209,"column":null}},"line":159},"4":{"name":"(anonymous_4)","decl":{"start":{"line":196,"column":5},"end":{"line":196,"column":10}},"loc":{"start":{"line":196,"column":45},"end":{"line":207,"column":6}},"line":196},"5":{"name":"(anonymous_5)","decl":{"start":{"line":208,"column":5},"end":{"line":208,"column":11}},"loc":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"line":208},"6":{"name":"inferDocTypeFromSheetName","decl":{"start":{"line":212,"column":9},"end":{"line":212,"column":35}},"loc":{"start":{"line":212,"column":69},"end":{"line":217,"column":null}},"line":212}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"default-arg","locations":[{"start":{"line":37,"column":40},"end":{"line":37,"column":null}}],"line":37},"1":{"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":17},"end":{"line":43,"column":65}},{"start":{"line":43,"column":65},"end":{"line":43,"column":null}}],"line":43},"2":{"loc":{"start":{"line":43,"column":47},"end":{"line":43,"column":60}},"type":"binary-expr","locations":[{"start":{"line":43,"column":47},"end":{"line":43,"column":58}},{"start":{"line":43,"column":58},"end":{"line":43,"column":60}}],"line":43},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":18},"end":{"line":47,"column":67}},{"start":{"line":47,"column":67},"end":{"line":47,"column":null}}],"line":47},"5":{"loc":{"start":{"line":47,"column":48},"end":{"line":47,"column":62}},"type":"binary-expr","locations":[{"start":{"line":47,"column":48},"end":{"line":47,"column":60}},{"start":{"line":47,"column":60},"end":{"line":47,"column":62}}],"line":47},"6":{"loc":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}}],"line":50},"7":{"loc":{"start":{"line":55,"column":6},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":65,"column":20}},{"start":{"line":65,"column":20},"end":{"line":65,"column":null}}],"line":55},"8":{"loc":{"start":{"line":89,"column":52},"end":{"line":89,"column":68}},"type":"binary-expr","locations":[{"start":{"line":89,"column":52},"end":{"line":89,"column":66}},{"start":{"line":89,"column":66},"end":{"line":89,"column":68}}],"line":89},"9":{"loc":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":90},"10":{"loc":{"start":{"line":101,"column":51},"end":{"line":101,"column":66}},"type":"binary-expr","locations":[{"start":{"line":101,"column":51},"end":{"line":101,"column":64}},{"start":{"line":101,"column":64},"end":{"line":101,"column":66}}],"line":101},"11":{"loc":{"start":{"line":108,"column":10},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":32},"end":{"line":108,"column":44}},{"start":{"line":108,"column":44},"end":{"line":108,"column":null}}],"line":108},"12":{"loc":{"start":{"line":111,"column":10},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":17},"end":{"line":111,"column":28}},{"start":{"line":111,"column":28},"end":{"line":111,"column":null}}],"line":111},"13":{"loc":{"start":{"line":113,"column":10},"end":{"line":113,"column":null}},"type":"cond-expr","locations":[{"start":{"line":113,"column":33},"end":{"line":113,"column":71}},{"start":{"line":113,"column":71},"end":{"line":113,"column":null}}],"line":113},"14":{"loc":{"start":{"line":114,"column":10},"end":{"line":114,"column":null}},"type":"cond-expr","locations":[{"start":{"line":114,"column":19},"end":{"line":114,"column":32}},{"start":{"line":114,"column":32},"end":{"line":114,"column":null}}],"line":114},"15":{"loc":{"start":{"line":115,"column":10},"end":{"line":115,"column":null}},"type":"cond-expr","locations":[{"start":{"line":115,"column":19},"end":{"line":115,"column":32}},{"start":{"line":115,"column":32},"end":{"line":115,"column":null}}],"line":115},"16":{"loc":{"start":{"line":130,"column":2},"end":{"line":130,"column":null}},"type":"default-arg","locations":[{"start":{"line":130,"column":40},"end":{"line":130,"column":null}}],"line":130},"17":{"loc":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"type":"binary-expr","locations":[{"start":{"line":134,"column":25},"end":{"line":134,"column":49}},{"start":{"line":134,"column":49},"end":{"line":134,"column":null}}],"line":134},"18":{"loc":{"start":{"line":137,"column":10},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":137,"column":25},"end":{"line":137,"column":58}},{"start":{"line":137,"column":58},"end":{"line":137,"column":null}}],"line":137},"19":{"loc":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"type":"binary-expr","locations":[{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},{"start":{"line":143,"column":17},"end":{"line":144,"column":null}},{"start":{"line":145,"column":6},"end":{"line":145,"column":null}}],"line":143},"20":{"loc":{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},{"start":{"line":183,"column":11},"end":{"line":192,"column":null}}],"line":175},"21":{"loc":{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},{"start":{"line":179,"column":13},"end":{"line":181,"column":null}}],"line":177},"22":{"loc":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":21},"end":{"line":188,"column":35}},{"start":{"line":188,"column":35},"end":{"line":188,"column":null}}],"line":188},"23":{"loc":{"start":{"line":200,"column":10},"end":{"line":205,"column":null}},"type":"cond-expr","locations":[{"start":{"line":201,"column":10},"end":{"line":204,"column":null}},{"start":{"line":205,"column":10},"end":{"line":205,"column":null}}],"line":200},"24":{"loc":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"type":"binary-expr","locations":[{"start":{"line":208,"column":20},"end":{"line":208,"column":39}},{"start":{"line":208,"column":39},"end":{"line":208,"column":89}}],"line":208},"25":{"loc":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"26":{"loc":{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},"type":"if","locations":[{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},{"start":{},"end":{}}],"line":215},"27":{"loc":{"start":{"line":215,"column":6},"end":{"line":215,"column":52}},"type":"binary-expr","locations":[{"start":{"line":215,"column":6},"end":{"line":215,"column":30}},{"start":{"line":215,"column":30},"end":{"line":215,"column":52}}],"line":215}},"s":{"0":15,"1":15,"2":24,"3":24,"4":24,"5":24,"6":1,"7":23,"8":23,"9":24,"10":24,"11":24,"12":24,"13":24,"14":24,"15":1,"16":22,"17":22,"18":24,"19":24,"20":24,"21":15,"22":1,"23":1,"24":2,"25":2,"26":2,"27":1,"28":1,"29":4,"30":4,"31":8,"32":8,"33":8,"34":2,"35":2,"36":1,"37":1,"38":2,"39":6,"40":4,"41":6,"42":4,"43":2,"44":2,"45":1,"46":1,"47":1,"48":0},"f":{"0":15,"1":1,"2":1,"3":4,"4":6,"5":4,"6":2},"b":{"0":[15],"1":[24,4],"2":[24,4],"3":[1,23],"4":[23,20],"5":[23,20],"6":[24,16,4],"7":[24,0],"8":[24,0],"9":[1,23],"10":[22,15],"11":[4,18],"12":[18,4],"13":[7,15],"14":[22,0],"15":[0,22],"16":[1],"17":[2,2],"18":[2,0],"19":[1,1,1],"20":[2,6],"21":[1,1],"22":[6,3],"23":[2,4],"24":[4,2],"25":[1,1],"26":[1,0],"27":[1,0]},"meta":{"lastBranch":28,"lastFunction":7,"lastStatement":49,"seen":{"f:35:16:35:Infinity":0,"b:37:40:37:Infinity":0,"s:39:41:39:Infinity":0,"s:40:2:117:Infinity":1,"s:41:19:41:Infinity":2,"s:42:20:42:Infinity":3,"s:43:17:43:Infinity":4,"b:43:17:43:65:43:65:43:Infinity":1,"b:43:47:43:58:43:58:43:60":2,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:44:Infinity":5,"s:44:15:44:Infinity":6,"s:46:21:46:Infinity":7,"s:47:18:47:Infinity":8,"b:47:18:47:67:47:67:47:Infinity":4,"b:47:48:47:60:47:60:47:62":5,"s:50:6:52:Infinity":9,"b:50:6:50:Infinity:51:6:51:Infinity:52:6:52:Infinity":6,"s:55:6:65:Infinity":10,"b:55:6:65:20:65:20:65:Infinity":7,"s:67:17:78:Infinity":11,"s:80:23:88:Infinity":12,"s:89:20:89:Infinity":13,"b:89:52:89:66:89:66:89:68":8,"b:90:4:90:Infinity:undefined:undefined:undefined:undefined":9,"s:90:4:90:Infinity":14,"s:90:31:90:Infinity":15,"s:92:22:100:Infinity":16,"s:101:19:101:Infinity":17,"b:101:51:101:64:101:64:101:66":10,"s:103:19:103:Infinity":18,"s:104:19:104:Infinity":19,"s:106:4:116:Infinity":20,"b:108:32:108:44:108:44:108:Infinity":11,"b:111:17:111:28:111:28:111:Infinity":12,"b:113:33:113:71:113:71:113:Infinity":13,"b:114:19:114:32:114:32:114:Infinity":14,"b:115:19:115:32:115:32:115:Infinity":15,"s:118:2:118:Infinity":21,"f:128:16:128:Infinity":1,"b:130:40:130:Infinity":16,"s:132:41:132:Infinity":22,"s:133:2:140:Infinity":23,"s:134:25:134:Infinity":24,"b:134:25:134:49:134:49:134:Infinity":17,"s:135:53:138:Infinity":25,"b:137:25:137:58:137:58:137:Infinity":18,"s:139:4:139:Infinity":26,"s:141:2:146:Infinity":27,"f:141:14:141:Infinity":2,"s:143:6:145:Infinity":28,"b:143:6:143:Infinity:143:17:144:Infinity:145:6:145:Infinity":19,"f:157:16:157:Infinity":3,"s:160:17:170:Infinity":29,"s:172:2:193:Infinity":30,"s:173:16:173:Infinity":31,"s:174:21:174:Infinity":32,"b:175:4:192:Infinity:183:11:192:Infinity":20,"s:175:4:192:Infinity":33,"s:176:6:176:Infinity":34,"b:177:6:181:Infinity:179:13:181:Infinity":21,"s:177:6:181:Infinity":35,"s:178:8:178:Infinity":36,"s:180:8:180:Infinity":37,"s:182:6:182:Infinity":38,"s:184:6:191:Infinity":39,"b:188:21:188:35:188:35:188:Infinity":22,"s:195:2:208:Infinity":40,"f:196:5:196:10":4,"s:196:45:207:6":41,"b:201:10:204:Infinity:205:10:205:Infinity":23,"f:208:5:208:11":5,"s:208:20:208:89":42,"b:208:20:208:39:208:39:208:89":24,"f:212:9:212:35":6,"s:213:12:213:Infinity":43,"b:214:2:214:Infinity:undefined:undefined:undefined:undefined":25,"s:214:2:214:Infinity":44,"s:214:29:214:Infinity":45,"b:215:2:215:Infinity:undefined:undefined:undefined:undefined":26,"s:215:2:215:Infinity":46,"b:215:6:215:30:215:30:215:52":27,"s:215:52:215:Infinity":47,"s:216:2:216:Infinity":48}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/errors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/errors.ts","statementMap":{"0":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":4},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":4},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"loc":{"start":{"line":22,"column":4},"end":{"line":26,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"type":"default-arg","locations":[{"start":{"line":20,"column":39},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":14,"1":14,"2":14},"f":{"0":14},"b":{"0":[14]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:18:2:18:Infinity":0,"b:20:39:20:Infinity":0,"s:23:4:23:Infinity":0,"s:24:4:24:Infinity":1,"s:25:4:25:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/headcount.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/headcount.ts","statementMap":{"0":{"start":{"line":31,"column":20},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":2},"end":{"line":51,"column":null}},"2":{"start":{"line":33,"column":19},"end":{"line":33,"column":null}},"3":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"4":{"start":{"line":36,"column":23},"end":{"line":40,"column":null}},"5":{"start":{"line":41,"column":27},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":44,"column":62},"end":{"line":44,"column":null}},"8":{"start":{"line":45,"column":22},"end":{"line":45,"column":null}},"9":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"10":{"start":{"line":47,"column":20},"end":{"line":47,"column":null}},"11":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"12":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"13":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"14":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"15":{"start":{"line":53,"column":2},"end":{"line":63,"column":null}},"16":{"start":{"line":55,"column":36},"end":{"line":55,"column":null}},"17":{"start":{"line":56,"column":6},"end":{"line":61,"column":null}},"18":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"19":{"start":{"line":70,"column":16},"end":{"line":73,"column":null}},"20":{"start":{"line":71,"column":42},"end":{"line":71,"column":88}},"21":{"start":{"line":72,"column":42},"end":{"line":72,"column":89}},"22":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"23":{"start":{"line":74,"column":14},"end":{"line":74,"column":null}},"24":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}}},"fnMap":{"0":{"name":"aggregateHeadcountByDepartment","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"loc":{"start":{"line":30,"column":31},"end":{"line":64,"column":null}},"line":30},"1":{"name":"(anonymous_1)","decl":{"start":{"line":54,"column":5},"end":{"line":54,"column":10}},"loc":{"start":{"line":54,"column":27},"end":{"line":62,"column":5}},"line":54},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":11}},"loc":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"line":63},"3":{"name":"buildHeadcountTimeSeries","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"loc":{"start":{"line":69,"column":31},"end":{"line":76,"column":null}},"line":69},"4":{"name":"(anonymous_4)","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":28}},"loc":{"start":{"line":71,"column":42},"end":{"line":71,"column":88}},"line":71},"5":{"name":"(anonymous_5)","decl":{"start":{"line":72,"column":22},"end":{"line":72,"column":28}},"loc":{"start":{"line":72,"column":42},"end":{"line":72,"column":89}},"line":72}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":6},"end":{"line":35,"column":86}},{"start":{"line":35,"column":86},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":35,"column":36},"end":{"line":35,"column":81}},"type":"binary-expr","locations":[{"start":{"line":35,"column":36},"end":{"line":35,"column":79}},{"start":{"line":35,"column":79},"end":{"line":35,"column":81}}],"line":35},"2":{"loc":{"start":{"line":42,"column":6},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":6},"end":{"line":42,"column":81}},{"start":{"line":42,"column":81},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":44,"column":8},"end":{"line":44,"column":62}},"type":"binary-expr","locations":[{"start":{"line":44,"column":8},"end":{"line":44,"column":17}},{"start":{"line":44,"column":17},"end":{"line":44,"column":32}},{"start":{"line":44,"column":32},"end":{"line":44,"column":62}}],"line":44},"5":{"loc":{"start":{"line":45,"column":22},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":22},"end":{"line":45,"column":92}},{"start":{"line":45,"column":92},"end":{"line":45,"column":null}}],"line":45},"6":{"loc":{"start":{"line":47,"column":20},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":20},"end":{"line":47,"column":42}},{"start":{"line":47,"column":42},"end":{"line":47,"column":null}}],"line":47},"7":{"loc":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"8":{"loc":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"type":"binary-expr","locations":[{"start":{"line":63,"column":20},"end":{"line":63,"column":39}},{"start":{"line":63,"column":39},"end":{"line":63,"column":85}}],"line":63},"9":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"default-arg","locations":[{"start":{"line":68,"column":43},"end":{"line":68,"column":null}}],"line":68},"10":{"loc":{"start":{"line":70,"column":16},"end":{"line":73,"column":null}},"type":"cond-expr","locations":[{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},{"start":{"line":72,"column":6},"end":{"line":73,"column":null}}],"line":70},"11":{"loc":{"start":{"line":72,"column":6},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},{"start":{"line":73,"column":6},"end":{"line":73,"column":null}}],"line":72},"12":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74}},"s":{"0":3,"1":3,"2":10,"3":10,"4":10,"5":10,"6":10,"7":0,"8":10,"9":10,"10":10,"11":10,"12":10,"13":10,"14":10,"15":3,"16":7,"17":7,"18":6,"19":4,"20":2,"21":1,"22":4,"23":2,"24":2},"f":{"0":3,"1":7,"2":6,"3":4,"4":2,"5":1},"b":{"0":[10,0],"1":[10,0],"2":[10,0],"3":[0,10],"4":[10,10,10],"5":[10,0],"6":[10,7],"7":[10,0],"8":[6,2],"9":[4],"10":[2,2],"11":[2,1],"12":[2,2]},"meta":{"lastBranch":13,"lastFunction":6,"lastStatement":25,"seen":{"f:27:16:27:Infinity":0,"s:31:20:31:Infinity":0,"s:32:2:51:Infinity":1,"s:33:19:33:Infinity":2,"s:35:6:35:Infinity":3,"b:35:6:35:86:35:86:35:Infinity":0,"b:35:36:35:79:35:79:35:81":1,"s:36:23:40:Infinity":4,"s:41:27:43:Infinity":5,"b:42:6:42:81:42:81:42:Infinity":2,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:44:Infinity":6,"b:44:8:44:17:44:17:44:32:44:32:44:62":4,"s:44:62:44:Infinity":7,"s:45:22:45:Infinity":8,"b:45:22:45:92:45:92:45:Infinity":5,"s:46:16:46:Infinity":9,"s:47:20:47:Infinity":10,"b:47:20:47:42:47:42:47:Infinity":6,"s:48:4:48:Infinity":11,"b:49:4:49:Infinity:undefined:undefined:undefined:undefined":7,"s:49:4:49:Infinity":12,"s:49:19:49:Infinity":13,"s:50:4:50:Infinity":14,"s:53:2:63:Infinity":15,"f:54:5:54:10":1,"s:55:36:55:Infinity":16,"s:56:6:61:Infinity":17,"f:63:5:63:11":2,"s:63:20:63:85":18,"b:63:20:63:39:63:39:63:85":8,"f:66:16:66:Infinity":3,"b:68:43:68:Infinity":9,"s:70:16:73:Infinity":19,"b:71:6:71:Infinity:72:6:73:Infinity":10,"f:71:22:71:28":4,"s:71:42:71:88":20,"b:72:6:72:Infinity:73:6:73:Infinity":11,"f:72:22:72:28":5,"s:72:42:72:89":21,"b:74:2:74:Infinity:undefined:undefined:undefined:undefined":12,"s:74:2:74:Infinity":22,"s:74:14:74:Infinity":23,"s:75:2:75:Infinity":24}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/download-links.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/download-links.ts","statementMap":{"0":{"start":{"line":27,"column":33},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":22},"end":{"line":29,"column":null}},"3":{"start":{"line":37,"column":45},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":24},"end":{"line":38,"column":null}},"5":{"start":{"line":39,"column":2},"end":{"line":72,"column":null}},"6":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":17},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"9":{"start":{"line":42,"column":15},"end":{"line":42,"column":null}},"10":{"start":{"line":43,"column":25},"end":{"line":43,"column":null}},"11":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"12":{"start":{"line":44,"column":36},"end":{"line":44,"column":null}},"13":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"14":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"15":{"start":{"line":47,"column":17},"end":{"line":47,"column":null}},"16":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"17":{"start":{"line":49,"column":4},"end":{"line":71,"column":null}},"18":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"19":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"20":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"21":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"22":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"23":{"start":{"line":88,"column":66},"end":{"line":88,"column":null}},"24":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"25":{"start":{"line":89,"column":37},"end":{"line":89,"column":null}},"26":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"27":{"start":{"line":90,"column":63},"end":{"line":90,"column":null}},"28":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"29":{"start":{"line":91,"column":44},"end":{"line":91,"column":null}},"30":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"31":{"start":{"line":92,"column":64},"end":{"line":92,"column":null}},"32":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"33":{"start":{"line":99,"column":15},"end":{"line":99,"column":null}},"34":{"start":{"line":100,"column":43},"end":{"line":100,"column":null}},"35":{"start":{"line":101,"column":2},"end":{"line":105,"column":null}},"36":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"37":{"start":{"line":102,"column":28},"end":{"line":102,"column":null}},"38":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"39":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"40":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"41":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"42":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}}},"fnMap":{"0":{"name":"extractStatskontoretDownloadLinks","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"loc":{"start":{"line":36,"column":31},"end":{"line":74,"column":null}},"line":36},"1":{"name":"classifyStatskontoretResource","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":null}},"loc":{"start":{"line":79,"column":29},"end":{"line":94,"column":null}},"line":79},"2":{"name":"deduplicateLinks","decl":{"start":{"line":96,"column":9},"end":{"line":96,"column":null}},"loc":{"start":{"line":98,"column":31},"end":{"line":107,"column":null}},"line":98},"3":{"name":"extractPageLastModified","decl":{"start":{"line":109,"column":9},"end":{"line":109,"column":33}},"loc":{"start":{"line":109,"column":67},"end":{"line":112,"column":null}},"line":109}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"type":"default-arg","locations":[{"start":{"line":35,"column":20},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":40,"column":28},"end":{"line":40,"column":42}},"type":"binary-expr","locations":[{"start":{"line":40,"column":28},"end":{"line":40,"column":40}},{"start":{"line":40,"column":40},"end":{"line":40,"column":42}}],"line":40},"2":{"loc":{"start":{"line":41,"column":49},"end":{"line":41,"column":63}},"type":"binary-expr","locations":[{"start":{"line":41,"column":49},"end":{"line":41,"column":61}},{"start":{"line":41,"column":61},"end":{"line":41,"column":63}}],"line":41},"3":{"loc":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":42},"4":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"5":{"loc":{"start":{"line":56,"column":10},"end":{"line":58,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":null}},{"start":{"line":58,"column":10},"end":{"line":58,"column":null}}],"line":56},"6":{"loc":{"start":{"line":57,"column":26},"end":{"line":57,"column":79}},"type":"binary-expr","locations":[{"start":{"line":57,"column":26},"end":{"line":57,"column":69}},{"start":{"line":57,"column":69},"end":{"line":57,"column":79}}],"line":57},"7":{"loc":{"start":{"line":59,"column":10},"end":{"line":61,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},{"start":{"line":61,"column":10},"end":{"line":61,"column":null}}],"line":59},"8":{"loc":{"start":{"line":60,"column":22},"end":{"line":60,"column":71}},"type":"binary-expr","locations":[{"start":{"line":60,"column":22},"end":{"line":60,"column":61}},{"start":{"line":60,"column":61},"end":{"line":60,"column":71}}],"line":60},"9":{"loc":{"start":{"line":62,"column":10},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},{"start":{"line":64,"column":10},"end":{"line":64,"column":null}}],"line":62},"10":{"loc":{"start":{"line":63,"column":22},"end":{"line":63,"column":71}},"type":"binary-expr","locations":[{"start":{"line":63,"column":22},"end":{"line":63,"column":61}},{"start":{"line":63,"column":61},"end":{"line":63,"column":71}}],"line":63},"11":{"loc":{"start":{"line":65,"column":10},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":31},"end":{"line":65,"column":42}},{"start":{"line":65,"column":42},"end":{"line":65,"column":null}}],"line":65},"12":{"loc":{"start":{"line":66,"column":10},"end":{"line":66,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":44}},{"start":{"line":66,"column":44},"end":{"line":66,"column":null}}],"line":66},"13":{"loc":{"start":{"line":67,"column":10},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},{"start":{"line":69,"column":10},"end":{"line":69,"column":null}}],"line":67},"14":{"loc":{"start":{"line":68,"column":20},"end":{"line":68,"column":67}},"type":"binary-expr","locations":[{"start":{"line":68,"column":20},"end":{"line":68,"column":57}},{"start":{"line":68,"column":57},"end":{"line":68,"column":67}}],"line":68},"15":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":26},"end":{"line":70,"column":57}},{"start":{"line":70,"column":57},"end":{"line":70,"column":null}}],"line":70},"16":{"loc":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":81},"17":{"loc":{"start":{"line":82,"column":4},"end":{"line":84,"column":null}},"type":"binary-expr","locations":[{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},{"start":{"line":84,"column":4},"end":{"line":84,"column":null}}],"line":82},"18":{"loc":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":88},"19":{"loc":{"start":{"line":88,"column":6},"end":{"line":88,"column":66}},"type":"binary-expr","locations":[{"start":{"line":88,"column":6},"end":{"line":88,"column":43}},{"start":{"line":88,"column":43},"end":{"line":88,"column":66}}],"line":88},"20":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"21":{"loc":{"start":{"line":89,"column":44},"end":{"line":89,"column":null}},"type":"cond-expr","locations":[{"start":{"line":89,"column":68},"end":{"line":89,"column":80}},{"start":{"line":89,"column":80},"end":{"line":89,"column":null}}],"line":89},"22":{"loc":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":90},"23":{"loc":{"start":{"line":90,"column":6},"end":{"line":90,"column":63}},"type":"binary-expr","locations":[{"start":{"line":90,"column":6},"end":{"line":90,"column":37}},{"start":{"line":90,"column":37},"end":{"line":90,"column":63}}],"line":90},"24":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"25":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92},"26":{"loc":{"start":{"line":92,"column":6},"end":{"line":92,"column":64}},"type":"binary-expr","locations":[{"start":{"line":92,"column":6},"end":{"line":92,"column":38}},{"start":{"line":92,"column":38},"end":{"line":92,"column":64}}],"line":92},"27":{"loc":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":102},"28":{"loc":{"start":{"line":111,"column":9},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":17},"end":{"line":111,"column":46}},{"start":{"line":111,"column":46},"end":{"line":111,"column":null}}],"line":111},"29":{"loc":{"start":{"line":111,"column":28},"end":{"line":111,"column":42}},"type":"binary-expr","locations":[{"start":{"line":111,"column":28},"end":{"line":111,"column":40}},{"start":{"line":111,"column":40},"end":{"line":111,"column":42}}],"line":111}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":7,"7":7,"8":7,"9":0,"10":7,"11":7,"12":0,"13":7,"14":7,"15":7,"16":7,"17":7,"18":4,"19":11,"20":11,"21":7,"22":4,"23":2,"24":2,"25":2,"26":2,"27":0,"28":2,"29":2,"30":1,"31":0,"32":1,"33":4,"34":4,"35":4,"36":7,"37":1,"38":6,"39":6,"40":4,"41":4,"42":4},"f":{"0":4,"1":11,"2":4,"3":4},"b":{"0":[4],"1":[7,0],"2":[7,0],"3":[0,7],"4":[0,7],"5":[2,5],"6":[2,0],"7":[6,1],"8":[6,0],"9":[2,5],"10":[2,0],"11":[4,3],"12":[2,5],"13":[2,5],"14":[2,0],"15":[2,5],"16":[7,4],"17":[11,5,4],"18":[2,2],"19":[4,2],"20":[0,2],"21":[0,0],"22":[0,2],"23":[2,0],"24":[1,1],"25":[0,1],"26":[1,1],"27":[1,6],"28":[1,3],"29":[1,0]},"meta":{"lastBranch":30,"lastFunction":4,"lastStatement":43,"seen":{"s:27:33:27:Infinity":0,"s:28:23:28:Infinity":1,"s:29:22:29:Infinity":2,"f:31:16:31:Infinity":0,"b:35:20:35:Infinity":0,"s:37:45:37:Infinity":3,"s:38:24:38:Infinity":4,"s:39:2:72:Infinity":5,"s:40:17:40:Infinity":6,"b:40:28:40:40:40:40:40:42":1,"s:41:17:41:Infinity":7,"b:41:49:41:61:41:61:41:63":2,"b:42:4:42:Infinity:undefined:undefined:undefined:undefined":3,"s:42:4:42:Infinity":8,"s:42:15:42:Infinity":9,"s:43:25:43:Infinity":10,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":4,"s:44:4:44:Infinity":11,"s:44:36:44:Infinity":12,"s:45:16:45:Infinity":13,"s:46:19:46:Infinity":14,"s:47:17:47:Infinity":15,"s:48:18:48:Infinity":16,"s:49:4:71:Infinity":17,"b:57:10:57:Infinity:58:10:58:Infinity":5,"b:57:26:57:69:57:69:57:79":6,"b:60:10:60:Infinity:61:10:61:Infinity":7,"b:60:22:60:61:60:61:60:71":8,"b:63:10:63:Infinity:64:10:64:Infinity":9,"b:63:22:63:61:63:61:63:71":10,"b:65:31:65:42:65:42:65:Infinity":11,"b:66:32:66:44:66:44:66:Infinity":12,"b:68:10:68:Infinity:69:10:69:Infinity":13,"b:68:20:68:57:68:57:68:67":14,"b:70:26:70:57:70:57:70:Infinity":15,"s:73:2:73:Infinity":18,"f:76:16:76:Infinity":1,"s:80:19:80:Infinity":19,"b:81:2:87:Infinity:undefined:undefined:undefined:undefined":16,"s:81:2:87:Infinity":20,"b:82:4:82:Infinity:83:4:83:Infinity:84:4:84:Infinity":17,"s:86:4:86:Infinity":21,"b:88:2:88:Infinity:undefined:undefined:undefined:undefined":18,"s:88:2:88:Infinity":22,"b:88:6:88:43:88:43:88:66":19,"s:88:66:88:Infinity":23,"b:89:2:89:Infinity:undefined:undefined:undefined:undefined":20,"s:89:2:89:Infinity":24,"s:89:37:89:Infinity":25,"b:89:68:89:80:89:80:89:Infinity":21,"b:90:2:90:Infinity:undefined:undefined:undefined:undefined":22,"s:90:2:90:Infinity":26,"b:90:6:90:37:90:37:90:63":23,"s:90:63:90:Infinity":27,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":24,"s:91:2:91:Infinity":28,"s:91:44:91:Infinity":29,"b:92:2:92:Infinity:undefined:undefined:undefined:undefined":25,"s:92:2:92:Infinity":30,"b:92:6:92:38:92:38:92:64":26,"s:92:64:92:Infinity":31,"s:93:2:93:Infinity":32,"f:96:9:96:Infinity":2,"s:99:15:99:Infinity":33,"s:100:43:100:Infinity":34,"s:101:2:105:Infinity":35,"b:102:4:102:Infinity:undefined:undefined:undefined:undefined":27,"s:102:4:102:Infinity":36,"s:102:28:102:Infinity":37,"s:103:4:103:Infinity":38,"s:104:4:104:Infinity":39,"s:106:2:106:Infinity":40,"f:109:9:109:33":3,"s:110:16:110:Infinity":41,"s:111:2:111:Infinity":42,"b:111:17:111:46:111:46:111:Infinity":28,"b:111:28:111:40:111:40:111:42":29}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/rows-to-records.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/rows-to-records.ts","statementMap":{"0":{"start":{"line":19,"column":30},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":18},"end":{"line":23,"column":null}},"4":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"5":{"start":{"line":24,"column":44},"end":{"line":24,"column":null}},"6":{"start":{"line":25,"column":2},"end":{"line":34,"column":null}},"7":{"start":{"line":26,"column":43},"end":{"line":26,"column":null}},"8":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"9":{"start":{"line":28,"column":4},"end":{"line":32,"column":null}},"10":{"start":{"line":28,"column":17},"end":{"line":28,"column":20}},"11":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"12":{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},"13":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"14":{"start":{"line":31,"column":6},"end":{"line":31,"column":null}},"15":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"16":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"17":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"18":{"start":{"line":39,"column":2},"end":{"line":58,"column":null}},"19":{"start":{"line":39,"column":15},"end":{"line":39,"column":18}},"20":{"start":{"line":40,"column":23},"end":{"line":40,"column":null}},"21":{"start":{"line":41,"column":27},"end":{"line":46,"column":null}},"22":{"start":{"line":42,"column":32},"end":{"line":42,"column":58}},"23":{"start":{"line":43,"column":32},"end":{"line":43,"column":60}},"24":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"25":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"26":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"27":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}},"28":{"start":{"line":48,"column":24},"end":{"line":56,"column":null}},"29":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"30":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"31":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"32":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"33":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"34":{"start":{"line":57,"column":26},"end":{"line":57,"column":null}},"35":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"36":{"start":{"line":59,"column":33},"end":{"line":59,"column":78}},"37":{"start":{"line":59,"column":54},"end":{"line":59,"column":65}}},"fnMap":{"0":{"name":"rowsToRecords","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"loc":{"start":{"line":18,"column":28},"end":{"line":36,"column":null}},"line":18},"1":{"name":"(anonymous_1)","decl":{"start":{"line":21,"column":44},"end":{"line":21,"column":null}},"loc":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"line":22},"2":{"name":"findLikelyHeaderRow","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":36}},"loc":{"start":{"line":38,"column":82},"end":{"line":60,"column":null}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":42,"column":17},"end":{"line":42,"column":23}},"loc":{"start":{"line":42,"column":32},"end":{"line":42,"column":58}},"line":42},"4":{"name":"(anonymous_4)","decl":{"start":{"line":43,"column":17},"end":{"line":43,"column":23}},"loc":{"start":{"line":43,"column":32},"end":{"line":43,"column":60}},"line":43},"5":{"name":"(anonymous_5)","decl":{"start":{"line":44,"column":17},"end":{"line":44,"column":23}},"loc":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"line":44},"6":{"name":"(anonymous_6)","decl":{"start":{"line":45,"column":17},"end":{"line":45,"column":23}},"loc":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"line":45},"7":{"name":"(anonymous_7)","decl":{"start":{"line":49,"column":17},"end":{"line":49,"column":23}},"loc":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"line":49},"8":{"name":"(anonymous_8)","decl":{"start":{"line":50,"column":17},"end":{"line":50,"column":null}},"loc":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"line":52},"9":{"name":"(anonymous_9)","decl":{"start":{"line":54,"column":17},"end":{"line":54,"column":23}},"loc":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"line":54},"10":{"name":"(anonymous_10)","decl":{"start":{"line":55,"column":17},"end":{"line":55,"column":23}},"loc":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"line":55},"11":{"name":"(anonymous_11)","decl":{"start":{"line":59,"column":14},"end":{"line":59,"column":25}},"loc":{"start":{"line":59,"column":33},"end":{"line":59,"column":78}},"line":59},"12":{"name":"(anonymous_12)","decl":{"start":{"line":59,"column":37},"end":{"line":59,"column":45}},"loc":{"start":{"line":59,"column":54},"end":{"line":59,"column":65}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":30},"end":{"line":19,"column":null}},"type":"binary-expr","locations":[{"start":{"line":19,"column":30},"end":{"line":19,"column":48}},{"start":{"line":19,"column":48},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"2":{"loc":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"type":"binary-expr","locations":[{"start":{"line":22,"column":23},"end":{"line":22,"column":40}},{"start":{"line":22,"column":40},"end":{"line":22,"column":null}}],"line":22},"3":{"loc":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"type":"binary-expr","locations":[{"start":{"line":29,"column":20},"end":{"line":29,"column":38}},{"start":{"line":29,"column":38},"end":{"line":29,"column":null}}],"line":29},"4":{"loc":{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":30},"5":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"6":{"loc":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"type":"binary-expr","locations":[{"start":{"line":44,"column":32},"end":{"line":44,"column":69}},{"start":{"line":44,"column":69},"end":{"line":44,"column":82}}],"line":44},"7":{"loc":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"type":"binary-expr","locations":[{"start":{"line":45,"column":32},"end":{"line":45,"column":49}},{"start":{"line":45,"column":49},"end":{"line":45,"column":64}}],"line":45},"8":{"loc":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"9":{"loc":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"type":"binary-expr","locations":[{"start":{"line":49,"column":32},"end":{"line":49,"column":59}},{"start":{"line":49,"column":59},"end":{"line":49,"column":83}}],"line":49},"10":{"loc":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"type":"binary-expr","locations":[{"start":{"line":52,"column":10},"end":{"line":52,"column":38}},{"start":{"line":52,"column":38},"end":{"line":52,"column":65}},{"start":{"line":52,"column":65},"end":{"line":52,"column":null}}],"line":52},"11":{"loc":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"type":"binary-expr","locations":[{"start":{"line":54,"column":32},"end":{"line":54,"column":49}},{"start":{"line":54,"column":49},"end":{"line":54,"column":80}},{"start":{"line":54,"column":80},"end":{"line":54,"column":95}}],"line":54},"12":{"loc":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"type":"binary-expr","locations":[{"start":{"line":55,"column":32},"end":{"line":55,"column":59}},{"start":{"line":55,"column":59},"end":{"line":55,"column":82}}],"line":55},"13":{"loc":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57}},"s":{"0":8,"1":8,"2":1,"3":7,"4":20,"5":7,"6":7,"7":16,"8":16,"9":16,"10":16,"11":56,"12":56,"13":56,"14":56,"15":16,"16":16,"17":7,"18":6,"19":6,"20":5,"21":5,"22":10,"23":13,"24":16,"25":7,"26":5,"27":3,"28":2,"29":4,"30":2,"31":4,"32":4,"33":2,"34":2,"35":0,"36":0,"37":0},"f":{"0":8,"1":20,"2":6,"3":10,"4":13,"5":16,"6":7,"7":4,"8":2,"9":4,"10":4,"11":0,"12":0},"b":{"0":[8,6],"1":[1,7],"2":[20,1],"3":[56,0],"4":[56,0],"5":[16,0],"6":[16,13],"7":[7,4],"8":[3,2],"9":[4,2],"10":[2,1,1],"11":[4,4,4],"12":[4,4],"13":[2,0]},"meta":{"lastBranch":14,"lastFunction":13,"lastStatement":38,"seen":{"f:15:16:15:Infinity":0,"s:19:30:19:Infinity":0,"b:19:30:19:48:19:48:19:Infinity":0,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":1,"s:20:2:20:Infinity":1,"s:20:31:20:Infinity":2,"s:21:18:23:Infinity":3,"f:21:44:21:Infinity":1,"s:22:23:22:Infinity":4,"b:22:23:22:40:22:40:22:Infinity":2,"s:24:44:24:Infinity":5,"s:25:2:34:Infinity":6,"s:26:43:26:Infinity":7,"s:27:19:27:Infinity":8,"s:28:4:32:Infinity":9,"s:28:17:28:20":10,"s:29:20:29:Infinity":11,"b:29:20:29:38:29:38:29:Infinity":3,"b:30:6:30:Infinity:undefined:undefined:undefined:undefined":4,"s:30:6:30:Infinity":12,"s:30:17:30:Infinity":13,"s:31:6:31:Infinity":14,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":5,"s:33:4:33:Infinity":15,"s:33:18:33:Infinity":16,"s:35:2:35:Infinity":17,"f:38:16:38:36":2,"s:39:2:58:Infinity":18,"s:39:15:39:18":19,"s:40:23:40:Infinity":20,"s:41:27:46:Infinity":21,"f:42:17:42:23":3,"s:42:32:42:58":22,"f:43:17:43:23":4,"s:43:32:43:60":23,"f:44:17:44:23":5,"s:44:32:44:82":24,"b:44:32:44:69:44:69:44:82":6,"f:45:17:45:23":6,"s:45:32:45:64":25,"b:45:32:45:49:45:49:45:64":7,"b:47:4:47:Infinity:undefined:undefined:undefined:undefined":8,"s:47:4:47:Infinity":26,"s:47:29:47:Infinity":27,"s:48:24:56:Infinity":28,"f:49:17:49:23":7,"s:49:32:49:83":29,"b:49:32:49:59:49:59:49:83":9,"f:50:17:50:Infinity":8,"s:52:10:52:Infinity":30,"b:52:10:52:38:52:38:52:65:52:65:52:Infinity":10,"f:54:17:54:23":9,"s:54:32:54:95":31,"b:54:32:54:49:54:49:54:80:54:80:54:95":11,"f:55:17:55:23":10,"s:55:32:55:82":32,"b:55:32:55:59:55:59:55:82":12,"b:57:4:57:Infinity:undefined:undefined:undefined:undefined":13,"s:57:4:57:Infinity":33,"s:57:26:57:Infinity":34,"s:59:2:59:Infinity":35,"f:59:14:59:25":11,"s:59:33:59:78":36,"f:59:37:59:45":12,"s:59:54:59:65":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/url-guard.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/url-guard.ts","statementMap":{"0":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"1":{"start":{"line":33,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"3":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"5":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"6":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},"8":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"resolveStatskontoretUrl","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":40}},"loc":{"start":{"line":18,"column":78},"end":{"line":20,"column":null}},"line":18},"1":{"name":"assertStatskontoretFetchTarget","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"loc":{"start":{"line":31,"column":7},"end":{"line":49,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"default-arg","locations":[{"start":{"line":30,"column":20},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":38},"2":{"loc":{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":42}},"s":{"0":17,"1":11,"2":11,"3":1,"4":10,"5":1,"6":9,"7":9,"8":2,"9":7},"f":{"0":17,"1":11},"b":{"0":[11],"1":[1,9],"2":[2,7]},"meta":{"lastBranch":3,"lastFunction":2,"lastStatement":10,"seen":{"f:18:16:18:40":0,"s:19:2:19:Infinity":0,"f:28:16:28:Infinity":1,"b:30:20:30:Infinity":0,"s:33:2:37:Infinity":1,"s:34:4:34:Infinity":2,"s:36:4:36:Infinity":3,"b:38:2:40:Infinity:undefined:undefined:undefined:undefined":1,"s:38:2:40:Infinity":4,"s:39:4:39:Infinity":5,"s:41:22:41:Infinity":6,"b:42:2:47:Infinity:undefined:undefined:undefined:undefined":2,"s:42:2:47:Infinity":7,"s:43:4:46:Infinity":8,"s:48:2:48:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/csv-zip.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/csv-zip.ts","statementMap":{"0":{"start":{"line":18,"column":14},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":38},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"4":{"start":{"line":21,"column":19},"end":{"line":21,"column":null}},"5":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"6":{"start":{"line":22,"column":31},"end":{"line":22,"column":null}},"7":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"8":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"parseStatskontoretCsvZip","decl":{"start":{"line":15,"column":22},"end":{"line":15,"column":null}},"loc":{"start":{"line":17,"column":35},"end":{"line":26,"column":null}},"line":17}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":21},"1":{"loc":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},{"start":{},"end":{}}],"line":22}},"s":{"0":1,"1":1,"2":1,"3":2,"4":0,"5":2,"6":1,"7":1,"8":1},"f":{"0":1},"b":{"0":[0,2],"1":[1,1]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":9,"seen":{"f:15:22:15:Infinity":0,"s:18:14:18:Infinity":0,"s:19:38:19:Infinity":1,"s:20:2:24:Infinity":2,"b:21:4:21:Infinity:undefined:undefined:undefined:undefined":0,"s:21:4:21:Infinity":3,"s:21:19:21:Infinity":4,"b:22:4:22:Infinity:undefined:undefined:undefined:undefined":1,"s:22:4:22:Infinity":5,"s:22:31:22:Infinity":6,"s:23:4:23:Infinity":7,"s:25:2:25:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/text.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/text.ts","statementMap":{"0":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"7":{"start":{"line":45,"column":21},"end":{"line":47,"column":null}},"8":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"9":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"10":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"11":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"12":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"14":{"start":{"line":59,"column":17},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":2},"end":{"line":62,"column":null}},"16":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"17":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"18":{"start":{"line":70,"column":31},"end":{"line":70,"column":null}},"19":{"start":{"line":71,"column":2},"end":{"line":74,"column":null}},"20":{"start":{"line":72,"column":18},"end":{"line":72,"column":null}},"21":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"22":{"start":{"line":73,"column":29},"end":{"line":73,"column":null}},"23":{"start":{"line":75,"column":2},"end":{"line":77,"column":null}},"24":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"25":{"start":{"line":76,"column":49},"end":{"line":76,"column":72}},"26":{"start":{"line":76,"column":75},"end":{"line":76,"column":null}},"27":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"28":{"start":{"line":82,"column":16},"end":{"line":82,"column":null}},"29":{"start":{"line":83,"column":17},"end":{"line":83,"column":null}},"30":{"start":{"line":84,"column":2},"end":{"line":86,"column":null}},"31":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"32":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"33":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"34":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"35":{"start":{"line":96,"column":26},"end":{"line":96,"column":null}},"36":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"37":{"start":{"line":98,"column":2},"end":{"line":100,"column":null}},"38":{"start":{"line":99,"column":4},"end":{"line":99,"column":null}},"39":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"trimTrailingSlash","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":34}},"loc":{"start":{"line":15,"column":57},"end":{"line":17,"column":null}},"line":15},"1":{"name":"normalizeWhitespace","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":36}},"loc":{"start":{"line":19,"column":59},"end":{"line":21,"column":null}},"line":19},"2":{"name":"normalizeKey","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":29}},"loc":{"start":{"line":23,"column":52},"end":{"line":29,"column":null}},"line":23},"3":{"name":"roundOneDecimal","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":32}},"loc":{"start":{"line":31,"column":55},"end":{"line":33,"column":null}},"line":31},"4":{"name":"decodeHtml","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":27}},"loc":{"start":{"line":35,"column":50},"end":{"line":37,"column":null}},"line":35},"5":{"name":"decodeXml","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":26}},"loc":{"start":{"line":39,"column":49},"end":{"line":41,"column":null}},"line":39},"6":{"name":"parseStatskontoretSwedishNumber","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":48}},"loc":{"start":{"line":43,"column":83},"end":{"line":50,"column":null}},"line":43},"7":{"name":"parseStatskontoretOptionalInt","decl":{"start":{"line":52,"column":16},"end":{"line":52,"column":46}},"loc":{"start":{"line":52,"column":88},"end":{"line":56,"column":null}},"line":52},"8":{"name":"buildRecordLookup","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":34}},"loc":{"start":{"line":58,"column":87},"end":{"line":64,"column":null}},"line":58},"9":{"name":"findField","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"loc":{"start":{"line":69,"column":22},"end":{"line":79,"column":null}},"line":69},"10":{"name":"(anonymous_10)","decl":{"start":{"line":76,"column":29},"end":{"line":76,"column":35}},"loc":{"start":{"line":76,"column":49},"end":{"line":76,"column":72}},"line":76},"11":{"name":"parseXmlAttributes","decl":{"start":{"line":81,"column":16},"end":{"line":81,"column":35}},"loc":{"start":{"line":81,"column":71},"end":{"line":88,"column":null}},"line":81},"12":{"name":"firstXmlTagValue","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":33}},"loc":{"start":{"line":90,"column":79},"end":{"line":93,"column":null}},"line":90},"13":{"name":"extractTextNodes","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":33}},"loc":{"start":{"line":95,"column":54},"end":{"line":102,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":21},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},{"start":{"line":47,"column":6},"end":{"line":47,"column":null}}],"line":45},"1":{"loc":{"start":{"line":49,"column":9},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":35},"end":{"line":49,"column":44}},{"start":{"line":49,"column":44},"end":{"line":49,"column":null}}],"line":49},"2":{"loc":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"3":{"loc":{"start":{"line":55,"column":9},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":35},"end":{"line":55,"column":44}},{"start":{"line":55,"column":44},"end":{"line":55,"column":null}}],"line":55},"4":{"loc":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"5":{"loc":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":76},"6":{"loc":{"start":{"line":85,"column":34},"end":{"line":85,"column":48}},"type":"binary-expr","locations":[{"start":{"line":85,"column":34},"end":{"line":85,"column":46}},{"start":{"line":85,"column":46},"end":{"line":85,"column":48}}],"line":85},"7":{"loc":{"start":{"line":92,"column":9},"end":{"line":92,"column":null}},"type":"cond-expr","locations":[{"start":{"line":92,"column":17},"end":{"line":92,"column":45}},{"start":{"line":92,"column":45},"end":{"line":92,"column":null}}],"line":92},"8":{"loc":{"start":{"line":92,"column":27},"end":{"line":92,"column":41}},"type":"binary-expr","locations":[{"start":{"line":92,"column":27},"end":{"line":92,"column":39}},{"start":{"line":92,"column":39},"end":{"line":92,"column":41}}],"line":92},"9":{"loc":{"start":{"line":99,"column":25},"end":{"line":99,"column":39}},"type":"binary-expr","locations":[{"start":{"line":99,"column":25},"end":{"line":99,"column":37}},{"start":{"line":99,"column":37},"end":{"line":99,"column":39}}],"line":99}},"s":{"0":24,"1":7,"2":1500,"3":41,"4":317,"5":285,"6":57,"7":57,"8":57,"9":57,"10":73,"11":33,"12":40,"13":40,"14":34,"15":34,"16":134,"17":34,"18":238,"19":238,"20":768,"21":768,"22":132,"23":106,"24":330,"25":1616,"26":37,"27":69,"28":82,"29":82,"30":82,"31":148,"32":82,"33":70,"34":70,"35":33,"36":33,"37":33,"38":33,"39":33},"f":{"0":24,"1":7,"2":1500,"3":41,"4":317,"5":285,"6":57,"7":73,"8":34,"9":238,"10":1616,"11":82,"12":70,"13":33},"b":{"0":[4,53],"1":[40,17],"2":[33,40],"3":[40,0],"4":[132,636],"5":[37,293],"6":[148,0],"7":[70,0],"8":[70,0],"9":[33,0]},"meta":{"lastBranch":10,"lastFunction":14,"lastStatement":40,"seen":{"f:15:16:15:34":0,"s:16:2:16:Infinity":0,"f:19:16:19:36":1,"s:20:2:20:Infinity":1,"f:23:16:23:29":2,"s:24:2:28:Infinity":2,"f:31:16:31:32":3,"s:32:2:32:Infinity":3,"f:35:16:35:27":4,"s:36:2:36:Infinity":4,"f:39:16:39:26":5,"s:40:2:40:Infinity":5,"f:43:16:43:48":6,"s:44:18:44:Infinity":6,"s:45:21:47:Infinity":7,"b:46:6:46:Infinity:47:6:47:Infinity":0,"s:48:17:48:Infinity":8,"s:49:2:49:Infinity":9,"b:49:35:49:44:49:44:49:Infinity":1,"f:52:16:52:46":7,"b:53:2:53:Infinity:undefined:undefined:undefined:undefined":2,"s:53:2:53:Infinity":10,"s:53:14:53:Infinity":11,"s:54:17:54:Infinity":12,"s:55:2:55:Infinity":13,"b:55:35:55:44:55:44:55:Infinity":3,"f:58:16:58:34":8,"s:59:17:59:Infinity":14,"s:60:2:62:Infinity":15,"s:61:4:61:Infinity":16,"s:63:2:63:Infinity":17,"f:66:16:66:Infinity":9,"s:70:31:70:Infinity":18,"s:71:2:74:Infinity":19,"s:72:18:72:Infinity":20,"b:73:4:73:Infinity:undefined:undefined:undefined:undefined":4,"s:73:4:73:Infinity":21,"s:73:29:73:Infinity":22,"s:75:2:77:Infinity":23,"b:76:4:76:Infinity:undefined:undefined:undefined:undefined":5,"s:76:4:76:Infinity":24,"f:76:29:76:35":10,"s:76:49:76:72":25,"s:76:75:76:Infinity":26,"s:78:2:78:Infinity":27,"f:81:16:81:35":11,"s:82:16:82:Infinity":28,"s:83:17:83:Infinity":29,"s:84:2:86:Infinity":30,"s:85:4:85:Infinity":31,"b:85:34:85:46:85:46:85:48":6,"s:87:2:87:Infinity":32,"f:90:16:90:33":12,"s:91:16:91:Infinity":33,"s:92:2:92:Infinity":34,"b:92:17:92:45:92:45:92:Infinity":7,"b:92:27:92:39:92:39:92:41":8,"f:95:16:95:33":13,"s:96:26:96:Infinity":35,"s:97:17:97:Infinity":36,"s:98:2:100:Infinity":37,"s:99:4:99:Infinity":38,"b:99:25:99:37:99:37:99:39":9,"s:101:2:101:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/source-registry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/source-registry.ts","statementMap":{"0":{"start":{"line":18,"column":38},"end":{"line":18,"column":null}},"1":{"start":{"line":20,"column":79},"end":{"line":53,"column":null}},"2":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"3":{"start":{"line":56,"column":59},"end":{"line":56,"column":80}},"4":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"5":{"start":{"line":57,"column":15},"end":{"line":57,"column":null}},"6":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"getStatskontoretSource","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":39}},"loc":{"start":{"line":55,"column":99},"end":{"line":59,"column":null}},"line":55},"1":{"name":"(anonymous_1)","decl":{"start":{"line":56,"column":39},"end":{"line":56,"column":45}},"loc":{"start":{"line":56,"column":59},"end":{"line":56,"column":80}},"line":56}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57}},"s":{"0":4,"1":4,"2":9,"3":26,"4":9,"5":2,"6":7},"f":{"0":9,"1":26},"b":{"0":[2,7]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":7,"seen":{"s:18:38:18:Infinity":0,"s:20:79:53:Infinity":1,"f:55:16:55:39":0,"s:56:17:56:Infinity":2,"f:56:39:56:45":1,"s:56:59:56:80":3,"b:57:2:57:Infinity:undefined:undefined:undefined:undefined":0,"s:57:2:57:Infinity":4,"s:57:15:57:Infinity":5,"s:58:2:58:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/xlsx.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/xlsx.ts","statementMap":{"0":{"start":{"line":27,"column":14},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":26},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":27},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"5":{"start":{"line":34,"column":15},"end":{"line":34,"column":null}},"6":{"start":{"line":35,"column":39},"end":{"line":35,"column":null}},"7":{"start":{"line":37,"column":2},"end":{"line":43,"column":null}},"8":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"9":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"10":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"11":{"start":{"line":40,"column":22},"end":{"line":40,"column":null}},"12":{"start":{"line":41,"column":21},"end":{"line":41,"column":null}},"13":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"14":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"15":{"start":{"line":49,"column":66},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":2},"end":{"line":56,"column":null}},"18":{"start":{"line":52,"column":18},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":17},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"21":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"22":{"start":{"line":55,"column":32},"end":{"line":55,"column":null}},"23":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"24":{"start":{"line":61,"column":15},"end":{"line":61,"column":null}},"25":{"start":{"line":62,"column":16},"end":{"line":62,"column":null}},"26":{"start":{"line":63,"column":2},"end":{"line":68,"column":null}},"27":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"28":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"29":{"start":{"line":66,"column":19},"end":{"line":66,"column":null}},"30":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"31":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"32":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"33":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"34":{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},"35":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"36":{"start":{"line":75,"column":15},"end":{"line":75,"column":null}},"37":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"38":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"39":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"40":{"start":{"line":83,"column":27},"end":{"line":83,"column":null}},"41":{"start":{"line":84,"column":16},"end":{"line":84,"column":null}},"42":{"start":{"line":85,"column":2},"end":{"line":95,"column":null}},"43":{"start":{"line":86,"column":26},"end":{"line":86,"column":null}},"44":{"start":{"line":87,"column":19},"end":{"line":87,"column":null}},"45":{"start":{"line":88,"column":4},"end":{"line":93,"column":null}},"46":{"start":{"line":89,"column":20},"end":{"line":89,"column":null}},"47":{"start":{"line":90,"column":18},"end":{"line":90,"column":null}},"48":{"start":{"line":91,"column":24},"end":{"line":91,"column":null}},"49":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"50":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"51":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"52":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"53":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"54":{"start":{"line":104,"column":28},"end":{"line":104,"column":null}},"55":{"start":{"line":105,"column":16},"end":{"line":105,"column":null}},"56":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"57":{"start":{"line":106,"column":27},"end":{"line":106,"column":null}},"58":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"59":{"start":{"line":107,"column":20},"end":{"line":107,"column":null}},"60":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}},"61":{"start":{"line":112,"column":18},"end":{"line":112,"column":null}},"62":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"63":{"start":{"line":113,"column":16},"end":{"line":113,"column":null}},"64":{"start":{"line":114,"column":14},"end":{"line":114,"column":null}},"65":{"start":{"line":115,"column":2},"end":{"line":117,"column":null}},"66":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"67":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"68":{"start":{"line":122,"column":15},"end":{"line":122,"column":null}},"69":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"70":{"start":{"line":123,"column":13},"end":{"line":123,"column":null}},"71":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}}},"fnMap":{"0":{"name":"parseStatskontoretXlsx","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":null}},"loc":{"start":{"line":26,"column":34},"end":{"line":46,"column":null}},"line":26},"1":{"name":"parseWorkbookSheets","decl":{"start":{"line":48,"column":9},"end":{"line":48,"column":29}},"loc":{"start":{"line":48,"column":91},"end":{"line":58,"column":null}},"line":48},"2":{"name":"parseWorkbookRelationships","decl":{"start":{"line":60,"column":9},"end":{"line":60,"column":36}},"loc":{"start":{"line":60,"column":70},"end":{"line":70,"column":null}},"line":60},"3":{"name":"parseSharedStrings","decl":{"start":{"line":72,"column":9},"end":{"line":72,"column":28}},"loc":{"start":{"line":72,"column":51},"end":{"line":80,"column":null}},"line":72},"4":{"name":"parseWorksheetRows","decl":{"start":{"line":82,"column":9},"end":{"line":82,"column":28}},"loc":{"start":{"line":82,"column":87},"end":{"line":97,"column":null}},"line":82},"5":{"name":"(anonymous_5)","decl":{"start":{"line":94,"column":46},"end":{"line":94,"column":50}},"loc":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"line":94},"6":{"name":"parseCellValue","decl":{"start":{"line":99,"column":9},"end":{"line":99,"column":null}},"loc":{"start":{"line":103,"column":10},"end":{"line":109,"column":null}},"line":103},"7":{"name":"cellRefToColumnIndex","decl":{"start":{"line":111,"column":9},"end":{"line":111,"column":30}},"loc":{"start":{"line":111,"column":63},"end":{"line":119,"column":null}},"line":111},"8":{"name":"readZipText","decl":{"start":{"line":121,"column":15},"end":{"line":121,"column":27}},"loc":{"start":{"line":121,"column":70},"end":{"line":125,"column":null}},"line":121}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":27},"end":{"line":32,"column":null}},"type":"cond-expr","locations":[{"start":{"line":31,"column":6},"end":{"line":31,"column":null}},{"start":{"line":32,"column":6},"end":{"line":32,"column":null}}],"line":30},"1":{"loc":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"2":{"loc":{"start":{"line":40,"column":22},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":47},"end":{"line":40,"column":65}},{"start":{"line":40,"column":65},"end":{"line":40,"column":null}}],"line":40},"3":{"loc":{"start":{"line":52,"column":37},"end":{"line":52,"column":51}},"type":"binary-expr","locations":[{"start":{"line":52,"column":37},"end":{"line":52,"column":49}},{"start":{"line":52,"column":49},"end":{"line":52,"column":51}}],"line":52},"4":{"loc":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"type":"binary-expr","locations":[{"start":{"line":54,"column":27},"end":{"line":54,"column":48}},{"start":{"line":54,"column":48},"end":{"line":54,"column":null}}],"line":54},"5":{"loc":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"6":{"loc":{"start":{"line":55,"column":8},"end":{"line":55,"column":32}},"type":"binary-expr","locations":[{"start":{"line":55,"column":8},"end":{"line":55,"column":16}},{"start":{"line":55,"column":16},"end":{"line":55,"column":32}}],"line":55},"7":{"loc":{"start":{"line":64,"column":37},"end":{"line":64,"column":51}},"type":"binary-expr","locations":[{"start":{"line":64,"column":37},"end":{"line":64,"column":49}},{"start":{"line":64,"column":49},"end":{"line":64,"column":51}}],"line":64},"8":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"9":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":22}},"type":"binary-expr","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":14}},{"start":{"line":67,"column":14},"end":{"line":67,"column":22}}],"line":67},"10":{"loc":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"11":{"loc":{"start":{"line":77,"column":34},"end":{"line":77,"column":48}},"type":"binary-expr","locations":[{"start":{"line":77,"column":34},"end":{"line":77,"column":46}},{"start":{"line":77,"column":46},"end":{"line":77,"column":48}}],"line":77},"12":{"loc":{"start":{"line":88,"column":29},"end":{"line":88,"column":46}},"type":"binary-expr","locations":[{"start":{"line":88,"column":29},"end":{"line":88,"column":44}},{"start":{"line":88,"column":44},"end":{"line":88,"column":46}}],"line":88},"13":{"loc":{"start":{"line":89,"column":39},"end":{"line":89,"column":57}},"type":"binary-expr","locations":[{"start":{"line":89,"column":39},"end":{"line":89,"column":55}},{"start":{"line":89,"column":55},"end":{"line":89,"column":57}}],"line":89},"14":{"loc":{"start":{"line":90,"column":18},"end":{"line":90,"column":null}},"type":"binary-expr","locations":[{"start":{"line":90,"column":18},"end":{"line":90,"column":36}},{"start":{"line":90,"column":36},"end":{"line":90,"column":null}}],"line":90},"15":{"loc":{"start":{"line":91,"column":24},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":91,"column":24},"end":{"line":91,"column":53}},{"start":{"line":91,"column":53},"end":{"line":91,"column":null}}],"line":91},"16":{"loc":{"start":{"line":92,"column":38},"end":{"line":92,"column":58}},"type":"binary-expr","locations":[{"start":{"line":92,"column":38},"end":{"line":92,"column":54}},{"start":{"line":92,"column":54},"end":{"line":92,"column":58}}],"line":92},"17":{"loc":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"type":"binary-expr","locations":[{"start":{"line":94,"column":59},"end":{"line":94,"column":69}},{"start":{"line":94,"column":69},"end":{"line":94,"column":71}}],"line":94},"18":{"loc":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},{"start":{},"end":{}}],"line":104},"19":{"loc":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":106},"20":{"loc":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":107},"21":{"loc":{"start":{"line":107,"column":27},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":107,"column":27},"end":{"line":107,"column":72}},{"start":{"line":107,"column":72},"end":{"line":107,"column":null}}],"line":107},"22":{"loc":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":113},"23":{"loc":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":123}},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5,"8":6,"9":6,"10":0,"11":6,"12":6,"13":6,"14":5,"15":5,"16":5,"17":5,"18":6,"19":6,"20":6,"21":6,"22":6,"23":5,"24":5,"25":5,"26":5,"27":6,"28":6,"29":6,"30":6,"31":6,"32":5,"33":5,"34":1,"35":4,"36":4,"37":4,"38":33,"39":4,"40":6,"41":6,"42":6,"43":20,"44":20,"45":20,"46":70,"47":70,"48":70,"49":70,"50":20,"51":71,"52":6,"53":70,"54":0,"55":70,"56":70,"57":0,"58":70,"59":42,"60":28,"61":70,"62":70,"63":0,"64":70,"65":70,"66":70,"67":70,"68":20,"69":20,"70":0,"71":20},"f":{"0":5,"1":5,"2":5,"3":5,"4":6,"5":71,"6":70,"7":70,"8":20},"b":{"0":[4,1],"1":[0,6],"2":[0,6],"3":[6,0],"4":[6,0],"5":[6,0],"6":[6,6],"7":[6,0],"8":[6,0],"9":[6,6],"10":[1,4],"11":[33,0],"12":[20,0],"13":[70,0],"14":[70,0],"15":[70,0],"16":[70,0],"17":[71,1],"18":[0,70],"19":[0,70],"20":[42,28],"21":[42,0],"22":[0,70],"23":[0,20]},"meta":{"lastBranch":24,"lastFunction":9,"lastStatement":72,"seen":{"f:24:22:24:Infinity":0,"s:27:14:27:Infinity":0,"s:28:22:28:Infinity":1,"s:29:26:29:Infinity":2,"s:30:27:32:Infinity":3,"b:31:6:31:Infinity:32:6:32:Infinity":0,"s:33:24:33:Infinity":4,"s:34:15:34:Infinity":5,"s:35:39:35:Infinity":6,"s:37:2:43:Infinity":7,"s:38:19:38:Infinity":8,"b:39:4:39:Infinity:undefined:undefined:undefined:undefined":1,"s:39:4:39:Infinity":9,"s:39:17:39:Infinity":10,"s:40:22:40:Infinity":11,"b:40:47:40:65:40:65:40:Infinity":2,"s:41:21:41:Infinity":12,"s:42:4:42:Infinity":13,"s:45:2:45:Infinity":14,"f:48:9:48:29":1,"s:49:66:49:Infinity":15,"s:50:18:50:Infinity":16,"s:51:2:56:Infinity":17,"s:52:18:52:Infinity":18,"b:52:37:52:49:52:49:52:51":3,"s:53:17:53:Infinity":19,"s:54:27:54:Infinity":20,"b:54:27:54:48:54:48:54:Infinity":4,"b:55:4:55:Infinity:undefined:undefined:undefined:undefined":5,"s:55:4:55:Infinity":21,"b:55:8:55:16:55:16:55:32":6,"s:55:32:55:Infinity":22,"s:57:2:57:Infinity":23,"f:60:9:60:36":2,"s:61:15:61:Infinity":24,"s:62:16:62:Infinity":25,"s:63:2:68:Infinity":26,"s:64:18:64:Infinity":27,"b:64:37:64:49:64:49:64:51":7,"s:65:15:65:Infinity":28,"s:66:19:66:Infinity":29,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":8,"s:67:4:67:Infinity":30,"b:67:8:67:14:67:14:67:22":9,"s:67:22:67:Infinity":31,"s:69:2:69:Infinity":32,"f:72:9:72:28":3,"b:73:2:73:Infinity:undefined:undefined:undefined:undefined":10,"s:73:2:73:Infinity":33,"s:73:12:73:Infinity":34,"s:74:28:74:Infinity":35,"s:75:15:75:Infinity":36,"s:76:2:78:Infinity":37,"s:77:4:77:Infinity":38,"b:77:34:77:46:77:46:77:48":11,"s:79:2:79:Infinity":39,"f:82:9:82:28":4,"s:83:27:83:Infinity":40,"s:84:16:84:Infinity":41,"s:85:2:95:Infinity":42,"s:86:26:86:Infinity":43,"s:87:19:87:Infinity":44,"s:88:4:93:Infinity":45,"b:88:29:88:44:88:44:88:46":12,"s:89:20:89:Infinity":46,"b:89:39:89:55:89:55:89:57":13,"s:90:18:90:Infinity":47,"b:90:18:90:36:90:36:90:Infinity":14,"s:91:24:91:Infinity":48,"b:91:24:91:53:91:53:91:Infinity":15,"s:92:6:92:Infinity":49,"b:92:38:92:54:92:54:92:58":16,"s:94:4:94:Infinity":50,"f:94:46:94:50":5,"s:94:59:94:71":51,"b:94:59:94:69:94:69:94:71":17,"s:96:2:96:Infinity":52,"f:99:9:99:Infinity":6,"b:104:2:104:Infinity:undefined:undefined:undefined:undefined":18,"s:104:2:104:Infinity":53,"s:104:28:104:Infinity":54,"s:105:16:105:Infinity":55,"b:106:2:106:Infinity:undefined:undefined:undefined:undefined":19,"s:106:2:106:Infinity":56,"s:106:27:106:Infinity":57,"b:107:2:107:Infinity:undefined:undefined:undefined:undefined":20,"s:107:2:107:Infinity":58,"s:107:20:107:Infinity":59,"b:107:27:107:72:107:72:107:Infinity":21,"s:108:2:108:Infinity":60,"f:111:9:111:30":7,"s:112:18:112:Infinity":61,"b:113:2:113:Infinity:undefined:undefined:undefined:undefined":22,"s:113:2:113:Infinity":62,"s:113:16:113:Infinity":63,"s:114:14:114:Infinity":64,"s:115:2:117:Infinity":65,"s:116:4:116:Infinity":66,"s:118:2:118:Infinity":67,"f:121:15:121:27":8,"s:122:15:122:Infinity":68,"b:123:2:123:Infinity:undefined:undefined:undefined:undefined":23,"s:123:2:123:Infinity":69,"s:123:13:123:Infinity":70,"s:124:2:124:Infinity":71}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/banned-phrases.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/banned-phrases.ts","statementMap":{"0":{"start":{"line":24,"column":43},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":32},"end":{"line":25,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"3":{"start":{"line":34,"column":33},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":19},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"9":{"start":{"line":41,"column":2},"end":{"line":61,"column":null}},"10":{"start":{"line":42,"column":17},"end":{"line":42,"column":null}},"11":{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},"12":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"13":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"14":{"start":{"line":47,"column":32},"end":{"line":47,"column":null}},"15":{"start":{"line":48,"column":6},"end":{"line":56,"column":null}},"16":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"17":{"start":{"line":49,"column":38},"end":{"line":49,"column":null}},"18":{"start":{"line":50,"column":24},"end":{"line":50,"column":null}},"19":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"20":{"start":{"line":51,"column":34},"end":{"line":51,"column":null}},"21":{"start":{"line":52,"column":20},"end":{"line":52,"column":null}},"22":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"23":{"start":{"line":53,"column":27},"end":{"line":53,"column":null}},"24":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"25":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"26":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"27":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"28":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"29":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"30":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"31":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"32":{"start":{"line":80,"column":59},"end":{"line":80,"column":null}},"33":{"start":{"line":81,"column":16},"end":{"line":81,"column":null}},"34":{"start":{"line":82,"column":2},"end":{"line":94,"column":null}},"35":{"start":{"line":83,"column":20},"end":{"line":83,"column":null}},"36":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"37":{"start":{"line":84,"column":30},"end":{"line":84,"column":null}},"38":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"39":{"start":{"line":86,"column":14},"end":{"line":86,"column":null}},"40":{"start":{"line":87,"column":4},"end":{"line":93,"column":null}},"41":{"start":{"line":88,"column":20},"end":{"line":88,"column":null}},"42":{"start":{"line":89,"column":18},"end":{"line":89,"column":null}},"43":{"start":{"line":90,"column":22},"end":{"line":90,"column":null}},"44":{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},"45":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"46":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"47":{"start":{"line":102,"column":34},"end":{"line":102,"column":null}},"48":{"start":{"line":103,"column":24},"end":{"line":103,"column":null}},"49":{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},"50":{"start":{"line":105,"column":4},"end":{"line":109,"column":null}},"51":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"52":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"53":{"start":{"line":112,"column":34},"end":{"line":112,"column":null}},"54":{"start":{"line":113,"column":15},"end":{"line":113,"column":null}},"55":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},"56":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"57":{"start":{"line":115,"column":47},"end":{"line":115,"column":62}},"58":{"start":{"line":116,"column":4},"end":{"line":120,"column":null}},"59":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"loadBannedPhrases","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":34}},"loc":{"start":{"line":33,"column":81},"end":{"line":64,"column":null}},"line":33},"1":{"name":"resetBannedPhrasesCache","decl":{"start":{"line":67,"column":16},"end":{"line":67,"column":48}},"loc":{"start":{"line":67,"column":48},"end":{"line":70,"column":null}},"line":67},"2":{"name":"scanBannedPhrases","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":null}},"loc":{"start":{"line":79,"column":46},"end":{"line":96,"column":null}},"line":79},"3":{"name":"checkBannedPhrases","decl":{"start":{"line":101,"column":16},"end":{"line":101,"column":35}},"loc":{"start":{"line":101,"column":82},"end":{"line":123,"column":null}},"line":101},"4":{"name":"(anonymous_4)","decl":{"start":{"line":115,"column":36},"end":{"line":115,"column":41}},"loc":{"start":{"line":115,"column":47},"end":{"line":115,"column":62}},"line":115}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":34},"end":{"line":33,"column":81}},"type":"default-arg","locations":[{"start":{"line":33,"column":53},"end":{"line":33,"column":81}}],"line":33},"1":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"2":{"loc":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":36},"3":{"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},{"start":{"line":45,"column":11},"end":{"line":58,"column":null}}],"line":43},"4":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":73}},"type":"binary-expr","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":43}},{"start":{"line":43,"column":43},"end":{"line":43,"column":73}}],"line":43},"5":{"loc":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"6":{"loc":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"7":{"loc":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":57,"column":28},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":49},"end":{"line":57,"column":59}},{"start":{"line":57,"column":59},"end":{"line":57,"column":null}}],"line":57},"9":{"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"10":{"loc":{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":104},"11":{"loc":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},{"start":{},"end":{}}],"line":112},"12":{"loc":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":114},"13":{"loc":{"start":{"line":119,"column":77},"end":{"line":119,"column":106}},"type":"cond-expr","locations":[{"start":{"line":119,"column":95},"end":{"line":119,"column":103}},{"start":{"line":119,"column":103},"end":{"line":119,"column":106}}],"line":119}},"s":{"0":2,"1":2,"2":10,"3":1,"4":9,"5":9,"6":2,"7":2,"8":2,"9":7,"10":7,"11":7,"12":1,"13":5,"14":5,"15":5,"16":242,"17":1,"18":241,"19":241,"20":1,"21":240,"22":240,"23":2,"24":238,"25":238,"26":5,"27":1,"28":7,"29":7,"30":16,"31":16,"32":7,"33":7,"34":7,"35":133,"36":133,"37":2,"38":131,"39":131,"40":131,"41":6,"42":6,"43":6,"44":6,"45":6,"46":7,"47":2,"48":2,"49":2,"50":0,"51":0,"52":2,"53":0,"54":2,"55":2,"56":1,"57":1,"58":1,"59":2},"f":{"0":10,"1":16,"2":7,"3":2,"4":1},"b":{"0":[10],"1":[1,9],"2":[2,7],"3":[1,5],"4":[7,5],"5":[1,241],"6":[1,240],"7":[2,238],"8":[5,0],"9":[2,131],"10":[0,2],"11":[0,2],"12":[1,1],"13":[0,1]},"meta":{"lastBranch":14,"lastFunction":5,"lastStatement":60,"seen":{"s:24:43:24:Infinity":0,"s:25:32:25:Infinity":1,"f:33:16:33:34":0,"b:33:53:33:81":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":1,"s:34:2:34:Infinity":2,"s:34:33:34:Infinity":3,"s:35:19:35:Infinity":4,"b:36:2:40:Infinity:undefined:undefined:undefined:undefined":2,"s:36:2:40:Infinity":5,"s:37:4:37:Infinity":6,"s:38:4:38:Infinity":7,"s:39:4:39:Infinity":8,"s:41:2:61:Infinity":9,"s:42:17:42:Infinity":10,"b:43:4:58:Infinity:45:11:58:Infinity":3,"s:43:4:58:Infinity":11,"b:43:8:43:43:43:43:43:73":4,"s:44:6:44:Infinity":12,"s:46:19:46:Infinity":13,"s:47:32:47:Infinity":14,"s:48:6:56:Infinity":15,"b:49:8:49:Infinity:undefined:undefined:undefined:undefined":5,"s:49:8:49:Infinity":16,"s:49:38:49:Infinity":17,"s:50:24:50:Infinity":18,"b:51:8:51:Infinity:undefined:undefined:undefined:undefined":6,"s:51:8:51:Infinity":19,"s:51:34:51:Infinity":20,"s:52:20:52:Infinity":21,"b:53:8:53:Infinity:undefined:undefined:undefined:undefined":7,"s:53:8:53:Infinity":22,"s:53:27:53:Infinity":23,"s:54:8:54:Infinity":24,"s:55:8:55:Infinity":25,"s:57:6:57:Infinity":26,"b:57:49:57:59:57:59:57:Infinity":8,"s:60:4:60:Infinity":27,"s:62:2:62:Infinity":28,"s:63:2:63:Infinity":29,"f:67:16:67:48":1,"s:68:2:68:Infinity":30,"s:69:2:69:Infinity":31,"f:76:16:76:Infinity":2,"s:80:59:80:Infinity":32,"s:81:16:81:Infinity":33,"s:82:2:94:Infinity":34,"s:83:20:83:Infinity":35,"b:84:4:84:Infinity:undefined:undefined:undefined:undefined":9,"s:84:4:84:Infinity":36,"s:84:30:84:Infinity":37,"s:85:19:85:Infinity":38,"s:86:14:86:Infinity":39,"s:87:4:93:Infinity":40,"s:88:20:88:Infinity":41,"s:89:18:89:Infinity":42,"s:90:22:90:Infinity":43,"s:91:6:91:Infinity":44,"s:92:6:92:Infinity":45,"s:95:2:95:Infinity":46,"f:101:16:101:35":3,"s:102:34:102:Infinity":47,"s:103:24:103:Infinity":48,"b:104:2:111:Infinity:undefined:undefined:undefined:undefined":10,"s:104:2:111:Infinity":49,"s:105:4:109:Infinity":50,"s:110:4:110:Infinity":51,"b:112:2:112:Infinity:undefined:undefined:undefined:undefined":11,"s:112:2:112:Infinity":52,"s:112:34:112:Infinity":53,"s:113:15:113:Infinity":54,"b:114:2:121:Infinity:undefined:undefined:undefined:undefined":12,"s:114:2:121:Infinity":55,"s:115:19:115:Infinity":56,"f:115:36:115:41":4,"s:115:47:115:62":57,"s:116:4:120:Infinity":58,"b:119:95:119:103:119:103:119:106":13,"s:122:2:122:Infinity":59}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/bluf.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/bluf.ts","statementMap":{"0":{"start":{"line":16,"column":36},"end":{"line":16,"column":null}},"1":{"start":{"line":17,"column":36},"end":{"line":17,"column":null}},"2":{"start":{"line":33,"column":41},"end":{"line":33,"column":null}},"3":{"start":{"line":43,"column":12},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":44,"column":10},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"7":{"start":{"line":45,"column":52},"end":{"line":45,"column":60}},"8":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"9":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"10":{"start":{"line":62,"column":29},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":14},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":2},"end":{"line":74,"column":null}},"13":{"start":{"line":72,"column":20},"end":{"line":72,"column":null}},"14":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"15":{"start":{"line":73,"column":17},"end":{"line":73,"column":null}},"16":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"17":{"start":{"line":82,"column":15},"end":{"line":82,"column":null}},"18":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"19":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"20":{"start":{"line":84,"column":34},"end":{"line":84,"column":null}},"21":{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},"22":{"start":{"line":86,"column":4},"end":{"line":90,"column":null}},"23":{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},"24":{"start":{"line":93,"column":4},"end":{"line":97,"column":null}},"25":{"start":{"line":99,"column":18},"end":{"line":99,"column":null}},"26":{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},"27":{"start":{"line":101,"column":4},"end":{"line":105,"column":null}},"28":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}}},"fnMap":{"0":{"name":"extractBluf","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":28}},"loc":{"start":{"line":42,"column":60},"end":{"line":47,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":41},"end":{"line":45,"column":46}},"loc":{"start":{"line":45,"column":52},"end":{"line":45,"column":60}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":45,"column":62},"end":{"line":45,"column":68}},"loc":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"line":45},"3":{"name":"countBlufEvidenceAnchors","decl":{"start":{"line":61,"column":16},"end":{"line":61,"column":41}},"loc":{"start":{"line":61,"column":63},"end":{"line":76,"column":null}},"line":61},"4":{"name":"checkBluf","decl":{"start":{"line":81,"column":16},"end":{"line":81,"column":26}},"loc":{"start":{"line":81,"column":73},"end":{"line":108,"column":null}},"line":81}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"type":"binary-expr","locations":[{"start":{"line":45,"column":74},"end":{"line":45,"column":90}},{"start":{"line":45,"column":90},"end":{"line":45,"column":109}}],"line":45},"2":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":9},"end":{"line":46,"column":22}},{"start":{"line":46,"column":22},"end":{"line":46,"column":null}}],"line":46},"3":{"loc":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"4":{"loc":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},{"start":{},"end":{}}],"line":83},"5":{"loc":{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":85},"6":{"loc":{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":92},"7":{"loc":{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":100}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":2,"6":10,"7":10,"8":10,"9":10,"10":14,"11":14,"12":14,"13":84,"14":84,"15":15,"16":14,"17":5,"18":5,"19":1,"20":4,"21":4,"22":1,"23":4,"24":1,"25":4,"26":4,"27":1,"28":4},"f":{"0":12,"1":10,"2":10,"3":14,"4":5},"b":{"0":[2,10],"1":[10,10],"2":[10,3],"3":[15,69],"4":[1,4],"5":[1,3],"6":[1,3],"7":[1,3]},"meta":{"lastBranch":8,"lastFunction":5,"lastStatement":29,"seen":{"s:16:36:16:Infinity":0,"s:17:36:17:Infinity":1,"s:33:41:33:Infinity":2,"f:42:16:42:28":0,"s:43:12:43:Infinity":3,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:44:Infinity":4,"s:44:10:44:Infinity":5,"s:45:20:45:Infinity":6,"f:45:41:45:46":1,"s:45:52:45:60":7,"f:45:62:45:68":2,"s:45:74:45:109":8,"b:45:74:45:90:45:90:45:109":1,"s:46:2:46:Infinity":9,"b:46:9:46:22:46:22:46:Infinity":2,"f:61:16:61:41":3,"s:62:29:69:Infinity":10,"s:70:14:70:Infinity":11,"s:71:2:74:Infinity":12,"s:72:20:72:Infinity":13,"b:73:4:73:Infinity:undefined:undefined:undefined:undefined":3,"s:73:4:73:Infinity":14,"s:73:17:73:Infinity":15,"s:75:2:75:Infinity":16,"f:81:16:81:26":4,"s:82:15:82:Infinity":17,"b:83:2:83:Infinity:undefined:undefined:undefined:undefined":4,"s:83:2:83:Infinity":18,"s:83:21:83:Infinity":19,"s:84:34:84:Infinity":20,"b:85:2:91:Infinity:undefined:undefined:undefined:undefined":5,"s:85:2:91:Infinity":21,"s:86:4:90:Infinity":22,"b:92:2:98:Infinity:undefined:undefined:undefined:undefined":6,"s:92:2:98:Infinity":23,"s:93:4:97:Infinity":24,"s:99:18:99:Infinity":25,"b:100:2:106:Infinity:undefined:undefined:undefined:undefined":7,"s:100:2:106:Infinity":26,"s:101:4:105:Infinity":27,"s:107:2:107:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/citation-density.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/citation-density.ts","statementMap":{"0":{"start":{"line":22,"column":16},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"4":{"start":{"line":26,"column":13},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":2},"end":{"line":30,"column":null}},"6":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"7":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"8":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"10":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"11":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"12":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"13":{"start":{"line":35,"column":51},"end":{"line":35,"column":63}},"14":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"15":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"16":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"17":{"start":{"line":45,"column":21},"end":{"line":45,"column":null}},"18":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"19":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"20":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"21":{"start":{"line":62,"column":18},"end":{"line":62,"column":null}},"22":{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},"23":{"start":{"line":64,"column":4},"end":{"line":70,"column":null}},"24":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"25":{"start":{"line":72,"column":21},"end":{"line":72,"column":null}},"26":{"start":{"line":73,"column":18},"end":{"line":73,"column":null}},"27":{"start":{"line":74,"column":18},"end":{"line":74,"column":null}},"28":{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},"29":{"start":{"line":76,"column":4},"end":{"line":97,"column":null}},"30":{"start":{"line":77,"column":29},"end":{"line":82,"column":null}},"31":{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},"32":{"start":{"line":84,"column":27},"end":{"line":84,"column":null}},"33":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"34":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"35":{"start":{"line":89,"column":32},"end":{"line":89,"column":null}},"36":{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},"37":{"start":{"line":91,"column":12},"end":{"line":91,"column":null}},"38":{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},"39":{"start":{"line":100,"column":4},"end":{"line":106,"column":null}},"40":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}}},"fnMap":{"0":{"name":"countWords","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":27}},"loc":{"start":{"line":21,"column":49},"end":{"line":37,"column":null}},"line":21},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":37},"end":{"line":35,"column":45}},"loc":{"start":{"line":35,"column":51},"end":{"line":35,"column":63}},"line":35},"2":{"name":"computeCitationDensity","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":39}},"loc":{"start":{"line":43,"column":61},"end":{"line":48,"column":null}},"line":43},"3":{"name":"checkCitationDensity","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":60,"column":22},"end":{"line":109,"column":null}},"line":60}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"1":{"loc":{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":63,"column":6},"end":{"line":63,"column":38}},"type":"binary-expr","locations":[{"start":{"line":63,"column":6},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":38}}],"line":63},"3":{"loc":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"4":{"loc":{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":75},"5":{"loc":{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":83},"6":{"loc":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":88},"7":{"loc":{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":90},"8":{"loc":{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":99}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":13,"7":13,"8":14,"9":14,"10":14,"11":14,"12":14,"13":846,"14":14,"15":3,"16":3,"17":2,"18":1,"19":1,"20":7,"21":7,"22":7,"23":1,"24":6,"25":1,"26":5,"27":5,"28":5,"29":3,"30":3,"31":3,"32":3,"33":3,"34":3,"35":3,"36":3,"37":2,"38":5,"39":2,"40":3},"f":{"0":14,"1":846,"2":3,"3":7},"b":{"0":[2,1],"1":[1,6],"2":[7,6],"3":[1,5],"4":[3,2],"5":[3,0],"6":[3,0],"7":[2,1],"8":[2,3]},"meta":{"lastBranch":9,"lastFunction":4,"lastStatement":41,"seen":{"f:21:16:21:27":0,"s:22:16:22:Infinity":0,"s:23:2:23:Infinity":1,"s:24:2:24:Infinity":2,"s:25:2:25:Infinity":3,"s:26:13:26:Infinity":4,"s:27:2:30:Infinity":5,"s:28:4:28:Infinity":6,"s:29:4:29:Infinity":7,"s:31:2:31:Infinity":8,"s:32:2:32:Infinity":9,"s:33:2:33:Infinity":10,"s:34:2:34:Infinity":11,"s:35:16:35:Infinity":12,"f:35:37:35:45":1,"s:35:51:35:63":13,"s:36:2:36:Infinity":14,"f:43:16:43:39":2,"s:44:18:44:Infinity":15,"b:45:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:45:2:45:Infinity":16,"s:45:21:45:Infinity":17,"s:46:16:46:Infinity":18,"s:47:2:47:Infinity":19,"f:56:16:56:Infinity":3,"s:61:20:61:Infinity":20,"s:62:18:62:Infinity":21,"b:63:2:71:Infinity:undefined:undefined:undefined:undefined":1,"s:63:2:71:Infinity":22,"b:63:6:63:23:63:23:63:38":2,"s:64:4:70:Infinity":23,"b:72:2:72:Infinity:undefined:undefined:undefined:undefined":3,"s:72:2:72:Infinity":24,"s:72:21:72:Infinity":25,"s:73:18:73:Infinity":26,"s:74:18:74:Infinity":27,"b:75:2:98:Infinity:undefined:undefined:undefined:undefined":4,"s:75:2:98:Infinity":28,"s:76:4:97:Infinity":29,"s:77:29:82:Infinity":30,"b:83:6:94:Infinity:undefined:undefined:undefined:undefined":5,"s:83:6:94:Infinity":31,"s:84:27:84:Infinity":32,"s:87:27:87:Infinity":33,"b:88:8:93:Infinity:undefined:undefined:undefined:undefined":6,"s:88:8:93:Infinity":34,"s:89:32:89:Infinity":35,"b:90:10:92:Infinity:undefined:undefined:undefined:undefined":7,"s:90:10:92:Infinity":36,"s:91:12:91:Infinity":37,"b:99:2:107:Infinity:undefined:undefined:undefined:undefined":8,"s:99:2:107:Infinity":38,"s:100:4:106:Infinity":39,"s:108:2:108:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/evidence-anchors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/evidence-anchors.ts","statementMap":{"0":{"start":{"line":23,"column":29},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"5":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"countArticleEvidenceAnchors","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":44}},"loc":{"start":{"line":22,"column":66},"end":{"line":37,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34}},"s":{"0":12,"1":12,"2":12,"3":60,"4":60,"5":9,"6":12},"f":{"0":12},"b":{"0":[9,51]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:22:16:22:44":0,"s:23:29:30:Infinity":0,"s:31:14:31:Infinity":1,"s:32:2:35:Infinity":2,"s:33:20:33:Infinity":3,"b:34:4:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:4:34:Infinity":4,"s:34:17:34:Infinity":5,"s:36:2:36:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/footer.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/footer.ts","statementMap":{"0":{"start":{"line":30,"column":89},"end":{"line":37,"column":null}},"1":{"start":{"line":43,"column":34},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":56,"column":null}},"3":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},"5":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},"7":{"start":{"line":49,"column":8},"end":{"line":53,"column":null}},"8":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"checkFooterMarkers","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":35}},"loc":{"start":{"line":42,"column":82},"end":{"line":58,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":20},"end":{"line":45,"column":50}},{"start":{"line":45,"column":50},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":46},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":48}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":2,"6":2,"7":1,"8":2},"f":{"0":2},"b":{"0":[12,10],"1":[2,10],"2":[1,1]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":9,"seen":{"s:30:89:37:Infinity":0,"f:42:16:42:35":0,"s:43:34:43:Infinity":1,"s:44:2:56:Infinity":2,"s:45:20:45:Infinity":3,"b:45:20:45:50:45:50:45:Infinity":0,"b:46:4:55:Infinity:undefined:undefined:undefined:undefined":1,"s:46:4:55:Infinity":4,"s:47:21:47:Infinity":5,"b:48:6:54:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:54:Infinity":6,"s:49:8:53:Infinity":7,"s:57:2:57:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/landmarks.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/landmarks.ts","statementMap":{"0":{"start":{"line":28,"column":5},"end":{"line":49,"column":null}},"1":{"start":{"line":55,"column":34},"end":{"line":55,"column":null}},"2":{"start":{"line":56,"column":2},"end":{"line":64,"column":null}},"3":{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},"4":{"start":{"line":58,"column":6},"end":{"line":62,"column":null}},"5":{"start":{"line":65,"column":23},"end":{"line":65,"column":null}},"6":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"7":{"start":{"line":67,"column":4},"end":{"line":71,"column":null}},"8":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"9":{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},"10":{"start":{"line":76,"column":18},"end":{"line":76,"column":null}},"11":{"start":{"line":77,"column":17},"end":{"line":77,"column":null}},"12":{"start":{"line":78,"column":19},"end":{"line":78,"column":null}},"13":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"14":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":81,"column":6},"end":{"line":85,"column":null}},"16":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}}},"fnMap":{"0":{"name":"checkLandmarks","decl":{"start":{"line":54,"column":16},"end":{"line":54,"column":31}},"loc":{"start":{"line":54,"column":78},"end":{"line":89,"column":null}},"line":54}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":57},"1":{"loc":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":66},"2":{"loc":{"start":{"line":66,"column":6},"end":{"line":66,"column":47}},"type":"binary-expr","locations":[{"start":{"line":66,"column":6},"end":{"line":66,"column":22}},{"start":{"line":66,"column":22},"end":{"line":66,"column":47}}],"line":66},"3":{"loc":{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":75},"4":{"loc":{"start":{"line":75,"column":6},"end":{"line":75,"column":66}},"type":"binary-expr","locations":[{"start":{"line":75,"column":6},"end":{"line":75,"column":27}},{"start":{"line":75,"column":27},"end":{"line":75,"column":66}}],"line":75},"5":{"loc":{"start":{"line":78,"column":19},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":33},"end":{"line":78,"column":41}},{"start":{"line":78,"column":41},"end":{"line":78,"column":null}}],"line":78},"6":{"loc":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":21},"end":{"line":79,"column":68}},{"start":{"line":79,"column":68},"end":{"line":79,"column":null}}],"line":79},"7":{"loc":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":80}},"s":{"0":2,"1":4,"2":4,"3":16,"4":4,"5":4,"6":4,"7":1,"8":4,"9":4,"10":3,"11":3,"12":3,"13":3,"14":3,"15":2,"16":4},"f":{"0":4},"b":{"0":[4,12],"1":[1,3],"2":[4,3],"3":[3,1],"4":[4,3],"5":[0,3],"6":[3,2],"7":[2,1]},"meta":{"lastBranch":8,"lastFunction":1,"lastStatement":17,"seen":{"s:28:5:49:Infinity":0,"f:54:16:54:31":0,"s:55:34:55:Infinity":1,"s:56:2:64:Infinity":2,"b:57:4:63:Infinity:undefined:undefined:undefined:undefined":0,"s:57:4:63:Infinity":3,"s:58:6:62:Infinity":4,"s:65:23:65:Infinity":5,"b:66:2:72:Infinity:undefined:undefined:undefined:undefined":1,"s:66:2:72:Infinity":6,"b:66:6:66:22:66:22:66:47":2,"s:67:4:71:Infinity":7,"s:74:28:74:Infinity":8,"b:75:2:87:Infinity:undefined:undefined:undefined:undefined":3,"s:75:2:87:Infinity":9,"b:75:6:75:27:75:27:75:66":4,"s:76:18:76:Infinity":10,"s:77:17:77:Infinity":11,"s:78:19:78:Infinity":12,"b:78:33:78:41:78:41:78:Infinity":5,"s:79:21:79:Infinity":13,"b:79:21:79:68:79:68:79:Infinity":6,"b:80:4:86:Infinity:undefined:undefined:undefined:undefined":7,"s:80:4:86:Infinity":14,"s:81:6:85:Infinity":15,"s:88:2:88:Infinity":16}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/mermaid-fences.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/mermaid-fences.ts","statementMap":{"0":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"1":{"start":{"line":47,"column":38},"end":{"line":47,"column":null}},"2":{"start":{"line":48,"column":10},"end":{"line":48,"column":null}},"3":{"start":{"line":49,"column":2},"end":{"line":74,"column":null}},"4":{"start":{"line":50,"column":17},"end":{"line":50,"column":null}},"5":{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},"6":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"7":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"8":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":33},"end":{"line":55,"column":null}},"10":{"start":{"line":56,"column":6},"end":{"line":66,"column":null}},"11":{"start":{"line":57,"column":20},"end":{"line":57,"column":null}},"12":{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},"13":{"start":{"line":59,"column":10},"end":{"line":59,"column":null}},"14":{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},"15":{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},"16":{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},"17":{"start":{"line":64,"column":10},"end":{"line":64,"column":null}},"18":{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},"19":{"start":{"line":68,"column":8},"end":{"line":68,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"22":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"23":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"24":{"start":{"line":84,"column":18},"end":{"line":84,"column":null}},"25":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"26":{"start":{"line":92,"column":19},"end":{"line":92,"column":null}},"27":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"28":{"start":{"line":93,"column":29},"end":{"line":93,"column":null}},"29":{"start":{"line":94,"column":17},"end":{"line":94,"column":null}},"30":{"start":{"line":94,"column":49},"end":{"line":94,"column":71}},"31":{"start":{"line":95,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"findUnclosedMermaidFences","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":42}},"loc":{"start":{"line":45,"column":89},"end":{"line":76,"column":null}},"line":45},"1":{"name":"countMermaidOpenings","decl":{"start":{"line":83,"column":16},"end":{"line":83,"column":37}},"loc":{"start":{"line":83,"column":59},"end":{"line":86,"column":null}},"line":83},"2":{"name":"checkUnclosedMermaidFences","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":43}},"loc":{"start":{"line":91,"column":90},"end":{"line":102,"column":null}},"line":91},"3":{"name":"(anonymous_3)","decl":{"start":{"line":94,"column":38},"end":{"line":94,"column":43}},"loc":{"start":{"line":94,"column":49},"end":{"line":94,"column":71}},"line":94}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":51},"1":{"loc":{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":58},"2":{"loc":{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":67},"4":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":33},"end":{"line":70,"column":37}},{"start":{"line":70,"column":37},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":85,"column":9},"end":{"line":85,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":19},"end":{"line":85,"column":36}},{"start":{"line":85,"column":36},"end":{"line":85,"column":null}}],"line":85},"6":{"loc":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":93},"7":{"loc":{"start":{"line":99,"column":88},"end":{"line":99,"column":121}},"type":"cond-expr","locations":[{"start":{"line":99,"column":110},"end":{"line":99,"column":118}},{"start":{"line":99,"column":118},"end":{"line":99,"column":121}}],"line":99}},"s":{"0":6,"1":6,"2":6,"3":6,"4":13,"5":13,"6":10,"7":10,"8":10,"9":10,"10":10,"11":32,"12":32,"13":5,"14":5,"15":27,"16":3,"17":3,"18":10,"19":5,"20":10,"21":10,"22":3,"23":6,"24":4,"25":4,"26":2,"27":2,"28":1,"29":1,"30":1,"31":1},"f":{"0":6,"1":4,"2":2,"3":1},"b":{"0":[10,3],"1":[5,27],"2":[3,24],"3":[5,5],"4":[3,7],"5":[2,2],"6":[1,1],"7":[0,1]},"meta":{"lastBranch":8,"lastFunction":4,"lastStatement":32,"seen":{"f:45:16:45:42":0,"s:46:16:46:Infinity":0,"s:47:38:47:Infinity":1,"s:48:10:48:Infinity":2,"s:49:2:74:Infinity":3,"s:50:17:50:Infinity":4,"b:51:4:72:Infinity:undefined:undefined:undefined:undefined":0,"s:51:4:72:Infinity":5,"s:52:23:52:Infinity":6,"s:53:14:53:Infinity":7,"s:54:19:54:Infinity":8,"s:55:33:55:Infinity":9,"s:56:6:66:Infinity":10,"s:57:20:57:Infinity":11,"b:58:8:61:Infinity:undefined:undefined:undefined:undefined":1,"s:58:8:61:Infinity":12,"s:59:10:59:Infinity":13,"s:60:10:60:Infinity":14,"b:62:8:65:Infinity:undefined:undefined:undefined:undefined":2,"s:62:8:65:Infinity":15,"s:63:10:63:Infinity":16,"s:64:10:64:Infinity":17,"b:67:6:69:Infinity:undefined:undefined:undefined:undefined":3,"s:67:6:69:Infinity":18,"s:68:8:68:Infinity":19,"s:70:6:70:Infinity":20,"b:70:33:70:37:70:37:70:Infinity":4,"s:71:6:71:Infinity":21,"s:73:4:73:Infinity":22,"s:75:2:75:Infinity":23,"f:83:16:83:37":1,"s:84:18:84:Infinity":24,"s:85:2:85:Infinity":25,"b:85:19:85:36:85:36:85:Infinity":5,"f:91:16:91:43":2,"s:92:19:92:Infinity":26,"b:93:2:93:Infinity:undefined:undefined:undefined:undefined":6,"s:93:2:93:Infinity":27,"s:93:29:93:Infinity":28,"s:94:17:94:Infinity":29,"f:94:38:94:43":3,"s:94:49:94:71":30,"s:95:2:101:Infinity":31,"b:99:110:99:118:99:118:99:121":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/per-document.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/per-document.ts","statementMap":{"0":{"start":{"line":16,"column":39},"end":{"line":16,"column":null}},"1":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":27,"column":43},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":15},"end":{"line":28,"column":null}},"5":{"start":{"line":29,"column":15},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"7":{"start":{"line":31,"column":56},"end":{"line":31,"column":null}},"8":{"start":{"line":33,"column":25},"end":{"line":33,"column":null}},"9":{"start":{"line":34,"column":15},"end":{"line":34,"column":null}},"10":{"start":{"line":35,"column":10},"end":{"line":35,"column":null}},"11":{"start":{"line":36,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":37,"column":15},"end":{"line":37,"column":null}},"13":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"14":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"15":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"16":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"17":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"18":{"start":{"line":42,"column":43},"end":{"line":42,"column":null}},"19":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"20":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"21":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"22":{"start":{"line":50,"column":31},"end":{"line":50,"column":null}},"23":{"start":{"line":56,"column":34},"end":{"line":56,"column":null}},"24":{"start":{"line":57,"column":2},"end":{"line":66,"column":null}},"25":{"start":{"line":58,"column":17},"end":{"line":58,"column":null}},"26":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"27":{"start":{"line":60,"column":6},"end":{"line":64,"column":null}},"28":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}}},"fnMap":{"0":{"name":"extractPerDocumentSections","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":43}},"loc":{"start":{"line":25,"column":97},"end":{"line":47,"column":null}},"line":25},"1":{"name":"checkPerDocument","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":33}},"loc":{"start":{"line":55,"column":80},"end":{"line":68,"column":null}},"line":55}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},{"start":{},"end":{}}],"line":27},"1":{"loc":{"start":{"line":27,"column":6},"end":{"line":27,"column":43}},"type":"binary-expr","locations":[{"start":{"line":27,"column":6},"end":{"line":27,"column":16}},{"start":{"line":27,"column":16},"end":{"line":27,"column":43}}],"line":27},"2":{"loc":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":31},"end":{"line":30,"column":38}},{"start":{"line":30,"column":38},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":36,"column":9},"end":{"line":36,"column":37}},"type":"binary-expr","locations":[{"start":{"line":36,"column":9},"end":{"line":36,"column":14}},{"start":{"line":36,"column":14},"end":{"line":36,"column":37}}],"line":36},"4":{"loc":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":52},"end":{"line":40,"column":81}},{"start":{"line":40,"column":81},"end":{"line":40,"column":null}}],"line":40},"5":{"loc":{"start":{"line":40,"column":17},"end":{"line":40,"column":52}},"type":"binary-expr","locations":[{"start":{"line":40,"column":17},"end":{"line":40,"column":25}},{"start":{"line":40,"column":25},"end":{"line":40,"column":52}}],"line":40},"6":{"loc":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":42},"7":{"loc":{"start":{"line":42,"column":8},"end":{"line":42,"column":43}},"type":"binary-expr","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":17}},{"start":{"line":42,"column":17},"end":{"line":42,"column":43}}],"line":42},"8":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":80}},{"start":{"line":58,"column":80},"end":{"line":58,"column":null}}],"line":58},"9":{"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":59}},"s":{"0":2,"1":2,"2":2,"3":0,"4":2,"5":2,"6":2,"7":2,"8":2,"9":2,"10":2,"11":2,"12":3,"13":3,"14":3,"15":3,"16":3,"17":3,"18":2,"19":1,"20":1,"21":2,"22":2,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1},"f":{"0":2,"1":1},"b":{"0":[0,2],"1":[2,2],"2":[1,1],"3":[2,3],"4":[1,2],"5":[3,1],"6":[2,1],"7":[3,1],"8":[1,1],"9":[1,0]},"meta":{"lastBranch":10,"lastFunction":2,"lastStatement":29,"seen":{"s:16:39:16:Infinity":0,"f:25:16:25:43":0,"s:26:16:26:Infinity":1,"b:27:2:27:Infinity:undefined:undefined:undefined:undefined":0,"s:27:2:27:Infinity":2,"b:27:6:27:16:27:16:27:43":1,"s:27:43:27:Infinity":3,"s:28:15:28:Infinity":4,"s:29:15:29:Infinity":5,"s:30:17:30:Infinity":6,"b:30:31:30:38:30:38:30:Infinity":2,"s:31:56:31:Infinity":7,"s:33:25:33:Infinity":8,"s:34:15:34:Infinity":9,"s:35:10:35:Infinity":10,"s:36:2:45:Infinity":11,"b:36:9:36:14:36:14:36:37":3,"s:37:15:37:Infinity":12,"s:38:18:38:Infinity":13,"s:39:17:39:Infinity":14,"s:40:17:40:Infinity":15,"b:40:52:40:81:40:81:40:Infinity":4,"b:40:17:40:25:40:25:40:52":5,"s:41:4:41:Infinity":16,"b:42:4:42:Infinity:undefined:undefined:undefined:undefined":6,"s:42:4:42:Infinity":17,"b:42:8:42:17:42:17:42:43":7,"s:42:43:42:Infinity":18,"s:43:4:43:Infinity":19,"s:44:4:44:Infinity":20,"s:46:2:46:Infinity":21,"s:50:31:50:Infinity":22,"f:55:16:55:33":1,"s:56:34:56:Infinity":23,"s:57:2:66:Infinity":24,"s:58:17:58:Infinity":25,"b:58:17:58:80:58:80:58:Infinity":8,"b:59:4:65:Infinity:undefined:undefined:undefined:undefined":9,"s:59:4:65:Infinity":26,"s:60:6:64:Infinity":27,"s:67:2:67:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/placeholders.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/placeholders.ts","statementMap":{"0":{"start":{"line":24,"column":55},"end":{"line":30,"column":null}},"1":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":2},"end":{"line":38,"column":null}},"3":{"start":{"line":36,"column":14},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"5":{"start":{"line":37,"column":11},"end":{"line":37,"column":null}},"6":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"7":{"start":{"line":46,"column":34},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":56,"column":null}},"9":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},"11":{"start":{"line":50,"column":6},"end":{"line":54,"column":null}},"12":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"scanPlaceholders","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":33}},"loc":{"start":{"line":33,"column":57},"end":{"line":40,"column":null}},"line":33},"1":{"name":"checkPlaceholders","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":34}},"loc":{"start":{"line":45,"column":81},"end":{"line":58,"column":null}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":49}},"s":{"0":2,"1":1,"2":1,"3":5,"4":5,"5":2,"6":1,"7":2,"8":2,"9":10,"10":10,"11":2,"12":2},"f":{"0":1,"1":2},"b":{"0":[2,3],"1":[2,8]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":13,"seen":{"s:24:55:30:Infinity":0,"f:33:16:33:33":0,"s:34:25:34:Infinity":1,"s:35:2:38:Infinity":2,"s:36:14:36:Infinity":3,"b:37:4:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:37:Infinity":4,"s:37:11:37:Infinity":5,"s:39:2:39:Infinity":6,"f:45:16:45:34":1,"s:46:34:46:Infinity":7,"s:47:2:56:Infinity":8,"s:48:14:48:Infinity":9,"b:49:4:55:Infinity:undefined:undefined:undefined:undefined":1,"s:49:4:55:Infinity":10,"s:50:6:54:Infinity":11,"s:57:2:57:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/stale-provenance.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/stale-provenance.ts","statementMap":{"0":{"start":{"line":34,"column":67},"end":{"line":34,"column":null}},"1":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"2":{"start":{"line":37,"column":2},"end":{"line":51,"column":null}},"3":{"start":{"line":38,"column":20},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},"8":{"start":{"line":43,"column":24},"end":{"line":43,"column":null}},"9":{"start":{"line":44,"column":26},"end":{"line":44,"column":null}},"10":{"start":{"line":45,"column":28},"end":{"line":45,"column":null}},"11":{"start":{"line":46,"column":23},"end":{"line":46,"column":null}},"12":{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},"13":{"start":{"line":48,"column":8},"end":{"line":48,"column":null}},"14":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"15":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"16":{"start":{"line":59,"column":39},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":16},"end":{"line":60,"column":null}},"18":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"19":{"start":{"line":61,"column":26},"end":{"line":61,"column":null}},"20":{"start":{"line":62,"column":17},"end":{"line":62,"column":null}},"21":{"start":{"line":62,"column":46},"end":{"line":62,"column":83}},"22":{"start":{"line":63,"column":2},"end":{"line":69,"column":null}}},"fnMap":{"0":{"name":"scanStaleProvenance","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"loc":{"start":{"line":33,"column":53},"end":{"line":53,"column":null}},"line":33},"1":{"name":"checkStaleProvenance","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":37}},"loc":{"start":{"line":58,"column":84},"end":{"line":70,"column":null}},"line":58},"2":{"name":"(anonymous_2)","decl":{"start":{"line":62,"column":35},"end":{"line":62,"column":40}},"loc":{"start":{"line":62,"column":46},"end":{"line":62,"column":83}},"line":62}},"branchMap":{"0":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"default-arg","locations":[{"start":{"line":32,"column":24},"end":{"line":32,"column":null}}],"line":32},"1":{"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":42},"2":{"loc":{"start":{"line":44,"column":26},"end":{"line":44,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":42},"end":{"line":44,"column":58}},{"start":{"line":44,"column":58},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":47},"4":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":61}},"s":{"0":8,"1":8,"2":8,"3":10,"4":10,"5":10,"6":10,"7":10,"8":8,"9":8,"10":8,"11":8,"12":8,"13":6,"14":8,"15":5,"16":1,"17":4,"18":4,"19":4,"20":2,"21":3,"22":2},"f":{"0":8,"1":5,"2":3},"b":{"0":[8],"1":[8,2],"2":[7,1],"3":[6,2],"4":[1,4],"5":[2,2]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":23,"seen":{"f:30:16:30:Infinity":0,"b:32:24:32:Infinity":0,"s:34:67:34:Infinity":0,"s:35:17:35:Infinity":1,"s:37:2:51:Infinity":2,"s:38:20:38:Infinity":3,"s:39:22:39:Infinity":4,"s:40:19:40:Infinity":5,"s:41:23:41:Infinity":6,"b:42:4:50:Infinity:undefined:undefined:undefined:undefined":1,"s:42:4:50:Infinity":7,"s:43:24:43:Infinity":8,"s:44:26:44:Infinity":9,"b:44:42:44:58:44:58:44:Infinity":2,"s:45:28:45:Infinity":10,"s:46:23:46:Infinity":11,"b:47:6:49:Infinity:undefined:undefined:undefined:undefined":3,"s:47:6:49:Infinity":12,"s:48:8:48:Infinity":13,"s:52:2:52:Infinity":14,"f:58:16:58:37":1,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":4,"s:59:2:59:Infinity":15,"s:59:39:59:Infinity":16,"s:60:16:60:Infinity":17,"b:61:2:61:Infinity:undefined:undefined:undefined:undefined":5,"s:61:2:61:Infinity":18,"s:61:26:61:Infinity":19,"s:62:17:62:Infinity":20,"f:62:35:62:40":2,"s:62:46:62:83":21,"s:63:2:69:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/slug.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/slug.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":20,"column":null}},"1":{"start":{"line":27,"column":34},"end":{"line":27,"column":null}},"2":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"3":{"start":{"line":29,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":30,"column":24},"end":{"line":30,"column":null}},"5":{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},"6":{"start":{"line":32,"column":6},"end":{"line":36,"column":null}},"7":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}}},"fnMap":{"0":{"name":"permissiveSlug","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":31}},"loc":{"start":{"line":16,"column":56},"end":{"line":21,"column":null}},"line":16},"1":{"name":"checkHeadingSlugs","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":34}},"loc":{"start":{"line":26,"column":81},"end":{"line":40,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"type":"binary-expr","locations":[{"start":{"line":28,"column":23},"end":{"line":28,"column":62}},{"start":{"line":28,"column":62},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":31}},"s":{"0":6,"1":2,"2":2,"3":2,"4":2,"5":2,"6":1,"7":2},"f":{"0":6,"1":2},"b":{"0":[2,0],"1":[1,1]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":8,"seen":{"f:16:16:16:31":0,"s:17:2:20:Infinity":0,"f:26:16:26:34":1,"s:27:34:27:Infinity":1,"s:28:23:28:Infinity":2,"b:28:23:28:62:28:62:28:Infinity":0,"s:29:2:38:Infinity":3,"s:30:24:30:Infinity":4,"b:31:4:37:Infinity:undefined:undefined:undefined:undefined":1,"s:31:4:37:Infinity":5,"s:32:6:36:Infinity":6,"s:39:2:39:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/types.ts","statementMap":{"0":{"start":{"line":18,"column":25},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":2},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:25:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/headings.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/headings.ts","statementMap":{"0":{"start":{"line":18,"column":19},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":16},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":29},"end":{"line":20,"column":51}}},"fnMap":{"0":{"name":"countHeadings","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":50},"end":{"line":21,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":15},"end":{"line":20,"column":23}},"loc":{"start":{"line":20,"column":29},"end":{"line":20,"column":51}},"line":20}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":575},"f":{"0":23,"1":575},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":4,"seen":{"f:17:16:17:30":0,"s:18:19:18:Infinity":0,"s:19:16:19:Infinity":1,"s:20:2:20:Infinity":2,"f:20:15:20:23":1,"s:20:29:20:51":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/code-fences.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/code-fences.ts","statementMap":{"0":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"2":{"start":{"line":16,"column":32},"end":{"line":16,"column":null}},"3":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}}},"fnMap":{"0":{"name":"countCodeFences","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":32}},"loc":{"start":{"line":14,"column":52},"end":{"line":19,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"type":"binary-expr","locations":[{"start":{"line":15,"column":18},"end":{"line":15,"column":40}},{"start":{"line":15,"column":40},"end":{"line":15,"column":null}}],"line":15},"1":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"if","locations":[{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},{"start":{},"end":{}}],"line":16}},"s":{"0":24,"1":24,"2":2,"3":22},"f":{"0":24},"b":{"0":[24,0],"1":[2,22]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":4,"seen":{"f:14:16:14:32":0,"s:15:18:15:Infinity":0,"b:15:18:15:40:15:40:15:Infinity":0,"b:16:2:16:Infinity:undefined:undefined:undefined:undefined":1,"s:16:2:16:Infinity":1,"s:16:32:16:Infinity":2,"s:18:2:18:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/mermaid-blocks.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/mermaid-blocks.ts","statementMap":{"0":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}}},"fnMap":{"0":{"name":"countMermaidBlocks","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":35}},"loc":{"start":{"line":14,"column":55},"end":{"line":17,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":16,"column":9},"end":{"line":16,"column":null}},"type":"cond-expr","locations":[{"start":{"line":16,"column":19},"end":{"line":16,"column":36}},{"start":{"line":16,"column":36},"end":{"line":16,"column":null}}],"line":16}},"s":{"0":23,"1":23},"f":{"0":23},"b":{"0":[23,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":2,"seen":{"f:14:16:14:35":0,"s:15:18:15:Infinity":0,"s:16:2:16:Infinity":1,"b:16:19:16:36:16:36:16:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/table-rows.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/table-rows.ts","statementMap":{"0":{"start":{"line":18,"column":19},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":16},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":29},"end":{"line":20,"column":53}}},"fnMap":{"0":{"name":"countTableRows","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":31}},"loc":{"start":{"line":17,"column":51},"end":{"line":21,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":15},"end":{"line":20,"column":23}},"loc":{"start":{"line":20,"column":29},"end":{"line":20,"column":53}},"line":20}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":575},"f":{"0":23,"1":575},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":4,"seen":{"f:17:16:17:31":0,"s:18:19:18:Infinity":0,"s:19:16:19:Infinity":1,"s:20:2:20:Infinity":2,"f:20:15:20:23":1,"s:20:29:20:53":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/words.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/words.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"2":{"start":{"line":25,"column":45},"end":{"line":25,"column":67}}},"fnMap":{"0":{"name":"countWords","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":27}},"loc":{"start":{"line":23,"column":47},"end":{"line":26,"column":null}},"line":23},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":31},"end":{"line":25,"column":39}},"loc":{"start":{"line":25,"column":45},"end":{"line":25,"column":67}},"line":25}},"branchMap":{},"s":{"0":19,"1":19,"2":1143},"f":{"0":19,"1":1143},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":3,"seen":{"f:23:16:23:27":0,"s:24:19:24:Infinity":0,"s:25:2:25:Infinity":1,"f:25:31:25:39":1,"s:25:45:25:67":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/dok-ids.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/dok-ids.ts","statementMap":{"0":{"start":{"line":19,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"2":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"3":{"start":{"line":26,"column":42},"end":{"line":26,"column":57}}},"fnMap":{"0":{"name":"extractDokIds","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":30}},"loc":{"start":{"line":18,"column":55},"end":{"line":27,"column":null}},"line":18},"1":{"name":"(anonymous_1)","decl":{"start":{"line":26,"column":28},"end":{"line":26,"column":36}},"loc":{"start":{"line":26,"column":42},"end":{"line":26,"column":57}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"type":"binary-expr","locations":[{"start":{"line":25,"column":21},"end":{"line":25,"column":66}},{"start":{"line":25,"column":66},"end":{"line":25,"column":null}}],"line":25}},"s":{"0":24,"1":24,"2":24,"3":66},"f":{"0":24,"1":66},"b":{"0":[24,3]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":4,"seen":{"f:18:16:18:30":0,"s:19:19:19:Infinity":0,"s:25:21:25:Infinity":1,"b:25:21:25:66:25:66:25:Infinity":0,"s:26:2:26:Infinity":2,"f:26:28:26:36":1,"s:26:42:26:57":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/source-sha.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/source-sha.ts","statementMap":{"0":{"start":{"line":16,"column":16},"end":{"line":16,"column":null}},"1":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"2":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}}},"fnMap":{"0":{"name":"extractSourceShaMarker","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":39}},"loc":{"start":{"line":15,"column":66},"end":{"line":18,"column":null}},"line":15},"1":{"name":"hasRtlMarker","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":29}},"loc":{"start":{"line":21,"column":50},"end":{"line":23,"column":null}},"line":21}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":9},"end":{"line":17,"column":null}},"type":"binary-expr","locations":[{"start":{"line":17,"column":9},"end":{"line":17,"column":23}},{"start":{"line":17,"column":23},"end":{"line":17,"column":null}}],"line":17}},"s":{"0":15,"1":15,"2":4},"f":{"0":15,"1":4},"b":{"0":[15,4]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":3,"seen":{"f:15:16:15:39":0,"s:16:16:16:Infinity":0,"s:17:2:17:Infinity":1,"b:17:9:17:23:17:23:17:Infinity":0,"f:21:16:21:29":1,"s:22:2:22:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/urls.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/urls.ts","statementMap":{"0":{"start":{"line":18,"column":15},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"4":{"start":{"line":21,"column":15},"end":{"line":21,"column":null}},"5":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"6":{"start":{"line":22,"column":24},"end":{"line":22,"column":null}},"7":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}}},"fnMap":{"0":{"name":"extractUrls","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":28}},"loc":{"start":{"line":16,"column":53},"end":{"line":24,"column":null}},"line":16}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"type":"binary-expr","locations":[{"start":{"line":19,"column":22},"end":{"line":19,"column":63}},{"start":{"line":19,"column":63},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":21,"column":15},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":15},"end":{"line":21,"column":60}},{"start":{"line":21,"column":60},"end":{"line":21,"column":null}}],"line":21}},"s":{"0":23,"1":23,"2":23,"3":20,"4":23,"5":23,"6":19,"7":23},"f":{"0":23},"b":{"0":[23,3],"1":[23,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":8,"seen":{"f:16:16:16:28":0,"s:18:15:18:Infinity":0,"s:19:22:19:Infinity":1,"b:19:22:19:63:19:63:19:Infinity":0,"s:20:2:20:Infinity":2,"s:20:31:20:Infinity":3,"s:21:15:21:Infinity":4,"b:21:15:21:60:21:60:21:Infinity":1,"s:22:2:22:Infinity":5,"s:22:24:22:Infinity":6,"s:23:2:23:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/narrative-drift.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/narrative-drift.ts","statementMap":{"0":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":24},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":18},"end":{"line":37,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":39,"column":20},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},"6":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"7":{"start":{"line":42,"column":8},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"9":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"10":{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},"11":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"12":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"13":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"14":{"start":{"line":65,"column":24},"end":{"line":65,"column":null}},"15":{"start":{"line":66,"column":21},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":20},"end":{"line":67,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"stripMermaidBlocks","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":55},"end":{"line":55,"column":null}},"line":34},"1":{"name":"isDiffMermaidOnly","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":34}},"loc":{"start":{"line":64,"column":74},"end":{"line":69,"column":null}},"line":64},"2":{"name":"normalise","decl":{"start":{"line":71,"column":9},"end":{"line":71,"column":19}},"loc":{"start":{"line":71,"column":38},"end":{"line":73,"column":null}},"line":71}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},{"start":{"line":46,"column":11},"end":{"line":52,"column":null}}],"line":40},"1":{"loc":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":41},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65}},"s":{"0":16,"1":16,"2":16,"3":16,"4":115,"5":115,"6":71,"7":15,"8":15,"9":56,"10":44,"11":15,"12":16,"13":7,"14":1,"15":6,"16":6,"17":6,"18":12},"f":{"0":16,"1":7,"2":12},"b":{"0":[71,44],"1":[15,56],"2":[15,29],"3":[1,6]},"meta":{"lastBranch":4,"lastFunction":3,"lastStatement":19,"seen":{"f:34:16:34:35":0,"s:35:16:35:Infinity":0,"s:36:24:36:Infinity":1,"s:37:18:37:Infinity":2,"s:38:2:53:Infinity":3,"s:39:20:39:Infinity":4,"b:40:4:52:Infinity:46:11:52:Infinity":0,"s:40:4:52:Infinity":5,"b:41:6:44:Infinity:undefined:undefined:undefined:undefined":1,"s:41:6:44:Infinity":6,"s:42:8:42:Infinity":7,"s:43:8:43:Infinity":8,"s:45:6:45:Infinity":9,"b:48:6:50:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:50:Infinity":10,"s:49:8:49:Infinity":11,"s:54:2:54:Infinity":12,"f:64:16:64:34":1,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:2:65:Infinity":13,"s:65:24:65:Infinity":14,"s:66:21:66:Infinity":15,"s:67:20:67:Infinity":16,"s:68:2:68:Infinity":17,"f:71:9:71:19":2,"s:72:2:72:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/rules/banned-english.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/rules/banned-english.ts","statementMap":{"0":{"start":{"line":17,"column":54},"end":{"line":29,"column":null}},"1":{"start":{"line":32,"column":64},"end":{"line":37,"column":null}},"2":{"start":{"line":41,"column":25},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":57,"column":null}},"4":{"start":{"line":43,"column":15},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":22},"end":{"line":44,"column":null}},"7":{"start":{"line":46,"column":21},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":4},"end":{"line":55,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":26},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":26},"end":{"line":50,"column":null}},"13":{"start":{"line":50,"column":73},"end":{"line":50,"column":87}},"14":{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},"15":{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},"16":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"17":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"18":{"start":{"line":56,"column":20},"end":{"line":56,"column":null}},"19":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"findBannedEnglishPhrases","decl":{"start":{"line":40,"column":16},"end":{"line":40,"column":41}},"loc":{"start":{"line":40,"column":63},"end":{"line":59,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":50,"column":59},"end":{"line":50,"column":65}},"loc":{"start":{"line":50,"column":73},"end":{"line":50,"column":87}},"line":50}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"2":{"loc":{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":51},"3":{"loc":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56}},"s":{"0":1,"1":1,"2":15,"3":15,"4":165,"5":165,"6":163,"7":2,"8":2,"9":2,"10":14,"11":12,"12":2,"13":8,"14":2,"15":2,"16":2,"17":2,"18":2,"19":15},"f":{"0":15,"1":8},"b":{"0":[163,2],"1":[12,2],"2":[2,0],"3":[2,0]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":20,"seen":{"s:17:54:29:Infinity":0,"s:32:64:37:Infinity":1,"f:40:16:40:41":0,"s:41:25:41:Infinity":2,"s:42:2:57:Infinity":3,"s:43:15:43:Infinity":4,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:4:44:Infinity":5,"s:44:22:44:Infinity":6,"s:46:21:46:Infinity":7,"s:47:21:47:Infinity":8,"s:48:4:55:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":1,"s:49:6:49:Infinity":10,"s:49:26:49:Infinity":11,"s:50:26:50:Infinity":12,"f:50:59:50:65":1,"s:50:73:50:87":13,"b:51:6:54:Infinity:undefined:undefined:undefined:undefined":2,"s:51:6:54:Infinity":14,"s:52:8:52:Infinity":15,"s:53:8:53:Infinity":16,"b:56:4:56:Infinity:undefined:undefined:undefined:undefined":3,"s:56:4:56:Infinity":17,"s:56:20:56:Infinity":18,"s:58:2:58:Infinity":19}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/strippers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/strippers.ts","statementMap":{"0":{"start":{"line":17,"column":15},"end":{"line":17,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":24,"column":null}},"2":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":4},"end":{"line":23,"column":null}},"4":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"stripFencesAndComments","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":39}},"loc":{"start":{"line":15,"column":59},"end":{"line":26,"column":null}},"line":15}},"branchMap":{},"s":{"0":89,"1":89,"2":177,"3":177,"4":89},"f":{"0":89},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":5,"seen":{"f:15:16:15:39":0,"s:17:15:17:Infinity":0,"s:19:2:24:Infinity":1,"s:20:4:20:Infinity":2,"s:21:4:23:Infinity":3,"s:25:2:25:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/types.ts","statementMap":{"0":{"start":{"line":18,"column":33},"end":{"line":21,"column":null}},"1":{"start":{"line":25,"column":57},"end":{"line":25,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:18:33:21:Infinity":0,"s:25:57:25:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/validate-translation-content.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/validate-translation-content.ts","statementMap":{"0":{"start":{"line":42,"column":65},"end":{"line":42,"column":null}},"1":{"start":{"line":43,"column":32},"end":{"line":43,"column":null}},"2":{"start":{"line":46,"column":22},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":54,"column":null}},"5":{"start":{"line":57,"column":18},"end":{"line":57,"column":null}},"6":{"start":{"line":58,"column":18},"end":{"line":58,"column":null}},"7":{"start":{"line":59,"column":2},"end":{"line":65,"column":null}},"8":{"start":{"line":68,"column":20},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":20},"end":{"line":69,"column":null}},"10":{"start":{"line":70,"column":2},"end":{"line":76,"column":null}},"11":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"12":{"start":{"line":80,"column":21},"end":{"line":80,"column":null}},"13":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"14":{"start":{"line":90,"column":20},"end":{"line":90,"column":null}},"15":{"start":{"line":91,"column":20},"end":{"line":91,"column":null}},"16":{"start":{"line":92,"column":24},"end":{"line":92,"column":null}},"17":{"start":{"line":92,"column":54},"end":{"line":92,"column":72}},"18":{"start":{"line":93,"column":22},"end":{"line":93,"column":null}},"19":{"start":{"line":93,"column":52},"end":{"line":93,"column":70}},"20":{"start":{"line":94,"column":22},"end":{"line":94,"column":null}},"21":{"start":{"line":95,"column":2},"end":{"line":104,"column":null}},"22":{"start":{"line":107,"column":18},"end":{"line":107,"column":null}},"23":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"24":{"start":{"line":109,"column":22},"end":{"line":109,"column":null}},"25":{"start":{"line":109,"column":49},"end":{"line":109,"column":64}},"26":{"start":{"line":110,"column":20},"end":{"line":110,"column":null}},"27":{"start":{"line":110,"column":47},"end":{"line":110,"column":62}},"28":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"29":{"start":{"line":112,"column":2},"end":{"line":121,"column":null}},"30":{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},"31":{"start":{"line":125,"column":18},"end":{"line":125,"column":null}},"32":{"start":{"line":126,"column":4},"end":{"line":130,"column":null}},"33":{"start":{"line":134,"column":21},"end":{"line":134,"column":null}},"34":{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},"35":{"start":{"line":136,"column":4},"end":{"line":140,"column":null}},"36":{"start":{"line":142,"column":23},"end":{"line":142,"column":null}},"37":{"start":{"line":143,"column":4},"end":{"line":151,"column":null}},"38":{"start":{"line":155,"column":17},"end":{"line":155,"column":null}},"39":{"start":{"line":156,"column":2},"end":{"line":160,"column":null}},"40":{"start":{"line":167,"column":62},"end":{"line":167,"column":null}},"41":{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},"42":{"start":{"line":169,"column":4},"end":{"line":173,"column":null}},"43":{"start":{"line":175,"column":21},"end":{"line":175,"column":null}},"44":{"start":{"line":176,"column":21},"end":{"line":176,"column":null}},"45":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"46":{"start":{"line":178,"column":23},"end":{"line":178,"column":null}},"47":{"start":{"line":179,"column":23},"end":{"line":179,"column":null}},"48":{"start":{"line":180,"column":21},"end":{"line":180,"column":null}},"49":{"start":{"line":181,"column":4},"end":{"line":187,"column":null}},"50":{"start":{"line":190,"column":2},"end":{"line":190,"column":null}}},"fnMap":{"0":{"name":"validateTranslationContent","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":43}},"loc":{"start":{"line":41,"column":92},"end":{"line":191,"column":null}},"line":41},"1":{"name":"(anonymous_1)","decl":{"start":{"line":92,"column":39},"end":{"line":92,"column":47}},"loc":{"start":{"line":92,"column":54},"end":{"line":92,"column":72}},"line":92},"2":{"name":"(anonymous_2)","decl":{"start":{"line":93,"column":37},"end":{"line":93,"column":45}},"loc":{"start":{"line":93,"column":52},"end":{"line":93,"column":70}},"line":93},"3":{"name":"(anonymous_3)","decl":{"start":{"line":109,"column":35},"end":{"line":109,"column":43}},"loc":{"start":{"line":109,"column":49},"end":{"line":109,"column":64}},"line":109},"4":{"name":"(anonymous_4)","decl":{"start":{"line":110,"column":33},"end":{"line":110,"column":41}},"loc":{"start":{"line":110,"column":47},"end":{"line":110,"column":62}},"line":110}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":12},"end":{"line":53,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},{"start":{"line":53,"column":8},"end":{"line":53,"column":null}}],"line":51},"1":{"loc":{"start":{"line":62,"column":12},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":8},"end":{"line":63,"column":null}},{"start":{"line":64,"column":8},"end":{"line":64,"column":null}}],"line":62},"2":{"loc":{"start":{"line":73,"column":12},"end":{"line":75,"column":null}},"type":"cond-expr","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":null}},{"start":{"line":75,"column":8},"end":{"line":75,"column":null}}],"line":73},"3":{"loc":{"start":{"line":84,"column":12},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":8},"end":{"line":85,"column":null}},{"start":{"line":86,"column":8},"end":{"line":86,"column":null}}],"line":84},"4":{"loc":{"start":{"line":94,"column":22},"end":{"line":94,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":22},"end":{"line":94,"column":52}},{"start":{"line":94,"column":52},"end":{"line":94,"column":null}}],"line":94},"5":{"loc":{"start":{"line":98,"column":12},"end":{"line":103,"column":null}},"type":"cond-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},{"start":{"line":100,"column":8},"end":{"line":103,"column":null}}],"line":98},"6":{"loc":{"start":{"line":101,"column":10},"end":{"line":101,"column":null}},"type":"cond-expr","locations":[{"start":{"line":101,"column":37},"end":{"line":101,"column":78}},{"start":{"line":101,"column":78},"end":{"line":101,"column":null}}],"line":101},"7":{"loc":{"start":{"line":102,"column":10},"end":{"line":102,"column":null}},"type":"cond-expr","locations":[{"start":{"line":102,"column":35},"end":{"line":102,"column":72}},{"start":{"line":102,"column":72},"end":{"line":102,"column":null}}],"line":102},"8":{"loc":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":20},"end":{"line":111,"column":48}},{"start":{"line":111,"column":48},"end":{"line":111,"column":null}}],"line":111},"9":{"loc":{"start":{"line":115,"column":12},"end":{"line":120,"column":null}},"type":"cond-expr","locations":[{"start":{"line":116,"column":8},"end":{"line":116,"column":null}},{"start":{"line":117,"column":8},"end":{"line":120,"column":null}}],"line":115},"10":{"loc":{"start":{"line":118,"column":10},"end":{"line":118,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":35},"end":{"line":118,"column":88}},{"start":{"line":118,"column":88},"end":{"line":118,"column":null}}],"line":118},"11":{"loc":{"start":{"line":119,"column":10},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":33},"end":{"line":119,"column":77}},{"start":{"line":119,"column":77},"end":{"line":119,"column":null}}],"line":119},"12":{"loc":{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":124},"13":{"loc":{"start":{"line":129,"column":14},"end":{"line":129,"column":null}},"type":"cond-expr","locations":[{"start":{"line":129,"column":22},"end":{"line":129,"column":34}},{"start":{"line":129,"column":34},"end":{"line":129,"column":null}}],"line":129},"14":{"loc":{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},{"start":{"line":141,"column":9},"end":{"line":152,"column":null}}],"line":135},"15":{"loc":{"start":{"line":135,"column":6},"end":{"line":135,"column":53}},"type":"binary-expr","locations":[{"start":{"line":135,"column":6},"end":{"line":135,"column":28}},{"start":{"line":135,"column":28},"end":{"line":135,"column":53}}],"line":135},"16":{"loc":{"start":{"line":139,"column":14},"end":{"line":139,"column":null}},"type":"cond-expr","locations":[{"start":{"line":139,"column":27},"end":{"line":139,"column":39}},{"start":{"line":139,"column":39},"end":{"line":139,"column":null}}],"line":139},"17":{"loc":{"start":{"line":146,"column":14},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":10},"end":{"line":147,"column":null}},{"start":{"line":148,"column":10},"end":{"line":150,"column":null}}],"line":146},"18":{"loc":{"start":{"line":148,"column":10},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":149,"column":12},"end":{"line":149,"column":null}},{"start":{"line":150,"column":12},"end":{"line":150,"column":null}}],"line":148},"19":{"loc":{"start":{"line":159,"column":12},"end":{"line":159,"column":null}},"type":"cond-expr","locations":[{"start":{"line":159,"column":34},"end":{"line":159,"column":44}},{"start":{"line":159,"column":44},"end":{"line":159,"column":null}}],"line":159},"20":{"loc":{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},{"start":{"line":174,"column":9},"end":{"line":188,"column":null}}],"line":168},"21":{"loc":{"start":{"line":180,"column":21},"end":{"line":180,"column":null}},"type":"binary-expr","locations":[{"start":{"line":180,"column":21},"end":{"line":180,"column":47}},{"start":{"line":180,"column":47},"end":{"line":180,"column":null}}],"line":180},"22":{"loc":{"start":{"line":184,"column":14},"end":{"line":186,"column":null}},"type":"cond-expr","locations":[{"start":{"line":185,"column":10},"end":{"line":185,"column":null}},{"start":{"line":186,"column":10},"end":{"line":186,"column":null}}],"line":184}},"s":{"0":11,"1":11,"2":11,"3":11,"4":11,"5":11,"6":11,"7":11,"8":11,"9":11,"10":11,"11":11,"12":11,"13":11,"14":11,"15":11,"16":11,"17":33,"18":11,"19":23,"20":11,"21":11,"22":11,"23":11,"24":11,"25":22,"26":11,"27":15,"28":11,"29":11,"30":11,"31":2,"32":2,"33":11,"34":11,"35":0,"36":11,"37":11,"38":11,"39":11,"40":11,"41":11,"42":2,"43":9,"44":9,"45":9,"46":9,"47":9,"48":9,"49":9,"50":11},"f":{"0":11,"1":33,"2":23,"3":22,"4":15},"b":{"0":[11,0],"1":[11,0],"2":[10,1],"3":[11,0],"4":[11,7],"5":[7,4],"6":[4,0],"7":[0,4],"8":[11,7],"9":[7,4],"10":[4,0],"11":[0,4],"12":[2,9],"13":[1,1],"14":[0,11],"15":[11,11],"16":[0,0],"17":[2,9],"18":[8,1],"19":[11,0],"20":[2,9],"21":[9,8],"22":[8,1]},"meta":{"lastBranch":23,"lastFunction":5,"lastStatement":51,"seen":{"f:41:16:41:43":0,"s:42:65:42:Infinity":0,"s:43:32:43:Infinity":1,"s:46:22:46:Infinity":2,"s:47:22:47:Infinity":3,"s:48:2:54:Infinity":4,"b:52:8:52:Infinity:53:8:53:Infinity":0,"s:57:18:57:Infinity":5,"s:58:18:58:Infinity":6,"s:59:2:65:Infinity":7,"b:63:8:63:Infinity:64:8:64:Infinity":1,"s:68:20:68:Infinity":8,"s:69:20:69:Infinity":9,"s:70:2:76:Infinity":10,"b:74:8:74:Infinity:75:8:75:Infinity":2,"s:79:21:79:Infinity":11,"s:80:21:80:Infinity":12,"s:81:2:87:Infinity":13,"b:85:8:85:Infinity:86:8:86:Infinity":3,"s:90:20:90:Infinity":14,"s:91:20:91:Infinity":15,"s:92:24:92:Infinity":16,"f:92:39:92:47":1,"s:92:54:92:72":17,"s:93:22:93:Infinity":18,"f:93:37:93:45":2,"s:93:52:93:70":19,"s:94:22:94:Infinity":20,"b:94:22:94:52:94:52:94:Infinity":4,"s:95:2:104:Infinity":21,"b:99:8:99:Infinity:100:8:103:Infinity":5,"b:101:37:101:78:101:78:101:Infinity":6,"b:102:35:102:72:102:72:102:Infinity":7,"s:107:18:107:Infinity":22,"s:108:18:108:Infinity":23,"s:109:22:109:Infinity":24,"f:109:35:109:43":3,"s:109:49:109:64":25,"s:110:20:110:Infinity":26,"f:110:33:110:41":4,"s:110:47:110:62":27,"s:111:20:111:Infinity":28,"b:111:20:111:48:111:48:111:Infinity":8,"s:112:2:121:Infinity":29,"b:116:8:116:Infinity:117:8:120:Infinity":9,"b:118:35:118:88:118:88:118:Infinity":10,"b:119:33:119:77:119:77:119:Infinity":11,"b:124:2:131:Infinity:undefined:undefined:undefined:undefined":12,"s:124:2:131:Infinity":30,"s:125:18:125:Infinity":31,"s:126:4:130:Infinity":32,"b:129:22:129:34:129:34:129:Infinity":13,"s:134:21:134:Infinity":33,"b:135:2:152:Infinity:141:9:152:Infinity":14,"s:135:2:152:Infinity":34,"b:135:6:135:28:135:28:135:53":15,"s:136:4:140:Infinity":35,"b:139:27:139:39:139:39:139:Infinity":16,"s:142:23:142:Infinity":36,"s:143:4:151:Infinity":37,"b:147:10:147:Infinity:148:10:150:Infinity":17,"b:149:12:149:Infinity:150:12:150:Infinity":18,"s:155:17:155:Infinity":38,"s:156:2:160:Infinity":39,"b:159:34:159:44:159:44:159:Infinity":19,"s:167:62:167:Infinity":40,"b:168:2:188:Infinity:174:9:188:Infinity":20,"s:168:2:188:Infinity":41,"s:169:4:173:Infinity":42,"s:175:21:175:Infinity":43,"s:176:21:176:Infinity":44,"s:177:22:177:Infinity":45,"s:178:23:178:Infinity":46,"s:179:23:179:Infinity":47,"s:180:21:180:Infinity":48,"b:180:21:180:47:180:47:180:Infinity":21,"s:181:4:187:Infinity":49,"b:185:10:185:Infinity:186:10:186:Infinity":22,"s:190:2:190:Infinity":50}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-static-pages.js":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-static-pages.js","statementMap":{"0":{"start":{"line":104,"column":2},"end":{"line":104,"column":103}},"1":{"start":{"line":127,"column":2},"end":{"line":127,"column":125}},"2":{"start":{"line":148,"column":23},"end":{"line":148,"column":67}},"3":{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},"4":{"start":{"line":151,"column":21},"end":{"line":151,"column":70}},"5":{"start":{"line":152,"column":18},"end":{"line":152,"column":40}},"6":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"7":{"start":{"line":153,"column":60},"end":{"line":153,"column":null}},"8":{"start":{"line":156,"column":20},"end":{"line":156,"column":48}},"9":{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},"10":{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},"11":{"start":{"line":160,"column":6},"end":{"line":160,"column":null}},"12":{"start":{"line":163,"column":17},"end":{"line":165,"column":60}},"13":{"start":{"line":165,"column":21},"end":{"line":165,"column":59}},"14":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"15":{"start":{"line":166,"column":27},"end":{"line":166,"column":null}},"16":{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},"17":{"start":{"line":168,"column":6},"end":{"line":171,"column":null}},"18":{"start":{"line":175,"column":2},"end":{"line":179,"column":null}},"19":{"start":{"line":202,"column":23},"end":{"line":202,"column":67}},"20":{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},"21":{"start":{"line":205,"column":21},"end":{"line":205,"column":70}},"22":{"start":{"line":206,"column":16},"end":{"line":206,"column":45}},"23":{"start":{"line":207,"column":18},"end":{"line":207,"column":31}},"24":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"25":{"start":{"line":208,"column":59},"end":{"line":208,"column":null}},"26":{"start":{"line":211,"column":16},"end":{"line":211,"column":50}},"27":{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},"28":{"start":{"line":213,"column":15},"end":{"line":213,"column":63}},"29":{"start":{"line":214,"column":17},"end":{"line":214,"column":64}},"30":{"start":{"line":214,"column":53},"end":{"line":214,"column":63}},"31":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"32":{"start":{"line":215,"column":27},"end":{"line":215,"column":null}},"33":{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},"34":{"start":{"line":217,"column":6},"end":{"line":220,"column":null}},"35":{"start":{"line":224,"column":2},"end":{"line":224,"column":null}},"36":{"start":{"line":236,"column":16},"end":{"line":236,"column":18}},"37":{"start":{"line":237,"column":2},"end":{"line":264,"column":null}},"38":{"start":{"line":238,"column":16},"end":{"line":238,"column":48}},"39":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"40":{"start":{"line":239,"column":29},"end":{"line":239,"column":null}},"41":{"start":{"line":240,"column":17},"end":{"line":240,"column":33}},"42":{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},"43":{"start":{"line":242,"column":6},"end":{"line":242,"column":null}},"44":{"start":{"line":243,"column":6},"end":{"line":243,"column":null}},"45":{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},"46":{"start":{"line":246,"column":22},"end":{"line":246,"column":66}},"47":{"start":{"line":247,"column":6},"end":{"line":251,"column":null}},"48":{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},"49":{"start":{"line":249,"column":10},"end":{"line":249,"column":null}},"50":{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},"51":{"start":{"line":253,"column":8},"end":{"line":261,"column":null}},"52":{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},"53":{"start":{"line":254,"column":32},"end":{"line":254,"column":null}},"54":{"start":{"line":255,"column":10},"end":{"line":260,"column":null}},"55":{"start":{"line":265,"column":2},"end":{"line":265,"column":null}},"56":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"57":{"start":{"line":280,"column":38},"end":{"line":280,"column":null}},"58":{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},"59":{"start":{"line":281,"column":36},"end":{"line":281,"column":null}},"60":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"61":{"start":{"line":296,"column":44},"end":{"line":296,"column":51}},"62":{"start":{"line":298,"column":2},"end":{"line":394,"column":null}},"63":{"start":{"line":307,"column":24},"end":{"line":307,"column":89}},"64":{"start":{"line":308,"column":29},"end":{"line":308,"column":57}},"65":{"start":{"line":311,"column":33},"end":{"line":311,"column":42}},"66":{"start":{"line":312,"column":30},"end":{"line":317,"column":9}},"67":{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},"68":{"start":{"line":314,"column":12},"end":{"line":314,"column":null}},"69":{"start":{"line":316,"column":10},"end":{"line":316,"column":null}},"70":{"start":{"line":319,"column":27},"end":{"line":319,"column":28}},"71":{"start":{"line":320,"column":29},"end":{"line":320,"column":30}},"72":{"start":{"line":321,"column":35},"end":{"line":321,"column":36}},"73":{"start":{"line":322,"column":27},"end":{"line":322,"column":29}},"74":{"start":{"line":324,"column":8},"end":{"line":381,"column":null}},"75":{"start":{"line":325,"column":24},"end":{"line":325,"column":58}},"76":{"start":{"line":326,"column":24},"end":{"line":326,"column":25}},"77":{"start":{"line":327,"column":26},"end":{"line":327,"column":27}},"78":{"start":{"line":328,"column":32},"end":{"line":328,"column":33}},"79":{"start":{"line":330,"column":10},"end":{"line":375,"column":null}},"80":{"start":{"line":331,"column":24},"end":{"line":331,"column":59}},"81":{"start":{"line":332,"column":28},"end":{"line":332,"column":51}},"82":{"start":{"line":333,"column":12},"end":{"line":333,"column":null}},"83":{"start":{"line":335,"column":25},"end":{"line":335,"column":57}},"84":{"start":{"line":336,"column":29},"end":{"line":336,"column":34}},"85":{"start":{"line":337,"column":35},"end":{"line":337,"column":40}},"86":{"start":{"line":341,"column":22},"end":{"line":351,"column":13}},"87":{"start":{"line":344,"column":16},"end":{"line":344,"column":null}},"88":{"start":{"line":345,"column":32},"end":{"line":345,"column":65}},"89":{"start":{"line":346,"column":16},"end":{"line":349,"column":null}},"90":{"start":{"line":353,"column":12},"end":{"line":369,"column":null}},"91":{"start":{"line":354,"column":31},"end":{"line":354,"column":55}},"92":{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},"93":{"start":{"line":356,"column":16},"end":{"line":356,"column":null}},"94":{"start":{"line":358,"column":14},"end":{"line":358,"column":null}},"95":{"start":{"line":359,"column":33},"end":{"line":363,"column":25}},"96":{"start":{"line":360,"column":16},"end":{"line":363,"column":25}},"97":{"start":{"line":364,"column":34},"end":{"line":364,"column":52}},"98":{"start":{"line":365,"column":33},"end":{"line":365,"column":50}},"99":{"start":{"line":366,"column":32},"end":{"line":366,"column":68}},"100":{"start":{"line":367,"column":31},"end":{"line":367,"column":65}},"101":{"start":{"line":368,"column":14},"end":{"line":368,"column":null}},"102":{"start":{"line":371,"column":12},"end":{"line":371,"column":null}},"103":{"start":{"line":372,"column":12},"end":{"line":372,"column":null}},"104":{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},"105":{"start":{"line":373,"column":28},"end":{"line":373,"column":null}},"106":{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},"107":{"start":{"line":374,"column":34},"end":{"line":374,"column":null}},"108":{"start":{"line":377,"column":10},"end":{"line":377,"column":null}},"109":{"start":{"line":378,"column":10},"end":{"line":378,"column":null}},"110":{"start":{"line":379,"column":10},"end":{"line":379,"column":null}},"111":{"start":{"line":380,"column":10},"end":{"line":380,"column":null}},"112":{"start":{"line":383,"column":24},"end":{"line":385,"column":21}},"113":{"start":{"line":384,"column":22},"end":{"line":384,"column":81}},"114":{"start":{"line":386,"column":8},"end":{"line":391,"column":null}}},"fnMap":{"0":{"name":"readStylesAssetName","decl":{"start":{"line":147,"column":9},"end":{"line":147,"column":28}},"loc":{"start":{"line":147,"column":38},"end":{"line":180,"column":null}},"line":147},"1":{"name":"(anonymous_1)","decl":{"start":{"line":165,"column":14},"end":{"line":165,"column":15}},"loc":{"start":{"line":165,"column":21},"end":{"line":165,"column":59}},"line":165},"2":{"name":"readModuleAssetName","decl":{"start":{"line":201,"column":9},"end":{"line":201,"column":28}},"loc":{"start":{"line":201,"column":49},"end":{"line":225,"column":null}},"line":201},"3":{"name":"(anonymous_3)","decl":{"start":{"line":214,"column":46},"end":{"line":214,"column":47}},"loc":{"start":{"line":214,"column":53},"end":{"line":214,"column":63}},"line":214},"4":{"name":"resolvePageFiles","decl":{"start":{"line":235,"column":9},"end":{"line":235,"column":25}},"loc":{"start":{"line":235,"column":44},"end":{"line":266,"column":null}},"line":235},"5":{"name":"rewrittenHref","decl":{"start":{"line":279,"column":9},"end":{"line":279,"column":22}},"loc":{"start":{"line":279,"column":51},"end":{"line":283,"column":null}},"line":279},"6":{"name":"staticPagesPlugin","decl":{"start":{"line":295,"column":24},"end":{"line":295,"column":41}},"loc":{"start":{"line":295,"column":51},"end":{"line":395,"column":null}},"line":295},"7":{"name":"(anonymous_7)","decl":{"start":{"line":306,"column":6},"end":{"line":306,"column":13}},"loc":{"start":{"line":306,"column":16},"end":{"line":392,"column":7}},"line":306},"8":{"name":"(anonymous_8)","decl":{"start":{"line":312,"column":30},"end":{"line":312,"column":31}},"loc":{"start":{"line":312,"column":45},"end":{"line":317,"column":9}},"line":312},"9":{"name":"(anonymous_9)","decl":{"start":{"line":343,"column":14},"end":{"line":343,"column":15}},"loc":{"start":{"line":343,"column":48},"end":{"line":350,"column":15}},"line":343},"10":{"name":"(anonymous_10)","decl":{"start":{"line":353,"column":48},"end":{"line":353,"column":49}},"loc":{"start":{"line":353,"column":85},"end":{"line":369,"column":13}},"line":353},"11":{"name":"(anonymous_11)","decl":{"start":{"line":359,"column":33},"end":{"line":359,"column":34}},"loc":{"start":{"line":360,"column":16},"end":{"line":363,"column":25}},"line":360},"12":{"name":"(anonymous_12)","decl":{"start":{"line":384,"column":15},"end":{"line":384,"column":16}},"loc":{"start":{"line":384,"column":22},"end":{"line":384,"column":81}},"line":384}},"branchMap":{"0":{"loc":{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":149},"1":{"loc":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},{"start":{},"end":{}}],"line":153},"2":{"loc":{"start":{"line":153,"column":8},"end":{"line":153,"column":58}},"type":"binary-expr","locations":[{"start":{"line":153,"column":8},"end":{"line":153,"column":13}},{"start":{"line":153,"column":17},"end":{"line":153,"column":27}},{"start":{"line":153,"column":31},"end":{"line":153,"column":58}}],"line":153},"3":{"loc":{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},"type":"if","locations":[{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},{"start":{},"end":{}}],"line":157},"4":{"loc":{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":159},"5":{"loc":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":166},"6":{"loc":{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":167},"7":{"loc":{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},"type":"if","locations":[{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},{"start":{},"end":{}}],"line":203},"8":{"loc":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":208},"9":{"loc":{"start":{"line":208,"column":8},"end":{"line":208,"column":57}},"type":"binary-expr","locations":[{"start":{"line":208,"column":8},"end":{"line":208,"column":13}},{"start":{"line":208,"column":17},"end":{"line":208,"column":27}},{"start":{"line":208,"column":31},"end":{"line":208,"column":57}}],"line":208},"10":{"loc":{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},"type":"if","locations":[{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},{"start":{},"end":{}}],"line":212},"11":{"loc":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"type":"if","locations":[{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},{"start":{},"end":{}}],"line":215},"12":{"loc":{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":216},"13":{"loc":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"type":"if","locations":[{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},{"start":{},"end":{}}],"line":239},"14":{"loc":{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":241},"15":{"loc":{"start":{"line":241,"column":8},"end":{"line":241,"column":46}},"type":"binary-expr","locations":[{"start":{"line":241,"column":8},"end":{"line":241,"column":21}},{"start":{"line":241,"column":25},"end":{"line":241,"column":46}}],"line":241},"16":{"loc":{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},"type":"if","locations":[{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},{"start":{},"end":{}}],"line":245},"17":{"loc":{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},{"start":{},"end":{}}],"line":248},"18":{"loc":{"start":{"line":248,"column":12},"end":{"line":248,"column":50}},"type":"binary-expr","locations":[{"start":{"line":248,"column":12},"end":{"line":248,"column":22}},{"start":{"line":248,"column":26},"end":{"line":248,"column":50}}],"line":248},"19":{"loc":{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},"type":"if","locations":[{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},{"start":{},"end":{}}],"line":252},"20":{"loc":{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":254},"21":{"loc":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},{"start":{},"end":{}}],"line":280},"22":{"loc":{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},"type":"if","locations":[{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},{"start":{},"end":{}}],"line":281},"23":{"loc":{"start":{"line":307,"column":24},"end":{"line":307,"column":89}},"type":"cond-expr","locations":[{"start":{"line":307,"column":50},"end":{"line":307,"column":56}},{"start":{"line":307,"column":59},"end":{"line":307,"column":89}}],"line":307},"24":{"loc":{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":313},"25":{"loc":{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},"type":"if","locations":[{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},{"start":{},"end":{}}],"line":355},"26":{"loc":{"start":{"line":366,"column":32},"end":{"line":366,"column":68}},"type":"cond-expr","locations":[{"start":{"line":366,"column":46},"end":{"line":366,"column":63}},{"start":{"line":366,"column":66},"end":{"line":366,"column":68}}],"line":366},"27":{"loc":{"start":{"line":367,"column":31},"end":{"line":367,"column":65}},"type":"cond-expr","locations":[{"start":{"line":367,"column":44},"end":{"line":367,"column":60}},{"start":{"line":367,"column":63},"end":{"line":367,"column":65}}],"line":367},"28":{"loc":{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},"type":"if","locations":[{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},{"start":{},"end":{}}],"line":373},"29":{"loc":{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},"type":"if","locations":[{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},{"start":{},"end":{}}],"line":374}},"s":{"0":1,"1":1,"2":16,"3":16,"4":16,"5":16,"6":16,"7":13,"8":3,"9":3,"10":3,"11":1,"12":2,"13":1,"14":2,"15":1,"16":1,"17":0,"18":1,"19":5,"20":5,"21":5,"22":5,"23":5,"24":5,"25":3,"26":2,"27":2,"28":1,"29":1,"30":1,"31":1,"32":1,"33":0,"34":0,"35":1,"36":15,"37":15,"38":15,"39":15,"40":1,"41":14,"42":14,"43":6,"44":6,"45":8,"46":8,"47":8,"48":16,"49":16,"50":8,"51":1,"52":2,"53":2,"54":0,"55":15,"56":21,"57":16,"58":5,"59":0,"60":5,"61":17,"62":17,"63":16,"64":16,"65":16,"66":16,"67":8,"68":5,"69":8,"70":16,"71":16,"72":16,"73":16,"74":16,"75":15,"76":15,"77":15,"78":15,"79":15,"80":22,"81":22,"82":22,"83":22,"84":22,"85":22,"86":22,"87":21,"88":21,"89":21,"90":22,"91":8,"92":8,"93":1,"94":7,"95":7,"96":14,"97":7,"98":7,"99":7,"100":8,"101":8,"102":22,"103":22,"104":22,"105":21,"106":22,"107":7,"108":15,"109":15,"110":15,"111":15,"112":15,"113":15,"114":15},"f":{"0":16,"1":1,"2":5,"3":1,"4":15,"5":21,"6":17,"7":16,"8":8,"9":21,"10":8,"11":14,"12":15},"b":{"0":[16,0],"1":[13,3],"2":[16,13,13],"3":[3,0],"4":[1,2],"5":[1,1],"6":[0,1],"7":[5,0],"8":[3,2],"9":[5,3,3],"10":[1,1],"11":[1,0],"12":[0,0],"13":[1,14],"14":[6,8],"15":[14,6],"16":[8,0],"17":[16,0],"18":[16,16],"19":[1,7],"20":[2,0],"21":[16,5],"22":[0,5],"23":[0,16],"24":[5,3],"25":[1,7],"26":[7,0],"27":[0,7],"28":[21,1],"29":[7,15]},"meta":{"lastBranch":30,"lastFunction":13,"lastStatement":115,"seen":{"s:104:2:104:103":0,"s:127:2:127:125":1,"f:147:9:147:28":0,"s:148:23:148:67":2,"b:149:2:154:Infinity:undefined:undefined:undefined:undefined":0,"s:149:2:154:Infinity":3,"s:151:21:151:70":4,"s:152:18:152:40":5,"b:153:4:153:Infinity:undefined:undefined:undefined:undefined":1,"s:153:4:153:Infinity":6,"b:153:8:153:13:153:17:153:27:153:31:153:58":2,"s:153:60:153:Infinity":7,"s:156:20:156:48":8,"b:157:2:173:Infinity:undefined:undefined:undefined:undefined":3,"s:157:2:173:Infinity":9,"b:159:4:161:Infinity:undefined:undefined:undefined:undefined":4,"s:159:4:161:Infinity":10,"s:160:6:160:Infinity":11,"s:163:17:165:60":12,"f:165:14:165:15":1,"s:165:21:165:59":13,"b:166:4:166:Infinity:undefined:undefined:undefined:undefined":5,"s:166:4:166:Infinity":14,"s:166:27:166:Infinity":15,"b:167:4:172:Infinity:undefined:undefined:undefined:undefined":6,"s:167:4:172:Infinity":16,"s:168:6:171:Infinity":17,"s:175:2:179:Infinity":18,"f:201:9:201:28":2,"s:202:23:202:67":19,"b:203:2:209:Infinity:undefined:undefined:undefined:undefined":7,"s:203:2:209:Infinity":20,"s:205:21:205:70":21,"s:206:16:206:45":22,"s:207:18:207:31":23,"b:208:4:208:Infinity:undefined:undefined:undefined:undefined":8,"s:208:4:208:Infinity":24,"b:208:8:208:13:208:17:208:27:208:31:208:57":9,"s:208:59:208:Infinity":25,"s:211:16:211:50":26,"b:212:2:222:Infinity:undefined:undefined:undefined:undefined":10,"s:212:2:222:Infinity":27,"s:213:15:213:63":28,"s:214:17:214:64":29,"f:214:46:214:47":3,"s:214:53:214:63":30,"b:215:4:215:Infinity:undefined:undefined:undefined:undefined":11,"s:215:4:215:Infinity":31,"s:215:27:215:Infinity":32,"b:216:4:221:Infinity:undefined:undefined:undefined:undefined":12,"s:216:4:221:Infinity":33,"s:217:6:220:Infinity":34,"s:224:2:224:Infinity":35,"f:235:9:235:25":4,"s:236:16:236:18":36,"s:237:2:264:Infinity":37,"s:238:16:238:48":38,"b:239:4:239:Infinity:undefined:undefined:undefined:undefined":13,"s:239:4:239:Infinity":39,"s:239:29:239:Infinity":40,"s:240:17:240:33":41,"b:241:4:244:Infinity:undefined:undefined:undefined:undefined":14,"s:241:4:244:Infinity":42,"b:241:8:241:21:241:25:241:46":15,"s:242:6:242:Infinity":43,"s:243:6:243:Infinity":44,"b:245:4:263:Infinity:undefined:undefined:undefined:undefined":16,"s:245:4:263:Infinity":45,"s:246:22:246:66":46,"s:247:6:251:Infinity":47,"b:248:8:250:Infinity:undefined:undefined:undefined:undefined":17,"s:248:8:250:Infinity":48,"b:248:12:248:22:248:26:248:50":18,"s:249:10:249:Infinity":49,"b:252:6:262:Infinity:undefined:undefined:undefined:undefined":19,"s:252:6:262:Infinity":50,"s:253:8:261:Infinity":51,"b:254:10:254:Infinity:undefined:undefined:undefined:undefined":20,"s:254:10:254:Infinity":52,"s:254:32:254:Infinity":53,"s:255:10:260:Infinity":54,"s:265:2:265:Infinity":55,"f:279:9:279:22":5,"b:280:2:280:Infinity:undefined:undefined:undefined:undefined":21,"s:280:2:280:Infinity":56,"s:280:38:280:Infinity":57,"b:281:2:281:Infinity:undefined:undefined:undefined:undefined":22,"s:281:2:281:Infinity":58,"s:281:36:281:Infinity":59,"s:282:2:282:Infinity":60,"f:295:24:295:41":6,"s:296:44:296:51":61,"s:298:2:394:Infinity":62,"f:306:6:306:13":7,"s:307:24:307:89":63,"b:307:50:307:56:307:59:307:89":23,"s:308:29:308:57":64,"s:311:33:311:42":65,"s:312:30:317:9":66,"f:312:30:312:31":8,"b:313:10:315:Infinity:undefined:undefined:undefined:undefined":24,"s:313:10:315:Infinity":67,"s:314:12:314:Infinity":68,"s:316:10:316:Infinity":69,"s:319:27:319:28":70,"s:320:29:320:30":71,"s:321:35:321:36":72,"s:322:27:322:29":73,"s:324:8:381:Infinity":74,"s:325:24:325:58":75,"s:326:24:326:25":76,"s:327:26:327:27":77,"s:328:32:328:33":78,"s:330:10:375:Infinity":79,"s:331:24:331:59":80,"s:332:28:332:51":81,"s:333:12:333:Infinity":82,"s:335:25:335:57":83,"s:336:29:336:34":84,"s:337:35:337:40":85,"s:341:22:351:13":86,"f:343:14:343:15":9,"s:344:16:344:Infinity":87,"s:345:32:345:65":88,"s:346:16:349:Infinity":89,"s:353:12:369:Infinity":90,"f:353:48:353:49":10,"s:354:31:354:55":91,"b:355:14:357:Infinity:undefined:undefined:undefined:undefined":25,"s:355:14:357:Infinity":92,"s:356:16:356:Infinity":93,"s:358:14:358:Infinity":94,"s:359:33:363:25":95,"f:359:33:359:34":11,"s:360:16:363:25":96,"s:364:34:364:52":97,"s:365:33:365:50":98,"s:366:32:366:68":99,"b:366:46:366:63:366:66:366:68":26,"s:367:31:367:65":100,"b:367:44:367:60:367:63:367:65":27,"s:368:14:368:Infinity":101,"s:371:12:371:Infinity":102,"s:372:12:372:Infinity":103,"b:373:12:373:Infinity:undefined:undefined:undefined:undefined":28,"s:373:12:373:Infinity":104,"s:373:28:373:Infinity":105,"b:374:12:374:Infinity:undefined:undefined:undefined:undefined":29,"s:374:12:374:Infinity":106,"s:374:34:374:Infinity":107,"s:377:10:377:Infinity":108,"s:378:10:378:Infinity":109,"s:379:10:379:Infinity":110,"s:380:10:380:Infinity":111,"s:383:24:385:21":112,"f:384:15:384:16":12,"s:384:22:384:81":113,"s:386:8:391:Infinity":114}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-sw-build-id.js":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-sw-build-id.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":66}},"1":{"start":{"line":54,"column":17},"end":{"line":54,"column":39}},"2":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"3":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"4":{"start":{"line":59,"column":2},"end":{"line":69,"column":null}},"5":{"start":{"line":60,"column":16},"end":{"line":63,"column":13}},"6":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"7":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"8":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"9":{"start":{"line":81,"column":43},"end":{"line":81,"column":50}},"10":{"start":{"line":83,"column":2},"end":{"line":125,"column":null}},"11":{"start":{"line":92,"column":24},"end":{"line":92,"column":40}},"12":{"start":{"line":93,"column":24},"end":{"line":95,"column":42}},"13":{"start":{"line":97,"column":24},"end":{"line":97,"column":65}},"14":{"start":{"line":98,"column":25},"end":{"line":98,"column":52}},"15":{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},"16":{"start":{"line":101,"column":10},"end":{"line":103,"column":null}},"17":{"start":{"line":106,"column":20},"end":{"line":106,"column":52}},"18":{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},"19":{"start":{"line":108,"column":10},"end":{"line":112,"column":null}},"20":{"start":{"line":115,"column":20},"end":{"line":115,"column":59}},"21":{"start":{"line":117,"column":8},"end":{"line":117,"column":null}},"22":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"23":{"start":{"line":120,"column":8},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"resolveBuildId","decl":{"start":{"line":53,"column":9},"end":{"line":53,"column":23}},"loc":{"start":{"line":53,"column":26},"end":{"line":72,"column":null}},"line":53},"1":{"name":"swBuildIdPlugin","decl":{"start":{"line":80,"column":24},"end":{"line":80,"column":39}},"loc":{"start":{"line":80,"column":49},"end":{"line":126,"column":null}},"line":80},"2":{"name":"(anonymous_2)","decl":{"start":{"line":91,"column":6},"end":{"line":91,"column":13}},"loc":{"start":{"line":91,"column":16},"end":{"line":123,"column":7}},"line":91}},"branchMap":{"0":{"loc":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":55},"1":{"loc":{"start":{"line":55,"column":6},"end":{"line":55,"column":43}},"type":"binary-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":12}},{"start":{"line":55,"column":16},"end":{"line":55,"column":43}}],"line":55},"2":{"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"3":{"loc":{"start":{"line":64,"column":8},"end":{"line":64,"column":51}},"type":"binary-expr","locations":[{"start":{"line":64,"column":8},"end":{"line":64,"column":32}},{"start":{"line":64,"column":36},"end":{"line":64,"column":51}}],"line":64},"4":{"loc":{"start":{"line":81,"column":23},"end":{"line":81,"column":38}},"type":"default-arg","locations":[{"start":{"line":81,"column":32},"end":{"line":81,"column":38}}],"line":81},"5":{"loc":{"start":{"line":93,"column":24},"end":{"line":95,"column":42}},"type":"cond-expr","locations":[{"start":{"line":94,"column":12},"end":{"line":94,"column":null}},{"start":{"line":95,"column":12},"end":{"line":95,"column":42}}],"line":93},"6":{"loc":{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},{"start":{},"end":{}}],"line":100},"7":{"loc":{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":107}},"s":{"0":1,"1":6,"2":6,"3":5,"4":1,"5":1,"6":1,"7":1,"8":0,"9":7,"10":7,"11":6,"12":6,"13":6,"14":6,"15":6,"16":1,"17":5,"18":5,"19":1,"20":4,"21":4,"22":4,"23":4},"f":{"0":6,"1":7,"2":6},"b":{"0":[5,1],"1":[6,5],"2":[1,0],"3":[1,1],"4":[7],"5":[0,6],"6":[1,5],"7":[1,4]},"meta":{"lastBranch":8,"lastFunction":3,"lastStatement":24,"seen":{"s:1:17:1:66":0,"f:53:9:53:23":0,"s:54:17:54:39":1,"b:55:2:57:Infinity:undefined:undefined:undefined:undefined":0,"s:55:2:57:Infinity":2,"b:55:6:55:12:55:16:55:43":1,"s:56:4:56:Infinity":3,"s:59:2:69:Infinity":4,"s:60:16:63:13":5,"b:64:4:66:Infinity:undefined:undefined:undefined:undefined":2,"s:64:4:66:Infinity":6,"b:64:8:64:32:64:36:64:51":3,"s:65:6:65:Infinity":7,"s:71:2:71:Infinity":8,"f:80:24:80:39":1,"s:81:43:81:50":9,"b:81:32:81:38":4,"s:83:2:125:Infinity":10,"f:91:6:91:13":2,"s:92:24:92:40":11,"s:93:24:95:42":12,"b:94:12:94:Infinity:95:12:95:42":5,"s:97:24:97:65":13,"s:98:25:98:52":14,"b:100:8:104:Infinity:undefined:undefined:undefined:undefined":6,"s:100:8:104:Infinity":15,"s:101:10:103:Infinity":16,"s:106:20:106:52":17,"b:107:8:113:Infinity:undefined:undefined:undefined:undefined":7,"s:107:8:113:Infinity":18,"s:108:10:112:Infinity":19,"s:115:20:115:59":20,"s:117:8:117:Infinity":21,"s:118:8:118:Infinity":22,"s:120:8:122:Infinity":23}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-client.ts","statementMap":{"0":{"start":{"line":57,"column":25},"end":{"line":57,"column":null}},"1":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"2":{"start":{"line":59,"column":28},"end":{"line":59,"column":null}},"3":{"start":{"line":66,"column":26},"end":{"line":71,"column":null}},"4":{"start":{"line":74,"column":33},"end":{"line":76,"column":null}},"5":{"start":{"line":79,"column":29},"end":{"line":86,"column":null}},"6":{"start":{"line":120,"column":29},"end":{"line":323,"column":null}},"7":{"start":{"line":339,"column":4},"end":{"line":339,"column":null}},"8":{"start":{"line":340,"column":4},"end":{"line":340,"column":null}},"9":{"start":{"line":341,"column":4},"end":{"line":341,"column":null}},"10":{"start":{"line":357,"column":24},"end":{"line":357,"column":null}},"11":{"start":{"line":358,"column":16},"end":{"line":358,"column":null}},"12":{"start":{"line":360,"column":17},"end":{"line":360,"column":null}},"13":{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},"14":{"start":{"line":363,"column":6},"end":{"line":363,"column":null}},"15":{"start":{"line":366,"column":4},"end":{"line":383,"column":null}},"16":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"17":{"start":{"line":368,"column":22},"end":{"line":375,"column":8}},"18":{"start":{"line":377,"column":22},"end":{"line":377,"column":null}},"19":{"start":{"line":378,"column":22},"end":{"line":378,"column":null}},"20":{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},"21":{"start":{"line":379,"column":42},"end":{"line":379,"column":null}},"22":{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},"23":{"start":{"line":380,"column":26},"end":{"line":380,"column":null}},"24":{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},"25":{"start":{"line":381,"column":26},"end":{"line":381,"column":null}},"26":{"start":{"line":382,"column":8},"end":{"line":382,"column":null}},"27":{"start":{"line":397,"column":20},"end":{"line":397,"column":null}},"28":{"start":{"line":398,"column":4},"end":{"line":398,"column":null}},"29":{"start":{"line":412,"column":20},"end":{"line":412,"column":null}},"30":{"start":{"line":414,"column":4},"end":{"line":421,"column":null}},"31":{"start":{"line":415,"column":6},"end":{"line":420,"column":null}},"32":{"start":{"line":416,"column":23},"end":{"line":416,"column":null}},"33":{"start":{"line":417,"column":8},"end":{"line":417,"column":null}},"34":{"start":{"line":419,"column":8},"end":{"line":419,"column":null}},"35":{"start":{"line":423,"column":4},"end":{"line":423,"column":null}},"36":{"start":{"line":431,"column":23},"end":{"line":431,"column":null}},"37":{"start":{"line":432,"column":22},"end":{"line":432,"column":null}},"38":{"start":{"line":432,"column":39},"end":{"line":432,"column":59}},"39":{"start":{"line":434,"column":4},"end":{"line":454,"column":null}},"40":{"start":{"line":435,"column":23},"end":{"line":438,"column":null}},"41":{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},"42":{"start":{"line":441,"column":8},"end":{"line":441,"column":null}},"43":{"start":{"line":444,"column":6},"end":{"line":444,"column":null}},"44":{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},"45":{"start":{"line":447,"column":22},"end":{"line":447,"column":null}},"46":{"start":{"line":448,"column":8},"end":{"line":448,"column":null}},"47":{"start":{"line":448,"column":39},"end":{"line":448,"column":65}},"48":{"start":{"line":449,"column":8},"end":{"line":449,"column":null}},"49":{"start":{"line":451,"column":6},"end":{"line":451,"column":null}},"50":{"start":{"line":453,"column":6},"end":{"line":453,"column":null}},"51":{"start":{"line":462,"column":53},"end":{"line":462,"column":null}},"52":{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},"53":{"start":{"line":467,"column":4},"end":{"line":467,"column":null}},"54":{"start":{"line":469,"column":2},"end":{"line":469,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":338,"column":2},"end":{"line":338,"column":14}},"loc":{"start":{"line":338,"column":50},"end":{"line":342,"column":null}},"line":338},"1":{"name":"(anonymous_1)","decl":{"start":{"line":352,"column":8},"end":{"line":352,"column":null}},"loc":{"start":{"line":356,"column":35},"end":{"line":384,"column":null}},"line":356},"2":{"name":"(anonymous_2)","decl":{"start":{"line":367,"column":7},"end":{"line":367,"column":15}},"loc":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"line":367},"3":{"name":"(anonymous_3)","decl":{"start":{"line":368,"column":7},"end":{"line":368,"column":12}},"loc":{"start":{"line":368,"column":22},"end":{"line":375,"column":8}},"line":368},"4":{"name":"(anonymous_4)","decl":{"start":{"line":376,"column":7},"end":{"line":376,"column":13}},"loc":{"start":{"line":376,"column":22},"end":{"line":383,"column":7}},"line":376},"5":{"name":"(anonymous_5)","decl":{"start":{"line":393,"column":8},"end":{"line":393,"column":null}},"loc":{"start":{"line":396,"column":40},"end":{"line":399,"column":null}},"line":396},"6":{"name":"(anonymous_6)","decl":{"start":{"line":408,"column":8},"end":{"line":408,"column":null}},"loc":{"start":{"line":411,"column":53},"end":{"line":424,"column":null}},"line":411},"7":{"name":"(anonymous_7)","decl":{"start":{"line":430,"column":16},"end":{"line":430,"column":31}},"loc":{"start":{"line":430,"column":75},"end":{"line":455,"column":null}},"line":430},"8":{"name":"(anonymous_8)","decl":{"start":{"line":432,"column":22},"end":{"line":432,"column":39}},"loc":{"start":{"line":432,"column":39},"end":{"line":432,"column":59}},"line":432},"9":{"name":"(anonymous_9)","decl":{"start":{"line":448,"column":18},"end":{"line":448,"column":27}},"loc":{"start":{"line":448,"column":39},"end":{"line":448,"column":65}},"line":448},"10":{"name":"getDefaultWorldBankClient","decl":{"start":{"line":465,"column":16},"end":{"line":465,"column":61}},"loc":{"start":{"line":465,"column":61},"end":{"line":470,"column":null}},"line":465}},"branchMap":{"0":{"loc":{"start":{"line":338,"column":14},"end":{"line":338,"column":50}},"type":"default-arg","locations":[{"start":{"line":338,"column":46},"end":{"line":338,"column":50}}],"line":338},"1":{"loc":{"start":{"line":339,"column":19},"end":{"line":339,"column":null}},"type":"binary-expr","locations":[{"start":{"line":339,"column":19},"end":{"line":339,"column":37}},{"start":{"line":339,"column":37},"end":{"line":339,"column":null}}],"line":339},"2":{"loc":{"start":{"line":340,"column":19},"end":{"line":340,"column":null}},"type":"binary-expr","locations":[{"start":{"line":340,"column":19},"end":{"line":340,"column":37}},{"start":{"line":340,"column":37},"end":{"line":340,"column":null}}],"line":340},"3":{"loc":{"start":{"line":341,"column":22},"end":{"line":341,"column":null}},"type":"binary-expr","locations":[{"start":{"line":341,"column":22},"end":{"line":341,"column":43}},{"start":{"line":341,"column":43},"end":{"line":341,"column":null}}],"line":341},"4":{"loc":{"start":{"line":355,"column":4},"end":{"line":355,"column":null}},"type":"default-arg","locations":[{"start":{"line":355,"column":14},"end":{"line":355,"column":null}}],"line":355},"5":{"loc":{"start":{"line":357,"column":24},"end":{"line":357,"column":null}},"type":"cond-expr","locations":[{"start":{"line":357,"column":61},"end":{"line":357,"column":91}},{"start":{"line":357,"column":91},"end":{"line":357,"column":null}}],"line":357},"6":{"loc":{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},"type":"if","locations":[{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},{"start":{},"end":{}}],"line":362},"7":{"loc":{"start":{"line":362,"column":8},"end":{"line":362,"column":76}},"type":"binary-expr","locations":[{"start":{"line":362,"column":8},"end":{"line":362,"column":32}},{"start":{"line":362,"column":32},"end":{"line":362,"column":51}},{"start":{"line":362,"column":51},"end":{"line":362,"column":76}}],"line":362},"8":{"loc":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"type":"binary-expr","locations":[{"start":{"line":367,"column":71},"end":{"line":367,"column":94}},{"start":{"line":367,"column":94},"end":{"line":367,"column":118}}],"line":367},"9":{"loc":{"start":{"line":369,"column":19},"end":{"line":369,"column":null}},"type":"binary-expr","locations":[{"start":{"line":369,"column":19},"end":{"line":369,"column":39}},{"start":{"line":369,"column":39},"end":{"line":369,"column":null}}],"line":369},"10":{"loc":{"start":{"line":370,"column":21},"end":{"line":370,"column":null}},"type":"binary-expr","locations":[{"start":{"line":370,"column":21},"end":{"line":370,"column":44}},{"start":{"line":370,"column":44},"end":{"line":370,"column":null}}],"line":370},"11":{"loc":{"start":{"line":371,"column":21},"end":{"line":371,"column":null}},"type":"binary-expr","locations":[{"start":{"line":371,"column":21},"end":{"line":371,"column":43}},{"start":{"line":371,"column":43},"end":{"line":371,"column":null}}],"line":371},"12":{"loc":{"start":{"line":372,"column":23},"end":{"line":372,"column":null}},"type":"binary-expr","locations":[{"start":{"line":372,"column":23},"end":{"line":372,"column":48}},{"start":{"line":372,"column":48},"end":{"line":372,"column":null}}],"line":372},"13":{"loc":{"start":{"line":373,"column":14},"end":{"line":373,"column":null}},"type":"binary-expr","locations":[{"start":{"line":373,"column":14},"end":{"line":373,"column":27}},{"start":{"line":373,"column":27},"end":{"line":373,"column":null}}],"line":373},"14":{"loc":{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},"type":"if","locations":[{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},{"start":{},"end":{}}],"line":379},"15":{"loc":{"start":{"line":379,"column":12},"end":{"line":379,"column":42}},"type":"binary-expr","locations":[{"start":{"line":379,"column":12},"end":{"line":379,"column":28}},{"start":{"line":379,"column":28},"end":{"line":379,"column":42}}],"line":379},"16":{"loc":{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},"type":"if","locations":[{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},{"start":{},"end":{}}],"line":380},"17":{"loc":{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},"type":"if","locations":[{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},{"start":{},"end":{}}],"line":381},"18":{"loc":{"start":{"line":398,"column":11},"end":{"line":398,"column":null}},"type":"cond-expr","locations":[{"start":{"line":398,"column":32},"end":{"line":398,"column":45}},{"start":{"line":398,"column":45},"end":{"line":398,"column":null}}],"line":398},"19":{"loc":{"start":{"line":430,"column":44},"end":{"line":430,"column":75}},"type":"default-arg","locations":[{"start":{"line":430,"column":54},"end":{"line":430,"column":75}}],"line":430},"20":{"loc":{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},"type":"if","locations":[{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},{"start":{},"end":{}}],"line":440},"21":{"loc":{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},"type":"if","locations":[{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},{"start":{},"end":{}}],"line":446},"22":{"loc":{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},"type":"if","locations":[{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},{"start":{},"end":{}}],"line":466}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":57,"8":57,"9":57,"10":96,"11":96,"12":96,"13":93,"14":81,"15":12,"16":12,"17":11,"18":4,"19":4,"20":4,"21":0,"22":4,"23":0,"24":4,"25":0,"26":4,"27":6,"28":5,"29":2,"30":2,"31":4,"32":4,"33":3,"34":1,"35":2,"36":97,"37":97,"38":0,"39":97,"40":97,"41":94,"42":1,"43":93,"44":4,"45":1,"46":1,"47":1,"48":1,"49":3,"50":97,"51":3,"52":3,"53":1,"54":3},"f":{"0":57,"1":96,"2":12,"3":11,"4":4,"5":6,"6":2,"7":97,"8":0,"9":1,"10":3},"b":{"0":[57],"1":[57,56],"2":[57,55],"3":[57,53],"4":[96],"5":[7,89],"6":[81,12],"7":[93,13,12],"8":[12,11],"9":[11,0],"10":[11,1],"11":[11,0],"12":[11,1],"13":[11,0],"14":[0,4],"15":[4,0],"16":[0,4],"17":[0,4],"18":[4,1],"19":[97],"20":[1,93],"21":[1,3],"22":[1,2]},"meta":{"lastBranch":23,"lastFunction":11,"lastStatement":55,"seen":{"s:57:25:57:Infinity":0,"s:58:24:58:Infinity":1,"s:59:28:59:Infinity":2,"s:66:26:71:Infinity":3,"s:74:33:76:Infinity":4,"s:79:29:86:Infinity":5,"s:120:29:323:Infinity":6,"f:338:2:338:14":0,"b:338:46:338:50":0,"s:339:4:339:Infinity":7,"b:339:19:339:37:339:37:339:Infinity":1,"s:340:4:340:Infinity":8,"b:340:19:340:37:340:37:340:Infinity":2,"s:341:4:341:Infinity":9,"b:341:22:341:43:341:43:341:Infinity":3,"f:352:8:352:Infinity":1,"b:355:14:355:Infinity":4,"s:357:24:357:Infinity":10,"b:357:61:357:91:357:91:357:Infinity":5,"s:358:16:358:Infinity":11,"s:360:17:360:Infinity":12,"b:362:4:364:Infinity:undefined:undefined:undefined:undefined":6,"s:362:4:364:Infinity":13,"b:362:8:362:32:362:32:362:51:362:51:362:76":7,"s:363:6:363:Infinity":14,"s:366:4:383:Infinity":15,"f:367:7:367:15":2,"s:367:71:367:118":16,"b:367:71:367:94:367:94:367:118":8,"f:368:7:368:12":3,"s:368:22:375:8":17,"b:369:19:369:39:369:39:369:Infinity":9,"b:370:21:370:44:370:44:370:Infinity":10,"b:371:21:371:43:371:43:371:Infinity":11,"b:372:23:372:48:372:48:372:Infinity":12,"b:373:14:373:27:373:27:373:Infinity":13,"f:376:7:376:13":4,"s:377:22:377:Infinity":18,"s:378:22:378:Infinity":19,"b:379:8:379:Infinity:undefined:undefined:undefined:undefined":14,"s:379:8:379:Infinity":20,"b:379:12:379:28:379:28:379:42":15,"s:379:42:379:Infinity":21,"b:380:8:380:Infinity:undefined:undefined:undefined:undefined":16,"s:380:8:380:Infinity":22,"s:380:26:380:Infinity":23,"b:381:8:381:Infinity:undefined:undefined:undefined:undefined":17,"s:381:8:381:Infinity":24,"s:381:26:381:Infinity":25,"s:382:8:382:Infinity":26,"f:393:8:393:Infinity":5,"s:397:20:397:Infinity":27,"s:398:4:398:Infinity":28,"b:398:32:398:45:398:45:398:Infinity":18,"f:408:8:408:Infinity":6,"s:412:20:412:Infinity":29,"s:414:4:421:Infinity":30,"s:415:6:420:Infinity":31,"s:416:23:416:Infinity":32,"s:417:8:417:Infinity":33,"s:419:8:419:Infinity":34,"s:423:4:423:Infinity":35,"f:430:16:430:31":7,"b:430:54:430:75":19,"s:431:23:431:Infinity":36,"s:432:22:432:Infinity":37,"f:432:22:432:39":8,"s:432:39:432:59":38,"s:434:4:454:Infinity":39,"s:435:23:438:Infinity":40,"b:440:6:442:Infinity:undefined:undefined:undefined:undefined":20,"s:440:6:442:Infinity":41,"s:441:8:441:Infinity":42,"s:444:6:444:Infinity":43,"b:446:6:450:Infinity:undefined:undefined:undefined:undefined":21,"s:446:6:450:Infinity":44,"s:447:22:447:Infinity":45,"s:448:8:448:Infinity":46,"f:448:18:448:27":9,"s:448:39:448:65":47,"s:449:8:449:Infinity":48,"s:451:6:451:Infinity":49,"s:453:6:453:Infinity":50,"s:462:53:462:Infinity":51,"f:465:16:465:61":10,"b:466:2:468:Infinity:undefined:undefined:undefined:undefined":22,"s:466:2:468:Infinity":52,"s:467:4:467:Infinity":53,"s:469:2:469:Infinity":54}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-context.ts","statementMap":{"0":{"start":{"line":113,"column":2},"end":{"line":118,"column":null}},"1":{"start":{"line":114,"column":20},"end":{"line":114,"column":null}},"2":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"3":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"4":{"start":{"line":130,"column":2},"end":{"line":160,"column":null}},"5":{"start":{"line":131,"column":16},"end":{"line":131,"column":null}},"6":{"start":{"line":132,"column":42},"end":{"line":132,"column":null}},"7":{"start":{"line":134,"column":52},"end":{"line":134,"column":null}},"8":{"start":{"line":135,"column":4},"end":{"line":146,"column":null}},"9":{"start":{"line":136,"column":6},"end":{"line":145,"column":null}},"10":{"start":{"line":137,"column":8},"end":{"line":144,"column":null}},"11":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"12":{"start":{"line":150,"column":6},"end":{"line":152,"column":null}},"13":{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},"14":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"15":{"start":{"line":158,"column":4},"end":{"line":158,"column":null}},"16":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"17":{"start":{"line":185,"column":2},"end":{"line":185,"column":null}},"18":{"start":{"line":192,"column":54},"end":{"line":207,"column":null}},"19":{"start":{"line":217,"column":94},"end":{"line":316,"column":null}},"20":{"start":{"line":333,"column":19},"end":{"line":333,"column":null}},"21":{"start":{"line":334,"column":2},"end":{"line":334,"column":null}},"22":{"start":{"line":346,"column":12},"end":{"line":346,"column":null}},"23":{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},"24":{"start":{"line":348,"column":4},"end":{"line":348,"column":null}},"25":{"start":{"line":350,"column":2},"end":{"line":354,"column":null}},"26":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"27":{"start":{"line":352,"column":43},"end":{"line":352,"column":73}},"28":{"start":{"line":353,"column":39},"end":{"line":353,"column":60}},"29":{"start":{"line":366,"column":2},"end":{"line":370,"column":null}},"30":{"start":{"line":366,"column":51},"end":{"line":370,"column":4}},"31":{"start":{"line":386,"column":15},"end":{"line":386,"column":null}},"32":{"start":{"line":387,"column":38},"end":{"line":416,"column":null}},"33":{"start":{"line":418,"column":2},"end":{"line":418,"column":null}},"34":{"start":{"line":418,"column":36},"end":{"line":418,"column":54}}},"fnMap":{"0":{"name":"resolveInventoryPath","decl":{"start":{"line":112,"column":9},"end":{"line":112,"column":40}},"loc":{"start":{"line":112,"column":40},"end":{"line":119,"column":null}},"line":112},"1":{"name":"loadIndicatorsFromInventory","decl":{"start":{"line":129,"column":9},"end":{"line":129,"column":77}},"loc":{"start":{"line":129,"column":77},"end":{"line":161,"column":null}},"line":129},"2":{"name":"getEconomicHeading","decl":{"start":{"line":329,"column":16},"end":{"line":329,"column":null}},"loc":{"start":{"line":332,"column":10},"end":{"line":335,"column":null}},"line":332},"3":{"name":"findRelevantIndicators","decl":{"start":{"line":345,"column":16},"end":{"line":345,"column":39}},"loc":{"start":{"line":345,"column":92},"end":{"line":355,"column":null}},"line":345},"4":{"name":"(anonymous_4)","decl":{"start":{"line":350,"column":31},"end":{"line":350,"column":null}},"loc":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"line":352},"5":{"name":"(anonymous_5)","decl":{"start":{"line":352,"column":28},"end":{"line":352,"column":34}},"loc":{"start":{"line":352,"column":43},"end":{"line":352,"column":73}},"line":352},"6":{"name":"(anonymous_6)","decl":{"start":{"line":353,"column":27},"end":{"line":353,"column":33}},"loc":{"start":{"line":353,"column":39},"end":{"line":353,"column":60}},"line":353},"7":{"name":"getSwedishIndicatorQueries","decl":{"start":{"line":365,"column":16},"end":{"line":365,"column":116}},"loc":{"start":{"line":365,"column":116},"end":{"line":371,"column":null}},"line":365},"8":{"name":"(anonymous_8)","decl":{"start":{"line":366,"column":31},"end":{"line":366,"column":36}},"loc":{"start":{"line":366,"column":51},"end":{"line":370,"column":4}},"line":366},"9":{"name":"hasEconomicContext","decl":{"start":{"line":385,"column":16},"end":{"line":385,"column":35}},"loc":{"start":{"line":385,"column":61},"end":{"line":419,"column":null}},"line":385},"10":{"name":"(anonymous_10)","decl":{"start":{"line":418,"column":18},"end":{"line":418,"column":24}},"loc":{"start":{"line":418,"column":36},"end":{"line":418,"column":54}},"line":418}},"branchMap":{"0":{"loc":{"start":{"line":140,"column":23},"end":{"line":140,"column":null}},"type":"binary-expr","locations":[{"start":{"line":140,"column":23},"end":{"line":140,"column":42}},{"start":{"line":140,"column":42},"end":{"line":140,"column":null}}],"line":140},"1":{"loc":{"start":{"line":141,"column":23},"end":{"line":141,"column":null}},"type":"binary-expr","locations":[{"start":{"line":141,"column":23},"end":{"line":141,"column":42}},{"start":{"line":141,"column":42},"end":{"line":141,"column":null}}],"line":141},"2":{"loc":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":22},"end":{"line":142,"column":40}},{"start":{"line":142,"column":40},"end":{"line":142,"column":null}}],"line":142},"3":{"loc":{"start":{"line":150,"column":6},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":10},"end":{"line":151,"column":null}},{"start":{"line":152,"column":10},"end":{"line":152,"column":null}}],"line":150},"4":{"loc":{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},{"start":{},"end":{}}],"line":154},"5":{"loc":{"start":{"line":333,"column":19},"end":{"line":333,"column":null}},"type":"binary-expr","locations":[{"start":{"line":333,"column":19},"end":{"line":333,"column":66}},{"start":{"line":333,"column":66},"end":{"line":333,"column":null}}],"line":333},"6":{"loc":{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},"type":"if","locations":[{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},{"start":{},"end":{}}],"line":347},"7":{"loc":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"type":"binary-expr","locations":[{"start":{"line":352,"column":6},"end":{"line":352,"column":null}},{"start":{"line":353,"column":6},"end":{"line":353,"column":null}}],"line":352}},"s":{"0":1,"1":1,"2":1,"3":0,"4":1,"5":1,"6":1,"7":1,"8":1,"9":11,"10":79,"11":1,"12":0,"13":0,"14":0,"15":0,"16":0,"17":1,"18":1,"19":1,"20":91,"21":91,"22":185,"23":185,"24":2,"25":183,"26":14457,"27":35648,"28":19290,"29":22,"30":1738,"31":28,"32":28,"33":28,"34":437},"f":{"0":1,"1":1,"2":91,"3":185,"4":14457,"5":35648,"6":19290,"7":22,"8":1738,"9":28,"10":437},"b":{"0":[79,0],"1":[79,0],"2":[79,52],"3":[0,0],"4":[0,0],"5":[91,2],"6":[2,183],"7":[14457,14339]},"meta":{"lastBranch":8,"lastFunction":11,"lastStatement":35,"seen":{"f:112:9:112:40":0,"s:113:2:118:Infinity":0,"s:114:20:114:Infinity":1,"s:115:4:115:Infinity":2,"s:117:4:117:Infinity":3,"f:129:9:129:77":1,"s:130:2:160:Infinity":4,"s:131:16:131:Infinity":5,"s:132:42:132:Infinity":6,"s:134:52:134:Infinity":7,"s:135:4:146:Infinity":8,"s:136:6:145:Infinity":9,"s:137:8:144:Infinity":10,"b:140:23:140:42:140:42:140:Infinity":0,"b:141:23:141:42:141:42:141:Infinity":1,"b:142:22:142:40:142:40:142:Infinity":2,"s:147:4:147:Infinity":11,"s:150:6:152:Infinity":12,"b:151:10:151:Infinity:152:10:152:Infinity":3,"b:154:4:156:Infinity:undefined:undefined:undefined:undefined":4,"s:154:4:156:Infinity":13,"s:155:6:155:Infinity":14,"s:158:4:158:Infinity":15,"s:159:4:159:Infinity":16,"s:185:2:185:Infinity":17,"s:192:54:207:Infinity":18,"s:217:94:316:Infinity":19,"f:329:16:329:Infinity":2,"s:333:19:333:Infinity":20,"b:333:19:333:66:333:66:333:Infinity":5,"s:334:2:334:Infinity":21,"f:345:16:345:39":3,"s:346:12:346:Infinity":22,"b:347:2:349:Infinity:undefined:undefined:undefined:undefined":6,"s:347:2:349:Infinity":23,"s:348:4:348:Infinity":24,"s:350:2:354:Infinity":25,"f:350:31:350:Infinity":4,"s:352:6:353:Infinity":26,"b:352:6:352:Infinity:353:6:353:Infinity":7,"f:352:28:352:34":5,"s:352:43:352:73":27,"f:353:27:353:33":6,"s:353:39:353:60":28,"f:365:16:365:116":7,"s:366:2:370:Infinity":29,"f:366:31:366:36":8,"s:366:51:370:4":30,"f:385:16:385:35":9,"s:386:15:386:Infinity":31,"s:387:38:416:Infinity":32,"s:418:2:418:Infinity":33,"f:418:18:418:24":10,"s:418:36:418:54":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-contracts.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-contracts.ts","statementMap":{"0":{"start":{"line":38,"column":53},"end":{"line":479,"column":null}},"1":{"start":{"line":487,"column":2},"end":{"line":487,"column":null}},"2":{"start":{"line":487,"column":35},"end":{"line":487,"column":50}},"3":{"start":{"line":495,"column":45},"end":{"line":495,"column":null}},"4":{"start":{"line":496,"column":2},"end":{"line":499,"column":null}},"5":{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},"6":{"start":{"line":497,"column":27},"end":{"line":497,"column":null}},"7":{"start":{"line":498,"column":4},"end":{"line":498,"column":null}},"8":{"start":{"line":500,"column":2},"end":{"line":500,"column":null}}},"fnMap":{"0":{"name":"getCsvContract","decl":{"start":{"line":486,"column":16},"end":{"line":486,"column":31}},"loc":{"start":{"line":486,"column":65},"end":{"line":488,"column":null}},"line":486},"1":{"name":"(anonymous_1)","decl":{"start":{"line":487,"column":23},"end":{"line":487,"column":29}},"loc":{"start":{"line":487,"column":35},"end":{"line":487,"column":50}},"line":487},"2":{"name":"contractsByDashboard","decl":{"start":{"line":494,"column":16},"end":{"line":494,"column":79}},"loc":{"start":{"line":494,"column":79},"end":{"line":501,"column":null}},"line":494}},"branchMap":{"0":{"loc":{"start":{"line":487,"column":9},"end":{"line":487,"column":null}},"type":"binary-expr","locations":[{"start":{"line":487,"column":9},"end":{"line":487,"column":55}},{"start":{"line":487,"column":55},"end":{"line":487,"column":null}}],"line":487},"1":{"loc":{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},"type":"if","locations":[{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},{"start":{},"end":{}}],"line":497}},"s":{"0":2,"1":4,"2":60,"3":1,"4":1,"5":29,"6":10,"7":29,"8":1},"f":{"0":4,"1":60,"2":1},"b":{"0":[4,2],"1":[10,19]},"meta":{"lastBranch":2,"lastFunction":3,"lastStatement":9,"seen":{"s:38:53:479:Infinity":0,"f:486:16:486:31":0,"s:487:2:487:Infinity":1,"b:487:9:487:55:487:55:487:Infinity":0,"f:487:23:487:29":1,"s:487:35:487:50":2,"f:494:16:494:79":2,"s:495:45:495:Infinity":3,"s:496:2:499:Infinity":4,"b:497:4:497:Infinity:undefined:undefined:undefined:undefined":1,"s:497:4:497:Infinity":5,"s:497:27:497:Infinity":6,"s:498:4:498:Infinity":7,"s:500:2:500:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-utils.ts","statementMap":{"0":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"2":{"start":{"line":39,"column":43},"end":{"line":39,"column":null}},"3":{"start":{"line":41,"column":17},"end":{"line":46,"column":null}},"4":{"start":{"line":45,"column":31},"end":{"line":45,"column":null}},"5":{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},"6":{"start":{"line":49,"column":25},"end":{"line":51,"column":null}},"7":{"start":{"line":50,"column":20},"end":{"line":50,"column":86}},"8":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"9":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"10":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"11":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"12":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"13":{"start":{"line":74,"column":13},"end":{"line":74,"column":null}},"14":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"15":{"start":{"line":75,"column":13},"end":{"line":75,"column":null}},"16":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"17":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"18":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"19":{"start":{"line":105,"column":25},"end":{"line":105,"column":null}},"20":{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},"21":{"start":{"line":107,"column":4},"end":{"line":107,"column":null}},"22":{"start":{"line":110,"column":2},"end":{"line":121,"column":null}},"23":{"start":{"line":111,"column":4},"end":{"line":120,"column":null}},"24":{"start":{"line":112,"column":23},"end":{"line":112,"column":null}},"25":{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},"26":{"start":{"line":113,"column":24},"end":{"line":113,"column":null}},"27":{"start":{"line":114,"column":19},"end":{"line":114,"column":null}},"28":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"29":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"30":{"start":{"line":116,"column":27},"end":{"line":116,"column":null}},"31":{"start":{"line":118,"column":22},"end":{"line":118,"column":null}},"32":{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},"33":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"34":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"35":{"start":{"line":138,"column":2},"end":{"line":139,"column":null}},"36":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}}},"fnMap":{"0":{"name":"parseCSV","decl":{"start":{"line":37,"column":16},"end":{"line":37,"column":25}},"loc":{"start":{"line":37,"column":52},"end":{"line":58,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":4},"end":{"line":45,"column":21}},"loc":{"start":{"line":45,"column":31},"end":{"line":45,"column":null}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":50,"column":7},"end":{"line":50,"column":11}},"loc":{"start":{"line":50,"column":20},"end":{"line":50,"column":86}},"line":50},"3":{"name":"(anonymous_3)","decl":{"start":{"line":55,"column":21},"end":{"line":55,"column":28}},"loc":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"line":56},"4":{"name":"(anonymous_4)","decl":{"start":{"line":56,"column":23},"end":{"line":56,"column":28}},"loc":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"line":56},"5":{"name":"joinURL","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":24}},"loc":{"start":{"line":73,"column":60},"end":{"line":79,"column":null}},"line":73},"6":{"name":"loadCSV","decl":{"start":{"line":99,"column":22},"end":{"line":99,"column":null}},"loc":{"start":{"line":104,"column":21},"end":{"line":125,"column":null}},"line":104},"7":{"name":"createLoadCSV","decl":{"start":{"line":137,"column":16},"end":{"line":137,"column":30}},"loc":{"start":{"line":137,"column":77},"end":{"line":140,"column":null}},"line":137},"8":{"name":"(anonymous_8)","decl":{"start":{"line":138,"column":2},"end":{"line":138,"column":10}},"loc":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"line":139}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":39,"column":6},"end":{"line":39,"column":43}},"type":"binary-expr","locations":[{"start":{"line":39,"column":6},"end":{"line":39,"column":18}},{"start":{"line":39,"column":18},"end":{"line":39,"column":43}}],"line":39},"2":{"loc":{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":50,"column":44},"end":{"line":50,"column":67}},"type":"binary-expr","locations":[{"start":{"line":50,"column":44},"end":{"line":50,"column":57}},{"start":{"line":50,"column":57},"end":{"line":50,"column":67}}],"line":50},"4":{"loc":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"type":"binary-expr","locations":[{"start":{"line":56,"column":37},"end":{"line":56,"column":55}},{"start":{"line":56,"column":55},"end":{"line":56,"column":78}},{"start":{"line":56,"column":78},"end":{"line":56,"column":90}}],"line":56},"5":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74},"6":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":75},"7":{"loc":{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":106},"8":{"loc":{"start":{"line":107,"column":35},"end":{"line":107,"column":60}},"type":"binary-expr","locations":[{"start":{"line":107,"column":35},"end":{"line":107,"column":51}},{"start":{"line":107,"column":51},"end":{"line":107,"column":60}}],"line":107},"9":{"loc":{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":113},"10":{"loc":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":116},"11":{"loc":{"start":{"line":118,"column":22},"end":{"line":118,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":43},"end":{"line":118,"column":55}},{"start":{"line":118,"column":55},"end":{"line":118,"column":null}}],"line":118},"12":{"loc":{"start":{"line":137,"column":50},"end":{"line":137,"column":77}},"type":"default-arg","locations":[{"start":{"line":137,"column":64},"end":{"line":137,"column":77}}],"line":137}},"s":{"0":60,"1":60,"2":1,"3":59,"4":279,"5":59,"6":1,"7":1,"8":1,"9":58,"10":167,"11":167,"12":85,"13":1,"14":84,"15":1,"16":83,"17":83,"18":83,"19":38,"20":38,"21":37,"22":38,"23":43,"24":43,"25":42,"26":8,"27":34,"28":34,"29":34,"30":34,"31":1,"32":1,"33":4,"34":4,"35":22,"36":36},"f":{"0":60,"1":279,"2":1,"3":167,"4":167,"5":85,"6":38,"7":22,"8":36},"b":{"0":[1,59],"1":[60,60],"2":[1,58],"3":[1,0],"4":[167,167,167],"5":[1,84],"6":[1,83],"7":[37,1],"8":[37,37],"9":[8,34],"10":[34,0],"11":[1,0],"12":[22]},"meta":{"lastBranch":13,"lastFunction":9,"lastStatement":37,"seen":{"f:37:16:37:25":0,"s:38:18:38:Infinity":0,"b:39:2:39:Infinity:undefined:undefined:undefined:undefined":0,"s:39:2:39:Infinity":1,"b:39:6:39:18:39:18:39:43":1,"s:39:43:39:Infinity":2,"s:41:17:46:Infinity":3,"f:45:4:45:21":1,"s:45:31:45:Infinity":4,"b:48:2:53:Infinity:undefined:undefined:undefined:undefined":2,"s:48:2:53:Infinity":5,"s:49:25:51:Infinity":6,"f:50:7:50:11":2,"s:50:20:50:86":7,"b:50:44:50:57:50:57:50:67":3,"s:52:4:52:Infinity":8,"s:55:2:57:Infinity":9,"f:55:21:55:28":3,"s:56:4:56:Infinity":10,"f:56:23:56:28":4,"s:56:37:56:90":11,"b:56:37:56:55:56:55:56:78:56:78:56:90":4,"f:73:16:73:24":5,"b:74:2:74:Infinity:undefined:undefined:undefined:undefined":5,"s:74:2:74:Infinity":12,"s:74:13:74:Infinity":13,"b:75:2:75:Infinity:undefined:undefined:undefined:undefined":6,"s:75:2:75:Infinity":14,"s:75:13:75:Infinity":15,"s:76:22:76:Infinity":16,"s:77:22:77:Infinity":17,"s:78:2:78:Infinity":18,"f:99:22:99:Infinity":6,"s:105:25:105:Infinity":19,"b:106:2:108:Infinity:undefined:undefined:undefined:undefined":7,"s:106:2:108:Infinity":20,"s:107:4:107:Infinity":21,"b:107:35:107:51:107:51:107:60":8,"s:110:2:121:Infinity":22,"s:111:4:120:Infinity":23,"s:112:23:112:Infinity":24,"b:113:6:113:Infinity:undefined:undefined:undefined:undefined":9,"s:113:6:113:Infinity":25,"s:113:24:113:Infinity":26,"s:114:19:114:Infinity":27,"s:115:19:115:Infinity":28,"b:116:6:116:Infinity:undefined:undefined:undefined:undefined":10,"s:116:6:116:Infinity":29,"s:116:27:116:Infinity":30,"s:118:22:118:Infinity":31,"b:118:43:118:55:118:55:118:Infinity":11,"s:119:6:119:Infinity":32,"s:123:2:123:Infinity":33,"s:124:2:124:Infinity":34,"f:137:16:137:30":7,"b:137:64:137:77":12,"s:138:2:139:Infinity":35,"f:138:2:138:10":8,"s:139:4:139:Infinity":36}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/data-loader.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/data-loader.ts","statementMap":{"0":{"start":{"line":96,"column":55},"end":{"line":96,"column":null}},"1":{"start":{"line":99,"column":74},"end":{"line":99,"column":null}},"2":{"start":{"line":105,"column":56},"end":{"line":105,"column":null}},"3":{"start":{"line":108,"column":56},"end":{"line":108,"column":null}},"4":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"5":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"6":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"7":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"8":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"9":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"10":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"11":{"start":{"line":150,"column":4},"end":{"line":150,"column":null}},"12":{"start":{"line":155,"column":4},"end":{"line":155,"column":null}},"13":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"14":{"start":{"line":169,"column":4},"end":{"line":169,"column":null}},"15":{"start":{"line":174,"column":4},"end":{"line":174,"column":null}},"16":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"17":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"18":{"start":{"line":189,"column":4},"end":{"line":189,"column":null}},"19":{"start":{"line":198,"column":6},"end":{"line":209,"column":null}},"20":{"start":{"line":211,"column":4},"end":{"line":222,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":113,"column":2},"end":{"line":113,"column":16}},"loc":{"start":{"line":113,"column":16},"end":{"line":117,"column":null}},"line":113},"1":{"name":"(anonymous_1)","decl":{"start":{"line":124,"column":2},"end":{"line":124,"column":11}},"loc":{"start":{"line":124,"column":38},"end":{"line":126,"column":null}},"line":124},"2":{"name":"(anonymous_2)","decl":{"start":{"line":134,"column":8},"end":{"line":134,"column":16}},"loc":{"start":{"line":134,"column":77},"end":{"line":136,"column":null}},"line":134},"3":{"name":"(anonymous_3)","decl":{"start":{"line":139,"column":8},"end":{"line":139,"column":60}},"loc":{"start":{"line":139,"column":60},"end":{"line":141,"column":null}},"line":139},"4":{"name":"(anonymous_4)","decl":{"start":{"line":144,"column":8},"end":{"line":144,"column":58}},"loc":{"start":{"line":144,"column":58},"end":{"line":146,"column":null}},"line":144},"5":{"name":"(anonymous_5)","decl":{"start":{"line":149,"column":8},"end":{"line":149,"column":58}},"loc":{"start":{"line":149,"column":58},"end":{"line":151,"column":null}},"line":149},"6":{"name":"(anonymous_6)","decl":{"start":{"line":154,"column":8},"end":{"line":154,"column":58}},"loc":{"start":{"line":154,"column":58},"end":{"line":156,"column":null}},"line":154},"7":{"name":"(anonymous_7)","decl":{"start":{"line":159,"column":8},"end":{"line":159,"column":58}},"loc":{"start":{"line":159,"column":58},"end":{"line":161,"column":null}},"line":159},"8":{"name":"(anonymous_8)","decl":{"start":{"line":168,"column":8},"end":{"line":168,"column":54}},"loc":{"start":{"line":168,"column":54},"end":{"line":170,"column":null}},"line":168},"9":{"name":"(anonymous_9)","decl":{"start":{"line":173,"column":8},"end":{"line":173,"column":60}},"loc":{"start":{"line":173,"column":60},"end":{"line":175,"column":null}},"line":173},"10":{"name":"(anonymous_10)","decl":{"start":{"line":178,"column":8},"end":{"line":178,"column":59}},"loc":{"start":{"line":178,"column":59},"end":{"line":180,"column":null}},"line":178},"11":{"name":"(anonymous_11)","decl":{"start":{"line":183,"column":8},"end":{"line":183,"column":67}},"loc":{"start":{"line":183,"column":67},"end":{"line":185,"column":null}},"line":183},"12":{"name":"(anonymous_12)","decl":{"start":{"line":188,"column":8},"end":{"line":188,"column":61}},"loc":{"start":{"line":188,"column":61},"end":{"line":190,"column":null}},"line":188},"13":{"name":"(anonymous_13)","decl":{"start":{"line":196,"column":8},"end":{"line":196,"column":43}},"loc":{"start":{"line":196,"column":43},"end":{"line":223,"column":null}},"line":196}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":21,"5":21,"6":21,"7":5,"8":2,"9":0,"10":9,"11":1,"12":1,"13":0,"14":2,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1},"f":{"0":21,"1":5,"2":2,"3":0,"4":9,"5":1,"6":1,"7":0,"8":2,"9":1,"10":1,"11":1,"12":1,"13":1},"b":{},"meta":{"lastBranch":0,"lastFunction":14,"lastStatement":21,"seen":{"s:96:55:96:Infinity":0,"s:99:74:99:Infinity":1,"s:105:56:105:Infinity":2,"s:108:56:108:Infinity":3,"f:113:2:113:16":0,"s:114:4:114:Infinity":4,"s:115:4:115:Infinity":5,"s:116:4:116:Infinity":6,"f:124:2:124:11":1,"s:125:4:125:Infinity":7,"f:134:8:134:16":2,"s:135:4:135:Infinity":8,"f:139:8:139:60":3,"s:140:4:140:Infinity":9,"f:144:8:144:58":4,"s:145:4:145:Infinity":10,"f:149:8:149:58":5,"s:150:4:150:Infinity":11,"f:154:8:154:58":6,"s:155:4:155:Infinity":12,"f:159:8:159:58":7,"s:160:4:160:Infinity":13,"f:168:8:168:54":8,"s:169:4:169:Infinity":14,"f:173:8:173:60":9,"s:174:4:174:Infinity":15,"f:178:8:178:59":10,"s:179:4:179:Infinity":16,"f:183:8:183:67":11,"s:184:4:184:Infinity":17,"f:188:8:188:61":12,"s:189:4:189:Infinity":18,"f:196:8:196:43":13,"s:198:6:209:Infinity":19,"s:211:4:222:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-validator.ts","statementMap":{"0":{"start":{"line":36,"column":4},"end":{"line":40,"column":null}},"1":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"6":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"7":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"8":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"9":{"start":{"line":65,"column":18},"end":{"line":65,"column":null}},"10":{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},"11":{"start":{"line":67,"column":4},"end":{"line":72,"column":null}},"12":{"start":{"line":75,"column":21},"end":{"line":75,"column":null}},"13":{"start":{"line":76,"column":20},"end":{"line":76,"column":null}},"14":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"15":{"start":{"line":77,"column":57},"end":{"line":77,"column":74}},"16":{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},"17":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"18":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"19":{"start":{"line":93,"column":2},"end":{"line":102,"column":null}},"20":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"21":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"22":{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},"23":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"24":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"25":{"start":{"line":101,"column":4},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"loc":{"start":{"line":35,"column":4},"end":{"line":46,"column":null}},"line":35},"1":{"name":"validateCsvRows","decl":{"start":{"line":57,"column":16},"end":{"line":57,"column":null}},"loc":{"start":{"line":61,"column":16},"end":{"line":82,"column":null}},"line":61},"2":{"name":"(anonymous_2)","decl":{"start":{"line":77,"column":43},"end":{"line":77,"column":51}},"loc":{"start":{"line":77,"column":57},"end":{"line":77,"column":74}},"line":77},"3":{"name":"validateCsvRowsLenient","decl":{"start":{"line":89,"column":16},"end":{"line":89,"column":null}},"loc":{"start":{"line":92,"column":11},"end":{"line":103,"column":null}},"line":92}},"branchMap":{"0":{"loc":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"type":"binary-expr","locations":[{"start":{"line":62,"column":19},"end":{"line":62,"column":39}},{"start":{"line":62,"column":39},"end":{"line":62,"column":null}}],"line":62},"1":{"loc":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":65,"column":18},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":18},"end":{"line":65,"column":38}},{"start":{"line":65,"column":38},"end":{"line":65,"column":null}}],"line":65},"3":{"loc":{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":66},"4":{"loc":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":16},"end":{"line":70,"column":39}},{"start":{"line":70,"column":39},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"6":{"loc":{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},{"start":{},"end":{}}],"line":97}},"s":{"0":7,"1":7,"2":7,"3":7,"4":7,"5":7,"6":11,"7":11,"8":2,"9":9,"10":11,"11":3,"12":6,"13":6,"14":6,"15":25,"16":6,"17":3,"18":3,"19":2,"20":2,"21":2,"22":1,"23":1,"24":1,"25":0},"f":{"0":7,"1":11,"2":25,"3":2},"b":{"0":[11,4],"1":[2,9],"2":[9,4],"3":[3,8],"4":[1,2],"5":[3,3],"6":[1,0]},"meta":{"lastBranch":7,"lastFunction":4,"lastStatement":26,"seen":{"f:30:2:30:Infinity":0,"s:36:4:40:Infinity":0,"s:41:4:41:Infinity":1,"s:42:4:42:Infinity":2,"s:43:4:43:Infinity":3,"s:44:4:44:Infinity":4,"s:45:4:45:Infinity":5,"f:57:16:57:Infinity":1,"s:62:19:62:Infinity":6,"b:62:19:62:39:62:39:62:Infinity":0,"b:63:2:63:Infinity:undefined:undefined:undefined:undefined":1,"s:63:2:63:Infinity":7,"s:63:17:63:Infinity":8,"s:65:18:65:Infinity":9,"b:65:18:65:38:65:38:65:Infinity":2,"b:66:2:73:Infinity:undefined:undefined:undefined:undefined":3,"s:66:2:73:Infinity":10,"s:67:4:72:Infinity":11,"b:70:16:70:39:70:39:70:Infinity":4,"s:75:21:75:Infinity":12,"s:76:20:76:Infinity":13,"s:77:18:77:Infinity":14,"f:77:43:77:51":2,"s:77:57:77:74":15,"b:78:2:80:Infinity:undefined:undefined:undefined:undefined":5,"s:78:2:80:Infinity":16,"s:79:4:79:Infinity":17,"s:81:2:81:Infinity":18,"f:89:16:89:Infinity":3,"s:93:2:102:Infinity":19,"s:94:4:94:Infinity":20,"s:95:4:95:Infinity":21,"b:97:4:100:Infinity:undefined:undefined:undefined:undefined":6,"s:97:4:100:Infinity":22,"s:98:6:98:Infinity":23,"s:99:6:99:Infinity":24,"s:101:4:101:Infinity":25}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/committees.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/committees.ts","statementMap":{"0":{"start":{"line":38,"column":35},"end":{"line":41,"column":null}},"1":{"start":{"line":43,"column":46},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":46,"column":null}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"4":{"start":{"line":48,"column":24},"end":{"line":48,"column":null}},"5":{"start":{"line":50,"column":45},"end":{"line":50,"column":null}},"6":{"start":{"line":51,"column":2},"end":{"line":60,"column":null}},"7":{"start":{"line":52,"column":17},"end":{"line":52,"column":null}},"8":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"9":{"start":{"line":53,"column":15},"end":{"line":53,"column":null}},"10":{"start":{"line":54,"column":21},"end":{"line":54,"column":null}},"11":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"12":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"13":{"start":{"line":62,"column":39},"end":{"line":94,"column":null}},"14":{"start":{"line":64,"column":19},"end":{"line":64,"column":null}},"15":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"16":{"start":{"line":66,"column":30},"end":{"line":66,"column":null}},"17":{"start":{"line":67,"column":27},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":33},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":33},"end":{"line":69,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":85,"column":null}},"21":{"start":{"line":88,"column":6},"end":{"line":91,"column":null}},"22":{"start":{"line":94,"column":20},"end":{"line":94,"column":63}},"23":{"start":{"line":96,"column":31},"end":{"line":100,"column":null}},"24":{"start":{"line":96,"column":52},"end":{"line":100,"column":4}},"25":{"start":{"line":102,"column":31},"end":{"line":102,"column":null}},"26":{"start":{"line":103,"column":2},"end":{"line":117,"column":null}},"27":{"start":{"line":103,"column":15},"end":{"line":103,"column":18}},"28":{"start":{"line":104,"column":4},"end":{"line":116,"column":null}},"29":{"start":{"line":104,"column":17},"end":{"line":104,"column":24}},"30":{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},"31":{"start":{"line":109,"column":8},"end":{"line":114,"column":null}},"32":{"start":{"line":119,"column":2},"end":{"line":127,"column":null}}},"fnMap":{"0":{"name":"loadCommitteeNetwork","decl":{"start":{"line":37,"column":22},"end":{"line":37,"column":43}},"loc":{"start":{"line":37,"column":88},"end":{"line":128,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":44,"column":11},"end":{"line":44,"column":19}},"loc":{"start":{"line":44,"column":24},"end":{"line":46,"column":3}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":51,"column":15},"end":{"line":51,"column":23}},"loc":{"start":{"line":51,"column":28},"end":{"line":60,"column":3}},"line":51},"3":{"name":"(anonymous_3)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":9}},"loc":{"start":{"line":63,"column":14},"end":{"line":86,"column":5}},"line":63},"4":{"name":"(anonymous_4)","decl":{"start":{"line":87,"column":5},"end":{"line":87,"column":12}},"loc":{"start":{"line":87,"column":17},"end":{"line":93,"column":5}},"line":87},"5":{"name":"(anonymous_5)","decl":{"start":{"line":94,"column":5},"end":{"line":94,"column":11}},"loc":{"start":{"line":94,"column":20},"end":{"line":94,"column":63}},"line":94},"6":{"name":"(anonymous_6)","decl":{"start":{"line":96,"column":42},"end":{"line":96,"column":46}},"loc":{"start":{"line":96,"column":52},"end":{"line":100,"column":4}},"line":96}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":36},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":36},"end":{"line":45,"column":67}},{"start":{"line":45,"column":67},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":55},"3":{"loc":{"start":{"line":55,"column":8},"end":{"line":57,"column":76}},"type":"binary-expr","locations":[{"start":{"line":55,"column":8},"end":{"line":55,"column":22}},{"start":{"line":55,"column":22},"end":{"line":55,"column":null}},{"start":{"line":56,"column":10},"end":{"line":56,"column":null}},{"start":{"line":57,"column":10},"end":{"line":57,"column":76}}],"line":55},"4":{"loc":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":19},"end":{"line":65,"column":42}},{"start":{"line":65,"column":42},"end":{"line":65,"column":null}}],"line":65},"5":{"loc":{"start":{"line":66,"column":30},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":30},"end":{"line":66,"column":62}},{"start":{"line":66,"column":62},"end":{"line":66,"column":null}}],"line":66},"6":{"loc":{"start":{"line":67,"column":27},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":27},"end":{"line":67,"column":48}},{"start":{"line":67,"column":48},"end":{"line":67,"column":null}}],"line":67},"7":{"loc":{"start":{"line":69,"column":33},"end":{"line":69,"column":null}},"type":"binary-expr","locations":[{"start":{"line":69,"column":33},"end":{"line":69,"column":68}},{"start":{"line":69,"column":68},"end":{"line":69,"column":null}}],"line":69},"8":{"loc":{"start":{"line":73,"column":22},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":22},"end":{"line":73,"column":52}},{"start":{"line":73,"column":52},"end":{"line":73,"column":null}}],"line":73},"9":{"loc":{"start":{"line":74,"column":24},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":75,"column":12},"end":{"line":75,"column":null}},{"start":{"line":76,"column":12},"end":{"line":76,"column":null}}],"line":74},"10":{"loc":{"start":{"line":80,"column":10},"end":{"line":82,"column":null}},"type":"cond-expr","locations":[{"start":{"line":81,"column":14},"end":{"line":81,"column":null}},{"start":{"line":82,"column":14},"end":{"line":82,"column":null}}],"line":80},"11":{"loc":{"start":{"line":83,"column":20},"end":{"line":83,"column":46}},"type":"binary-expr","locations":[{"start":{"line":83,"column":20},"end":{"line":83,"column":41}},{"start":{"line":83,"column":41},"end":{"line":83,"column":46}}],"line":83},"12":{"loc":{"start":{"line":89,"column":8},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},{"start":{"line":91,"column":9},"end":{"line":91,"column":47}},{"start":{"line":91,"column":47},"end":{"line":91,"column":null}}],"line":89},"13":{"loc":{"start":{"line":104,"column":24},"end":{"line":104,"column":68}},"type":"binary-expr","locations":[{"start":{"line":104,"column":24},"end":{"line":104,"column":49}},{"start":{"line":104,"column":49},"end":{"line":104,"column":68}}],"line":104},"14":{"loc":{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},{"start":{},"end":{}}],"line":105},"15":{"loc":{"start":{"line":106,"column":8},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":null}},{"start":{"line":107,"column":8},"end":{"line":107,"column":null}}],"line":106}},"s":{"0":1,"1":1,"2":1,"3":2,"4":1,"5":1,"6":1,"7":4,"8":4,"9":0,"10":4,"11":4,"12":4,"13":1,"14":4,"15":4,"16":4,"17":4,"18":4,"19":4,"20":4,"21":4,"22":1,"23":1,"24":2,"25":1,"26":1,"27":1,"28":2,"29":2,"30":1,"31":1,"32":1},"f":{"0":1,"1":2,"2":4,"3":4,"4":4,"5":1,"6":2},"b":{"0":[2,0],"1":[0,4],"2":[4,0],"3":[4,0,0,0],"4":[4,2],"5":[4,1],"6":[4,2],"7":[4,0],"8":[4,1],"9":[3,1],"10":[3,1],"11":[4,0],"12":[4,3,2,0],"13":[2,1],"14":[1,0],"15":[1,1]},"meta":{"lastBranch":16,"lastFunction":7,"lastStatement":33,"seen":{"f:37:22:37:43":0,"s:38:35:41:Infinity":0,"s:43:46:43:Infinity":1,"s:44:2:46:Infinity":2,"f:44:11:44:19":1,"s:45:4:45:Infinity":3,"b:45:36:45:67:45:67:45:Infinity":0,"s:48:24:48:Infinity":4,"s:50:45:50:Infinity":5,"s:51:2:60:Infinity":6,"f:51:15:51:23":2,"s:52:17:52:Infinity":7,"b:53:4:53:Infinity:undefined:undefined:undefined:undefined":1,"s:53:4:53:Infinity":8,"s:53:15:53:Infinity":9,"s:54:21:54:Infinity":10,"b:55:4:59:Infinity:undefined:undefined:undefined:undefined":2,"s:55:4:59:Infinity":11,"b:55:8:55:22:55:22:55:Infinity:56:10:56:Infinity:57:10:57:76":3,"s:58:6:58:Infinity":12,"s:62:39:94:Infinity":13,"f:63:5:63:9":3,"s:64:19:64:Infinity":14,"s:65:19:65:Infinity":15,"b:65:19:65:42:65:42:65:Infinity":4,"s:66:30:66:Infinity":16,"b:66:30:66:62:66:62:66:Infinity":5,"s:67:27:67:Infinity":17,"b:67:27:67:48:67:48:67:Infinity":6,"s:68:33:68:Infinity":18,"s:69:33:69:Infinity":19,"b:69:33:69:68:69:68:69:Infinity":7,"s:70:6:85:Infinity":20,"b:73:22:73:52:73:52:73:Infinity":8,"b:75:12:75:Infinity:76:12:76:Infinity":9,"b:81:14:81:Infinity:82:14:82:Infinity":10,"b:83:20:83:41:83:41:83:46":11,"f:87:5:87:12":4,"s:88:6:91:Infinity":21,"b:89:8:89:Infinity:90:8:90:Infinity:91:9:91:47:91:47:91:Infinity":12,"f:94:5:94:11":5,"s:94:20:94:63":22,"s:96:31:100:Infinity":23,"f:96:42:96:46":6,"s:96:52:100:4":24,"s:102:31:102:Infinity":25,"s:103:2:117:Infinity":26,"s:103:15:103:18":27,"s:104:4:116:Infinity":28,"s:104:17:104:24":29,"b:104:24:104:49:104:49:104:68":13,"b:105:6:115:Infinity:undefined:undefined:undefined:undefined":14,"s:105:6:115:Infinity":30,"b:106:8:106:Infinity:107:8:107:Infinity":15,"s:109:8:114:Infinity":31,"s:119:2:127:Infinity":32}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/demographics.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/demographics.ts","statementMap":{"0":{"start":{"line":29,"column":39},"end":{"line":32,"column":null}},"1":{"start":{"line":34,"column":39},"end":{"line":40,"column":null}},"2":{"start":{"line":35,"column":17},"end":{"line":35,"column":60}},"3":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"4":{"start":{"line":42,"column":47},"end":{"line":48,"column":null}},"5":{"start":{"line":43,"column":17},"end":{"line":43,"column":60}},"6":{"start":{"line":44,"column":15},"end":{"line":48,"column":6}},"7":{"start":{"line":50,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"loadDemographics","decl":{"start":{"line":28,"column":22},"end":{"line":28,"column":39}},"loc":{"start":{"line":28,"column":89},"end":{"line":58,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":5},"end":{"line":35,"column":12}},"loc":{"start":{"line":35,"column":17},"end":{"line":35,"column":60}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":9}},"loc":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":43,"column":5},"end":{"line":43,"column":12}},"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":60}},"line":43},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":9}},"loc":{"start":{"line":44,"column":15},"end":{"line":48,"column":6}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":14},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":14},"end":{"line":39,"column":36}},{"start":{"line":39,"column":36},"end":{"line":39,"column":null}}],"line":39},"1":{"loc":{"start":{"line":46,"column":24},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":24},"end":{"line":46,"column":57}},{"start":{"line":46,"column":57},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":24},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":24},"end":{"line":47,"column":57}},{"start":{"line":47,"column":57},"end":{"line":47,"column":null}}],"line":47}},"s":{"0":2,"1":2,"2":5,"3":3,"4":2,"5":5,"6":3,"7":2},"f":{"0":2,"1":5,"2":3,"3":5,"4":3},"b":{"0":[3,0],"1":[3,0],"2":[3,0]},"meta":{"lastBranch":3,"lastFunction":5,"lastStatement":8,"seen":{"f:28:22:28:39":0,"s:29:39:32:Infinity":0,"s:34:39:40:Infinity":1,"f:35:5:35:12":1,"s:35:17:35:60":2,"f:36:5:36:9":2,"s:36:15:40:6":3,"b:39:14:39:36:39:36:39:Infinity":0,"s:42:47:48:Infinity":4,"f:43:5:43:12":3,"s:43:17:43:60":5,"f:44:5:44:9":4,"s:44:15:48:6":6,"b:46:24:46:57:46:57:46:Infinity":1,"b:47:24:47:57:47:57:47:Infinity":2,"s:50:2:57:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/documents.ts","statementMap":{"0":{"start":{"line":29,"column":38},"end":{"line":32,"column":null}},"1":{"start":{"line":34,"column":45},"end":{"line":40,"column":null}},"2":{"start":{"line":35,"column":18},"end":{"line":35,"column":44}},"3":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"4":{"start":{"line":42,"column":47},"end":{"line":51,"column":null}},"5":{"start":{"line":43,"column":18},"end":{"line":43,"column":49}},"6":{"start":{"line":44,"column":15},"end":{"line":51,"column":6}},"7":{"start":{"line":53,"column":2},"end":{"line":60,"column":null}}},"fnMap":{"0":{"name":"loadDocumentActivity","decl":{"start":{"line":28,"column":22},"end":{"line":28,"column":43}},"loc":{"start":{"line":28,"column":97},"end":{"line":61,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":5},"end":{"line":35,"column":12}},"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":44}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":9}},"loc":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":43,"column":5},"end":{"line":43,"column":12}},"loc":{"start":{"line":43,"column":18},"end":{"line":43,"column":49}},"line":43},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":9}},"loc":{"start":{"line":44,"column":15},"end":{"line":51,"column":6}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":13},"end":{"line":37,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":13},"end":{"line":37,"column":34}},{"start":{"line":37,"column":34},"end":{"line":37,"column":null}}],"line":37},"1":{"loc":{"start":{"line":38,"column":21},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":21},"end":{"line":38,"column":51}},{"start":{"line":38,"column":51},"end":{"line":38,"column":null}}],"line":38},"2":{"loc":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":17},"end":{"line":39,"column":43}},{"start":{"line":39,"column":43},"end":{"line":39,"column":null}}],"line":39},"3":{"loc":{"start":{"line":45,"column":13},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":13},"end":{"line":45,"column":34}},{"start":{"line":45,"column":34},"end":{"line":45,"column":null}}],"line":45},"4":{"loc":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":14},"end":{"line":46,"column":36}},{"start":{"line":46,"column":36},"end":{"line":46,"column":null}}],"line":46},"5":{"loc":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":22},"end":{"line":47,"column":53}},{"start":{"line":47,"column":53},"end":{"line":47,"column":null}}],"line":47},"6":{"loc":{"start":{"line":48,"column":26},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":26},"end":{"line":48,"column":61}},{"start":{"line":48,"column":61},"end":{"line":48,"column":null}}],"line":48},"7":{"loc":{"start":{"line":49,"column":26},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":26},"end":{"line":49,"column":61}},{"start":{"line":49,"column":61},"end":{"line":49,"column":null}}],"line":49},"8":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":51}},{"start":{"line":50,"column":51},"end":{"line":50,"column":null}}],"line":50}},"s":{"0":2,"1":2,"2":4,"3":2,"4":2,"5":4,"6":2,"7":2},"f":{"0":2,"1":4,"2":2,"3":4,"4":2},"b":{"0":[2,0],"1":[2,0],"2":[2,0],"3":[2,0],"4":[2,0],"5":[2,0],"6":[2,0],"7":[2,0],"8":[2,0]},"meta":{"lastBranch":9,"lastFunction":5,"lastStatement":8,"seen":{"f:28:22:28:43":0,"s:29:38:32:Infinity":0,"s:34:45:40:Infinity":1,"f:35:5:35:12":1,"s:35:18:35:44":2,"f:36:5:36:9":2,"s:36:15:40:6":3,"b:37:13:37:34:37:34:37:Infinity":0,"b:38:21:38:51:38:51:38:Infinity":1,"b:39:17:39:43:39:43:39:Infinity":2,"s:42:47:51:Infinity":4,"f:43:5:43:12":3,"s:43:18:43:49":5,"f:44:5:44:9":4,"s:44:15:51:6":6,"b:45:13:45:34:45:34:45:Infinity":3,"b:46:14:46:36:46:36:46:Infinity":4,"b:47:22:47:53:47:53:47:Infinity":5,"b:48:26:48:61:48:61:48:Infinity":6,"b:49:26:49:61:49:61:49:Infinity":7,"b:50:21:50:51:50:51:50:Infinity":8,"s:53:2:60:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/ministries.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/ministries.ts","statementMap":{"0":{"start":{"line":25,"column":15},"end":{"line":25,"column":null}},"1":{"start":{"line":27,"column":38},"end":{"line":37,"column":null}},"2":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"3":{"start":{"line":29,"column":15},"end":{"line":36,"column":6}},"4":{"start":{"line":37,"column":20},"end":{"line":37,"column":61}},"5":{"start":{"line":39,"column":2},"end":{"line":45,"column":null}}},"fnMap":{"0":{"name":"loadMinistryDashboard","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":44}},"loc":{"start":{"line":24,"column":90},"end":{"line":46,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":5},"end":{"line":28,"column":12}},"loc":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"line":28},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":5},"end":{"line":29,"column":9}},"loc":{"start":{"line":29,"column":15},"end":{"line":36,"column":6}},"line":29},"3":{"name":"(anonymous_3)","decl":{"start":{"line":37,"column":5},"end":{"line":37,"column":11}},"loc":{"start":{"line":37,"column":20},"end":{"line":37,"column":61}},"line":37}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"type":"binary-expr","locations":[{"start":{"line":28,"column":17},"end":{"line":28,"column":37}},{"start":{"line":28,"column":37},"end":{"line":28,"column":72}}],"line":28},"1":{"loc":{"start":{"line":31,"column":22},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":22},"end":{"line":31,"column":63}},{"start":{"line":31,"column":63},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":26},"end":{"line":32,"column":61}},{"start":{"line":32,"column":61},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":24},"end":{"line":33,"column":57}},{"start":{"line":33,"column":57},"end":{"line":33,"column":null}}],"line":33},"4":{"loc":{"start":{"line":34,"column":13},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":13},"end":{"line":34,"column":34}},{"start":{"line":34,"column":34},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":16},"end":{"line":35,"column":40}},{"start":{"line":35,"column":40},"end":{"line":35,"column":null}}],"line":35}},"s":{"0":2,"1":2,"2":5,"3":3,"4":1,"5":2},"f":{"0":2,"1":5,"2":3,"3":1},"b":{"0":[5,5],"1":[3,0],"2":[3,0],"3":[3,0],"4":[3,0],"5":[3,0]},"meta":{"lastBranch":6,"lastFunction":4,"lastStatement":6,"seen":{"f:24:22:24:44":0,"s:25:15:25:Infinity":0,"s:27:38:37:Infinity":1,"f:28:5:28:12":1,"s:28:17:28:72":2,"b:28:17:28:37:28:37:28:72":0,"f:29:5:29:9":2,"s:29:15:36:6":3,"b:31:22:31:63:31:63:31:Infinity":1,"b:32:26:32:61:32:61:32:Infinity":2,"b:33:24:33:57:33:57:33:Infinity":3,"b:34:13:34:34:34:34:34:Infinity":4,"b:35:16:35:40:35:40:35:Infinity":5,"f:37:5:37:11":3,"s:37:20:37:61":4,"s:39:2:45:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/election.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/election.ts","statementMap":{"0":{"start":{"line":19,"column":6},"end":{"line":26,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":20,"column":59},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"4":{"start":{"line":22,"column":16},"end":{"line":22,"column":null}},"5":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"6":{"start":{"line":23,"column":30},"end":{"line":23,"column":null}},"7":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"8":{"start":{"line":28,"column":6},"end":{"line":36,"column":null}},"9":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"10":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"11":{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},"12":{"start":{"line":31,"column":23},"end":{"line":31,"column":null}},"13":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"14":{"start":{"line":32,"column":31},"end":{"line":32,"column":null}},"15":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"16":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"17":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"18":{"start":{"line":46,"column":39},"end":{"line":49,"column":null}},"19":{"start":{"line":51,"column":18},"end":{"line":76,"column":null}},"20":{"start":{"line":52,"column":17},"end":{"line":52,"column":null}},"21":{"start":{"line":53,"column":25},"end":{"line":53,"column":null}},"22":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"23":{"start":{"line":55,"column":19},"end":{"line":55,"column":null}},"24":{"start":{"line":56,"column":22},"end":{"line":56,"column":null}},"25":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"26":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"27":{"start":{"line":62,"column":26},"end":{"line":62,"column":null}},"28":{"start":{"line":63,"column":26},"end":{"line":63,"column":null}},"29":{"start":{"line":65,"column":4},"end":{"line":75,"column":null}},"30":{"start":{"line":78,"column":29},"end":{"line":108,"column":null}},"31":{"start":{"line":79,"column":17},"end":{"line":79,"column":null}},"32":{"start":{"line":80,"column":24},"end":{"line":80,"column":null}},"33":{"start":{"line":81,"column":23},"end":{"line":81,"column":null}},"34":{"start":{"line":82,"column":21},"end":{"line":82,"column":null}},"35":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"36":{"start":{"line":84,"column":24},"end":{"line":87,"column":null}},"37":{"start":{"line":86,"column":16},"end":{"line":86,"column":24}},"38":{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},"39":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"40":{"start":{"line":100,"column":4},"end":{"line":107,"column":null}},"41":{"start":{"line":110,"column":2},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":6},"end":{"line":19,"column":24}},"loc":{"start":{"line":19,"column":63},"end":{"line":26,"column":null}},"line":19},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":6},"end":{"line":28,"column":19}},"loc":{"start":{"line":28,"column":59},"end":{"line":36,"column":null}},"line":28},"2":{"name":"loadElectionAnalysis","decl":{"start":{"line":45,"column":22},"end":{"line":45,"column":43}},"loc":{"start":{"line":45,"column":88},"end":{"line":122,"column":null}},"line":45},"3":{"name":"(anonymous_3)","decl":{"start":{"line":51,"column":31},"end":{"line":51,"column":39}},"loc":{"start":{"line":51,"column":44},"end":{"line":76,"column":3}},"line":51},"4":{"name":"(anonymous_4)","decl":{"start":{"line":78,"column":42},"end":{"line":78,"column":50}},"loc":{"start":{"line":78,"column":55},"end":{"line":108,"column":3}},"line":78},"5":{"name":"(anonymous_5)","decl":{"start":{"line":86,"column":7},"end":{"line":86,"column":11}},"loc":{"start":{"line":86,"column":16},"end":{"line":86,"column":24}},"line":86}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"1":{"loc":{"start":{"line":20,"column":6},"end":{"line":20,"column":59}},"type":"binary-expr","locations":[{"start":{"line":20,"column":6},"end":{"line":20,"column":35}},{"start":{"line":20,"column":35},"end":{"line":20,"column":59}}],"line":20},"2":{"loc":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":21},"3":{"loc":{"start":{"line":21,"column":6},"end":{"line":21,"column":56}},"type":"binary-expr","locations":[{"start":{"line":21,"column":6},"end":{"line":21,"column":35}},{"start":{"line":21,"column":35},"end":{"line":21,"column":56}}],"line":21},"4":{"loc":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23},"5":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},{"start":{},"end":{}}],"line":29},"6":{"loc":{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":30},"7":{"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"8":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"9":{"loc":{"start":{"line":52,"column":24},"end":{"line":52,"column":36}},"type":"binary-expr","locations":[{"start":{"line":52,"column":24},"end":{"line":52,"column":34}},{"start":{"line":52,"column":34},"end":{"line":52,"column":36}}],"line":52},"10":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":58},"11":{"loc":{"start":{"line":58,"column":8},"end":{"line":58,"column":128}},"type":"binary-expr","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":17}},{"start":{"line":58,"column":17},"end":{"line":58,"column":47}},{"start":{"line":58,"column":47},"end":{"line":58,"column":79}},{"start":{"line":58,"column":79},"end":{"line":58,"column":103}},{"start":{"line":58,"column":103},"end":{"line":58,"column":128}}],"line":58},"12":{"loc":{"start":{"line":72,"column":8},"end":{"line":74,"column":null}},"type":"cond-expr","locations":[{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},{"start":{"line":74,"column":12},"end":{"line":74,"column":null}}],"line":72},"13":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},{"start":{"line":72,"column":39},"end":{"line":72,"column":null}}],"line":72},"14":{"loc":{"start":{"line":79,"column":24},"end":{"line":79,"column":36}},"type":"binary-expr","locations":[{"start":{"line":79,"column":24},"end":{"line":79,"column":34}},{"start":{"line":79,"column":34},"end":{"line":79,"column":36}}],"line":79},"15":{"loc":{"start":{"line":83,"column":29},"end":{"line":83,"column":46}},"type":"binary-expr","locations":[{"start":{"line":83,"column":29},"end":{"line":83,"column":44}},{"start":{"line":83,"column":44},"end":{"line":83,"column":46}}],"line":83},"16":{"loc":{"start":{"line":84,"column":31},"end":{"line":84,"column":50}},"type":"binary-expr","locations":[{"start":{"line":84,"column":31},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":50}}],"line":84},"17":{"loc":{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":89},"18":{"loc":{"start":{"line":90,"column":6},"end":{"line":95,"column":null}},"type":"binary-expr","locations":[{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},{"start":{"line":93,"column":6},"end":{"line":93,"column":null}},{"start":{"line":94,"column":6},"end":{"line":94,"column":null}},{"start":{"line":95,"column":6},"end":{"line":95,"column":null}}],"line":90}},"s":{"0":4,"1":376,"2":370,"3":6,"4":0,"5":0,"6":0,"7":6,"8":4,"9":30,"10":29,"11":1,"12":1,"13":1,"14":0,"15":1,"16":0,"17":1,"18":10,"19":10,"20":53,"21":53,"22":53,"23":53,"24":53,"25":53,"26":1,"27":52,"28":52,"29":52,"30":10,"31":30,"32":30,"33":30,"34":30,"35":30,"36":30,"37":107,"38":30,"39":3,"40":27,"41":10},"f":{"0":376,"1":30,"2":10,"3":53,"4":30,"5":107},"b":{"0":[370,6],"1":[376,370],"2":[0,6],"3":[6,0],"4":[0,0],"5":[29,1],"6":[1,0],"7":[0,1],"8":[0,1],"9":[53,0],"10":[1,52],"11":[53,53,52,52,52],"12":[50,2],"13":[52,50],"14":[30,0],"15":[30,1],"16":[30,0],"17":[3,27],"18":[30,30,29,29,28,27]},"meta":{"lastBranch":19,"lastFunction":6,"lastStatement":42,"seen":{"s:19:6:26:Infinity":0,"f:19:6:19:24":0,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":0,"s:20:2:20:Infinity":1,"b:20:6:20:35:20:35:20:59":1,"s:20:59:20:Infinity":2,"b:21:2:24:Infinity:undefined:undefined:undefined:undefined":2,"s:21:2:24:Infinity":3,"b:21:6:21:35:21:35:21:56":3,"s:22:16:22:Infinity":4,"b:23:4:23:Infinity:undefined:undefined:undefined:undefined":4,"s:23:4:23:Infinity":5,"s:23:30:23:Infinity":6,"s:25:2:25:Infinity":7,"s:28:6:36:Infinity":8,"f:28:6:28:19":1,"b:29:2:29:Infinity:undefined:undefined:undefined:undefined":5,"s:29:2:29:Infinity":9,"s:29:34:29:Infinity":10,"b:30:2:34:Infinity:undefined:undefined:undefined:undefined":6,"s:30:2:34:Infinity":11,"s:31:23:31:Infinity":12,"b:32:4:32:Infinity:undefined:undefined:undefined:undefined":7,"s:32:4:32:Infinity":13,"s:32:31:32:Infinity":14,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":8,"s:33:4:33:Infinity":15,"s:33:32:33:Infinity":16,"s:35:2:35:Infinity":17,"f:45:22:45:43":2,"s:46:39:49:Infinity":18,"s:51:18:76:Infinity":19,"f:51:31:51:39":3,"s:52:17:52:Infinity":20,"b:52:24:52:34:52:34:52:36":9,"s:53:25:53:Infinity":21,"s:54:27:54:Infinity":22,"s:55:19:55:Infinity":23,"s:56:22:56:Infinity":24,"b:58:4:60:Infinity:undefined:undefined:undefined:undefined":10,"s:58:4:60:Infinity":25,"b:58:8:58:17:58:17:58:47:58:47:58:79:58:79:58:103:58:103:58:128":11,"s:59:6:59:Infinity":26,"s:62:26:62:Infinity":27,"s:63:26:63:Infinity":28,"s:65:4:75:Infinity":29,"b:73:12:73:Infinity:74:12:74:Infinity":12,"b:72:8:72:39:72:39:72:Infinity":13,"s:78:29:108:Infinity":30,"f:78:42:78:50":4,"s:79:17:79:Infinity":31,"b:79:24:79:34:79:34:79:36":14,"s:80:24:80:Infinity":32,"s:81:23:81:Infinity":33,"s:82:21:82:Infinity":34,"s:83:22:83:Infinity":35,"b:83:29:83:44:83:44:83:46":15,"s:84:24:87:Infinity":36,"b:84:31:84:48:84:48:84:50":16,"f:86:7:86:11":5,"s:86:16:86:24":37,"b:89:4:98:Infinity:undefined:undefined:undefined:undefined":17,"s:89:4:98:Infinity":38,"b:90:6:90:Infinity:91:6:91:Infinity:92:6:92:Infinity:93:6:93:Infinity:94:6:94:Infinity:95:6:95:Infinity":18,"s:97:6:97:Infinity":39,"s:100:4:107:Infinity":40,"s:110:2:121:Infinity":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/overview.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/overview.ts","statementMap":{"0":{"start":{"line":27,"column":77},"end":{"line":33,"column":null}},"1":{"start":{"line":35,"column":20},"end":{"line":35,"column":null}},"2":{"start":{"line":35,"column":43},"end":{"line":35,"column":87}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":24},"end":{"line":40,"column":null}},"5":{"start":{"line":39,"column":25},"end":{"line":39,"column":42}},"6":{"start":{"line":39,"column":56},"end":{"line":39,"column":83}},"7":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"8":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"9":{"start":{"line":43,"column":43},"end":{"line":43,"column":66}},"10":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"11":{"start":{"line":44,"column":42},"end":{"line":44,"column":67}},"12":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"13":{"start":{"line":45,"column":42},"end":{"line":45,"column":64}},"14":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"15":{"start":{"line":46,"column":47},"end":{"line":46,"column":92}},"16":{"start":{"line":47,"column":16},"end":{"line":47,"column":null}},"17":{"start":{"line":47,"column":43},"end":{"line":47,"column":88}},"18":{"start":{"line":48,"column":16},"end":{"line":48,"column":null}},"19":{"start":{"line":48,"column":43},"end":{"line":48,"column":88}},"20":{"start":{"line":50,"column":25},"end":{"line":52,"column":null}},"21":{"start":{"line":51,"column":36},"end":{"line":51,"column":81}},"22":{"start":{"line":54,"column":31},"end":{"line":56,"column":null}},"23":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"24":{"start":{"line":59,"column":25},"end":{"line":59,"column":null}},"25":{"start":{"line":59,"column":48},"end":{"line":59,"column":87}},"26":{"start":{"line":60,"column":24},"end":{"line":62,"column":null}},"27":{"start":{"line":61,"column":49},"end":{"line":61,"column":96}},"28":{"start":{"line":64,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"loadOverviewDashboard","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":44}},"loc":{"start":{"line":26,"column":90},"end":{"line":102,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":33},"end":{"line":35,"column":38}},"loc":{"start":{"line":35,"column":43},"end":{"line":35,"column":87}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":20}},"loc":{"start":{"line":39,"column":25},"end":{"line":39,"column":42}},"line":39},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":44},"end":{"line":39,"column":51}},"loc":{"start":{"line":39,"column":56},"end":{"line":39,"column":83}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":43,"column":31},"end":{"line":43,"column":38}},"loc":{"start":{"line":43,"column":43},"end":{"line":43,"column":66}},"line":43},"5":{"name":"(anonymous_5)","decl":{"start":{"line":44,"column":30},"end":{"line":44,"column":37}},"loc":{"start":{"line":44,"column":42},"end":{"line":44,"column":67}},"line":44},"6":{"name":"(anonymous_6)","decl":{"start":{"line":45,"column":30},"end":{"line":45,"column":37}},"loc":{"start":{"line":45,"column":42},"end":{"line":45,"column":64}},"line":45},"7":{"name":"(anonymous_7)","decl":{"start":{"line":46,"column":28},"end":{"line":46,"column":36}},"loc":{"start":{"line":46,"column":47},"end":{"line":46,"column":92}},"line":46},"8":{"name":"(anonymous_8)","decl":{"start":{"line":47,"column":24},"end":{"line":47,"column":32}},"loc":{"start":{"line":47,"column":43},"end":{"line":47,"column":88}},"line":47},"9":{"name":"(anonymous_9)","decl":{"start":{"line":48,"column":24},"end":{"line":48,"column":32}},"loc":{"start":{"line":48,"column":43},"end":{"line":48,"column":88}},"line":48},"10":{"name":"(anonymous_10)","decl":{"start":{"line":51,"column":17},"end":{"line":51,"column":25}},"loc":{"start":{"line":51,"column":36},"end":{"line":51,"column":81}},"line":51},"11":{"name":"(anonymous_11)","decl":{"start":{"line":59,"column":36},"end":{"line":59,"column":43}},"loc":{"start":{"line":59,"column":48},"end":{"line":59,"column":87}},"line":59},"12":{"name":"(anonymous_12)","decl":{"start":{"line":61,"column":32},"end":{"line":61,"column":40}},"loc":{"start":{"line":61,"column":49},"end":{"line":61,"column":96}},"line":61}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":32},"end":{"line":36,"column":68}},{"start":{"line":36,"column":68},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":41,"column":23},"end":{"line":41,"column":45}},{"start":{"line":41,"column":45},"end":{"line":41,"column":null}}],"line":41},"2":{"loc":{"start":{"line":46,"column":55},"end":{"line":46,"column":92}},"type":"binary-expr","locations":[{"start":{"line":46,"column":55},"end":{"line":46,"column":88}},{"start":{"line":46,"column":88},"end":{"line":46,"column":92}}],"line":46},"3":{"loc":{"start":{"line":47,"column":51},"end":{"line":47,"column":88}},"type":"binary-expr","locations":[{"start":{"line":47,"column":51},"end":{"line":47,"column":84}},{"start":{"line":47,"column":84},"end":{"line":47,"column":88}}],"line":47},"4":{"loc":{"start":{"line":48,"column":51},"end":{"line":48,"column":88}},"type":"binary-expr","locations":[{"start":{"line":48,"column":51},"end":{"line":48,"column":84}},{"start":{"line":48,"column":84},"end":{"line":48,"column":88}}],"line":48},"5":{"loc":{"start":{"line":50,"column":25},"end":{"line":52,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}}],"line":50},"6":{"loc":{"start":{"line":51,"column":44},"end":{"line":51,"column":81}},"type":"binary-expr","locations":[{"start":{"line":51,"column":44},"end":{"line":51,"column":77}},{"start":{"line":51,"column":77},"end":{"line":51,"column":81}}],"line":51},"7":{"loc":{"start":{"line":54,"column":31},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{"line":56,"column":6},"end":{"line":56,"column":null}}],"line":54},"8":{"loc":{"start":{"line":60,"column":24},"end":{"line":62,"column":null}},"type":"cond-expr","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},{"start":{"line":62,"column":6},"end":{"line":62,"column":null}}],"line":60},"9":{"loc":{"start":{"line":61,"column":55},"end":{"line":61,"column":96}},"type":"binary-expr","locations":[{"start":{"line":61,"column":55},"end":{"line":61,"column":92}},{"start":{"line":61,"column":92},"end":{"line":61,"column":96}}],"line":61},"10":{"loc":{"start":{"line":84,"column":23},"end":{"line":84,"column":null}},"type":"binary-expr","locations":[{"start":{"line":84,"column":23},"end":{"line":84,"column":62}},{"start":{"line":84,"column":62},"end":{"line":84,"column":null}}],"line":84},"11":{"loc":{"start":{"line":85,"column":27},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":27},"end":{"line":85,"column":69}},{"start":{"line":85,"column":69},"end":{"line":85,"column":null}}],"line":85},"12":{"loc":{"start":{"line":91,"column":17},"end":{"line":91,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":39},"end":{"line":91,"column":52}},{"start":{"line":91,"column":52},"end":{"line":91,"column":null}}],"line":91},"13":{"loc":{"start":{"line":93,"column":26},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":47},"end":{"line":93,"column":56}},{"start":{"line":93,"column":56},"end":{"line":93,"column":null}}],"line":93}},"s":{"0":2,"1":2,"2":1,"3":2,"4":2,"5":5,"6":5,"7":2,"8":2,"9":5,"10":2,"11":5,"12":2,"13":5,"14":2,"15":1,"16":2,"17":1,"18":2,"19":3,"20":2,"21":3,"22":2,"23":2,"24":2,"25":4,"26":2,"27":4,"28":2},"f":{"0":2,"1":1,"2":5,"3":5,"4":5,"5":5,"6":5,"7":1,"8":1,"9":3,"10":3,"11":4,"12":4},"b":{"0":[1,1],"1":[2,1],"2":[1,0],"3":[1,0],"4":[3,0],"5":[1,1],"6":[3,0],"7":[1,1],"8":[1,1],"9":[4,0],"10":[2,1],"11":[2,1],"12":[2,0],"13":[0,2]},"meta":{"lastBranch":14,"lastFunction":13,"lastStatement":29,"seen":{"f:26:22:26:44":0,"s:27:77:33:Infinity":0,"s:35:20:35:Infinity":1,"f:35:33:35:38":1,"s:35:43:35:87":2,"s:36:19:36:Infinity":3,"b:36:32:36:68:36:68:36:Infinity":0,"s:38:24:40:Infinity":4,"f:39:16:39:20":2,"s:39:25:39:42":5,"f:39:44:39:51":3,"s:39:56:39:83":6,"s:41:23:41:Infinity":7,"b:41:23:41:45:41:45:41:Infinity":1,"s:43:19:43:Infinity":8,"f:43:31:43:38":4,"s:43:43:43:66":9,"s:44:18:44:Infinity":10,"f:44:30:44:37":5,"s:44:42:44:67":11,"s:45:18:45:Infinity":12,"f:45:30:45:37":6,"s:45:42:45:64":13,"s:46:19:46:Infinity":14,"f:46:28:46:36":7,"s:46:47:46:92":15,"b:46:55:46:88:46:88:46:92":2,"s:47:16:47:Infinity":16,"f:47:24:47:32":8,"s:47:43:47:88":17,"b:47:51:47:84:47:84:47:88":3,"s:48:16:48:Infinity":18,"f:48:24:48:32":9,"s:48:43:48:88":19,"b:48:51:48:84:48:84:48:88":4,"s:50:25:52:Infinity":20,"b:51:6:51:Infinity:52:6:52:Infinity":5,"f:51:17:51:25":10,"s:51:36:51:81":21,"b:51:44:51:77:51:77:51:81":6,"s:54:31:56:Infinity":22,"b:55:6:55:Infinity:56:6:56:Infinity":7,"s:58:22:58:Infinity":23,"s:59:25:59:Infinity":24,"f:59:36:59:43":11,"s:59:48:59:87":25,"s:60:24:62:Infinity":26,"b:61:6:61:Infinity:62:6:62:Infinity":8,"f:61:32:61:40":12,"s:61:49:61:96":27,"b:61:55:61:92:61:92:61:96":9,"s:64:2:101:Infinity":28,"b:84:23:84:62:84:62:84:Infinity":10,"b:85:27:85:69:85:69:85:Infinity":11,"b:91:39:91:52:91:52:91:Infinity":12,"b:93:47:93:56:93:56:93:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/parties.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/parties.ts","statementMap":{"0":{"start":{"line":27,"column":43},"end":{"line":31,"column":null}},"1":{"start":{"line":33,"column":28},"end":{"line":33,"column":null}},"2":{"start":{"line":33,"column":52},"end":{"line":33,"column":95}},"3":{"start":{"line":35,"column":45},"end":{"line":35,"column":null}},"4":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"5":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"6":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"7":{"start":{"line":42,"column":49},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":2},"end":{"line":55,"column":null}},"9":{"start":{"line":44,"column":17},"end":{"line":44,"column":60}},"10":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"11":{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},"12":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"13":{"start":{"line":57,"column":42},"end":{"line":59,"column":null}},"14":{"start":{"line":61,"column":32},"end":{"line":90,"column":null}},"15":{"start":{"line":62,"column":18},"end":{"line":62,"column":null}},"16":{"start":{"line":63,"column":14},"end":{"line":63,"column":null}},"17":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"18":{"start":{"line":66,"column":4},"end":{"line":89,"column":null}},"19":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"20":{"start":{"line":92,"column":19},"end":{"line":92,"column":72}},"21":{"start":{"line":94,"column":2},"end":{"line":100,"column":null}}},"fnMap":{"0":{"name":"loadPartyPerformance","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":43}},"loc":{"start":{"line":26,"column":88},"end":{"line":101,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":40},"end":{"line":33,"column":47}},"loc":{"start":{"line":33,"column":52},"end":{"line":33,"column":95}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":10},"end":{"line":36,"column":18}},"loc":{"start":{"line":36,"column":23},"end":{"line":40,"column":3}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":12}},"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":60}},"line":44},"4":{"name":"(anonymous_4)","decl":{"start":{"line":45,"column":5},"end":{"line":45,"column":13}},"loc":{"start":{"line":45,"column":18},"end":{"line":55,"column":5}},"line":45},"5":{"name":"(anonymous_5)","decl":{"start":{"line":61,"column":50},"end":{"line":61,"column":54}},"loc":{"start":{"line":61,"column":59},"end":{"line":90,"column":3}},"line":61},"6":{"name":"(anonymous_6)","decl":{"start":{"line":92,"column":10},"end":{"line":92,"column":16}},"loc":{"start":{"line":92,"column":19},"end":{"line":92,"column":72}},"line":92}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":48,"column":8},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":8},"end":{"line":48,"column":null}},{"start":{"line":49,"column":9},"end":{"line":49,"column":null}},{"start":{"line":50,"column":10},"end":{"line":50,"column":null}},{"start":{"line":51,"column":11},"end":{"line":51,"column":null}}],"line":48},"3":{"loc":{"start":{"line":63,"column":14},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":14},"end":{"line":63,"column":35}},{"start":{"line":63,"column":35},"end":{"line":63,"column":null}}],"line":63},"4":{"loc":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"type":"binary-expr","locations":[{"start":{"line":64,"column":16},"end":{"line":64,"column":41}},{"start":{"line":64,"column":41},"end":{"line":64,"column":null}}],"line":64},"5":{"loc":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"type":"binary-expr","locations":[{"start":{"line":68,"column":18},"end":{"line":68,"column":45}},{"start":{"line":68,"column":45},"end":{"line":68,"column":null}}],"line":68},"6":{"loc":{"start":{"line":71,"column":15},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":15},"end":{"line":71,"column":33}},{"start":{"line":71,"column":33},"end":{"line":71,"column":null}}],"line":71},"7":{"loc":{"start":{"line":73,"column":22},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":22},"end":{"line":73,"column":53}},{"start":{"line":73,"column":53},"end":{"line":73,"column":null}}],"line":73},"8":{"loc":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":28},"end":{"line":74,"column":64}},{"start":{"line":74,"column":64},"end":{"line":74,"column":null}}],"line":74},"9":{"loc":{"start":{"line":75,"column":27},"end":{"line":75,"column":null}},"type":"binary-expr","locations":[{"start":{"line":75,"column":27},"end":{"line":75,"column":61}},{"start":{"line":75,"column":61},"end":{"line":75,"column":null}}],"line":75},"10":{"loc":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":22},"end":{"line":76,"column":51}},{"start":{"line":76,"column":51},"end":{"line":76,"column":null}}],"line":76},"11":{"loc":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":21},"end":{"line":79,"column":59}},{"start":{"line":79,"column":59},"end":{"line":79,"column":null}}],"line":79},"12":{"loc":{"start":{"line":80,"column":24},"end":{"line":80,"column":null}},"type":"binary-expr","locations":[{"start":{"line":80,"column":24},"end":{"line":80,"column":63}},{"start":{"line":80,"column":63},"end":{"line":80,"column":null}}],"line":80},"13":{"loc":{"start":{"line":81,"column":24},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":24},"end":{"line":81,"column":55}},{"start":{"line":81,"column":55},"end":{"line":81,"column":null}}],"line":81},"14":{"loc":{"start":{"line":84,"column":24},"end":{"line":84,"column":66}},"type":"binary-expr","locations":[{"start":{"line":84,"column":24},"end":{"line":84,"column":58}},{"start":{"line":84,"column":58},"end":{"line":84,"column":66}}],"line":84},"15":{"loc":{"start":{"line":85,"column":25},"end":{"line":85,"column":76}},"type":"binary-expr","locations":[{"start":{"line":85,"column":25},"end":{"line":85,"column":68}},{"start":{"line":85,"column":68},"end":{"line":85,"column":76}}],"line":85},"16":{"loc":{"start":{"line":86,"column":27},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":27},"end":{"line":86,"column":62}},{"start":{"line":86,"column":62},"end":{"line":86,"column":96}},{"start":{"line":86,"column":96},"end":{"line":86,"column":null}}],"line":86},"17":{"loc":{"start":{"line":92,"column":26},"end":{"line":92,"column":51}},"type":"binary-expr","locations":[{"start":{"line":92,"column":26},"end":{"line":92,"column":45}},{"start":{"line":92,"column":45},"end":{"line":92,"column":51}}],"line":92},"18":{"loc":{"start":{"line":92,"column":51},"end":{"line":92,"column":72}},"type":"binary-expr","locations":[{"start":{"line":92,"column":51},"end":{"line":92,"column":70}},{"start":{"line":92,"column":70},"end":{"line":92,"column":72}}],"line":92}},"s":{"0":2,"1":2,"2":4,"3":2,"4":2,"5":3,"6":3,"7":2,"8":2,"9":4,"10":4,"11":4,"12":4,"13":2,"14":2,"15":3,"16":3,"17":3,"18":3,"19":2,"20":1,"21":2},"f":{"0":2,"1":4,"2":3,"3":4,"4":4,"5":3,"6":1},"b":{"0":[3,0],"1":[4,0],"2":[4,1,1,1],"3":[3,0],"4":[3,0],"5":[3,0],"6":[3,0],"7":[3,0],"8":[3,0],"9":[3,0],"10":[3,0],"11":[3,1],"12":[3,1],"13":[3,1],"14":[3,0],"15":[3,0],"16":[3,1,0],"17":[1,0],"18":[1,0]},"meta":{"lastBranch":19,"lastFunction":7,"lastStatement":22,"seen":{"f:26:22:26:43":0,"s:27:43:31:Infinity":0,"s:33:28:33:Infinity":1,"f:33:40:33:47":1,"s:33:52:33:95":2,"s:35:45:35:Infinity":3,"s:36:2:40:Infinity":4,"f:36:10:36:18":2,"b:37:4:39:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:39:Infinity":5,"s:38:6:38:Infinity":6,"s:42:49:42:Infinity":7,"s:43:2:55:Infinity":8,"f:44:5:44:12":3,"s:44:17:44:60":9,"f:45:5:45:13":4,"s:46:20:46:Infinity":10,"b:47:6:54:Infinity:undefined:undefined:undefined:undefined":1,"s:47:6:54:Infinity":11,"b:48:8:48:Infinity:49:9:49:Infinity:50:10:50:Infinity:51:11:51:Infinity":2,"s:53:8:53:Infinity":12,"s:57:42:59:Infinity":13,"s:61:32:90:Infinity":14,"f:61:50:61:54":5,"s:62:18:62:Infinity":15,"s:63:14:63:Infinity":16,"b:63:14:63:35:63:35:63:Infinity":3,"s:64:16:64:Infinity":17,"b:64:16:64:41:64:41:64:Infinity":4,"s:66:4:89:Infinity":18,"b:68:18:68:45:68:45:68:Infinity":5,"b:71:15:71:33:71:33:71:Infinity":6,"b:73:22:73:53:73:53:73:Infinity":7,"b:74:28:74:64:74:64:74:Infinity":8,"b:75:27:75:61:75:61:75:Infinity":9,"b:76:22:76:51:76:51:76:Infinity":10,"b:79:21:79:59:79:59:79:Infinity":11,"b:80:24:80:63:80:63:80:Infinity":12,"b:81:24:81:55:81:55:81:Infinity":13,"b:84:24:84:58:84:58:84:66":14,"b:85:25:85:68:85:68:85:76":15,"b:86:27:86:62:86:62:86:96:86:96:86:Infinity":16,"s:92:2:92:Infinity":19,"f:92:10:92:16":6,"s:92:19:92:72":20,"b:92:26:92:45:92:45:92:51":17,"b:92:51:92:70:92:70:92:72":18,"s:94:2:100:Infinity":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/risk.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/risk.ts","statementMap":{"0":{"start":{"line":25,"column":15},"end":{"line":25,"column":null}},"1":{"start":{"line":27,"column":40},"end":{"line":34,"column":null}},"2":{"start":{"line":28,"column":18},"end":{"line":28,"column":51}},"3":{"start":{"line":29,"column":15},"end":{"line":34,"column":6}},"4":{"start":{"line":36,"column":2},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"loadRiskEvolution","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":40}},"loc":{"start":{"line":24,"column":91},"end":{"line":43,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":5},"end":{"line":28,"column":12}},"loc":{"start":{"line":28,"column":18},"end":{"line":28,"column":51}},"line":28},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":5},"end":{"line":29,"column":9}},"loc":{"start":{"line":29,"column":15},"end":{"line":34,"column":6}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":15},"end":{"line":30,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":15},"end":{"line":30,"column":49}},{"start":{"line":30,"column":49},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":31,"column":17},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":17},"end":{"line":31,"column":47}},{"start":{"line":31,"column":47},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":24},"end":{"line":32,"column":57}},{"start":{"line":32,"column":57},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":21},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":21},"end":{"line":33,"column":52}},{"start":{"line":33,"column":52},"end":{"line":33,"column":null}}],"line":33}},"s":{"0":2,"1":2,"2":5,"3":3,"4":2},"f":{"0":2,"1":5,"2":3},"b":{"0":[3,0],"1":[3,0],"2":[3,0],"3":[3,0]},"meta":{"lastBranch":4,"lastFunction":3,"lastStatement":5,"seen":{"f:24:22:24:40":0,"s:25:15:25:Infinity":0,"s:27:40:34:Infinity":1,"f:28:5:28:12":1,"s:28:18:28:51":2,"f:29:5:29:9":2,"s:29:15:34:6":3,"b:30:15:30:49:30:49:30:Infinity":0,"b:31:17:31:47:31:47:31:Infinity":1,"b:32:24:32:57:32:57:32:Infinity":2,"b:33:21:33:52:33:52:33:Infinity":3,"s:36:2:42:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/top10.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/top10.ts","statementMap":{"0":{"start":{"line":27,"column":35},"end":{"line":30,"column":null}},"1":{"start":{"line":32,"column":42},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"4":{"start":{"line":37,"column":17},"end":{"line":40,"column":null}},"5":{"start":{"line":38,"column":19},"end":{"line":38,"column":56}},"6":{"start":{"line":39,"column":14},"end":{"line":39,"column":103}},"7":{"start":{"line":42,"column":32},"end":{"line":63,"column":null}},"8":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"9":{"start":{"line":44,"column":4},"end":{"line":62,"column":null}},"10":{"start":{"line":54,"column":45},"end":{"line":54,"column":60}},"11":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"loadTop10Influential","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":43}},"loc":{"start":{"line":26,"column":88},"end":{"line":73,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":14},"end":{"line":33,"column":22}},"loc":{"start":{"line":33,"column":27},"end":{"line":35,"column":3}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":38,"column":5},"end":{"line":38,"column":12}},"loc":{"start":{"line":38,"column":19},"end":{"line":38,"column":56}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":5},"end":{"line":39,"column":11}},"loc":{"start":{"line":39,"column":14},"end":{"line":39,"column":103}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":42,"column":39},"end":{"line":42,"column":44}},"loc":{"start":{"line":42,"column":56},"end":{"line":63,"column":3}},"line":42},"5":{"name":"(anonymous_5)","decl":{"start":{"line":54,"column":21},"end":{"line":54,"column":31}},"loc":{"start":{"line":54,"column":45},"end":{"line":54,"column":60}},"line":54}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":22},"end":{"line":39,"column":65}},"type":"binary-expr","locations":[{"start":{"line":39,"column":22},"end":{"line":39,"column":58}},{"start":{"line":39,"column":58},"end":{"line":39,"column":65}}],"line":39},"1":{"loc":{"start":{"line":39,"column":65},"end":{"line":39,"column":103}},"type":"binary-expr","locations":[{"start":{"line":39,"column":65},"end":{"line":39,"column":101}},{"start":{"line":39,"column":101},"end":{"line":39,"column":103}}],"line":39},"2":{"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":17},"end":{"line":43,"column":52}},{"start":{"line":43,"column":52},"end":{"line":43,"column":null}}],"line":43},"3":{"loc":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":18},"end":{"line":47,"column":46}},{"start":{"line":47,"column":46},"end":{"line":47,"column":null}}],"line":47},"4":{"loc":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":17},"end":{"line":48,"column":44}},{"start":{"line":48,"column":44},"end":{"line":48,"column":null}}],"line":48},"5":{"loc":{"start":{"line":49,"column":14},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":14},"end":{"line":49,"column":37}},{"start":{"line":49,"column":37},"end":{"line":49,"column":null}}],"line":49},"6":{"loc":{"start":{"line":50,"column":13},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":11},"end":{"line":54,"column":null}},{"start":{"line":55,"column":10},"end":{"line":55,"column":null}}],"line":50},"7":{"loc":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":23},"end":{"line":56,"column":60}},{"start":{"line":56,"column":60},"end":{"line":56,"column":null}}],"line":56},"8":{"loc":{"start":{"line":57,"column":27},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":57,"column":27},"end":{"line":57,"column":64}},{"start":{"line":57,"column":64},"end":{"line":57,"column":null}}],"line":57},"9":{"loc":{"start":{"line":58,"column":29},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":29},"end":{"line":58,"column":68}},{"start":{"line":58,"column":68},"end":{"line":58,"column":null}}],"line":58},"10":{"loc":{"start":{"line":59,"column":18},"end":{"line":59,"column":null}},"type":"binary-expr","locations":[{"start":{"line":59,"column":18},"end":{"line":59,"column":48}},{"start":{"line":59,"column":48},"end":{"line":59,"column":null}}],"line":59},"11":{"loc":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":18},"end":{"line":60,"column":48}},{"start":{"line":60,"column":48},"end":{"line":60,"column":null}}],"line":60}},"s":{"0":2,"1":2,"2":2,"3":3,"4":2,"5":4,"6":1,"7":2,"8":3,"9":3,"10":5,"11":2},"f":{"0":2,"1":3,"2":4,"3":1,"4":3,"5":5},"b":{"0":[1,0],"1":[1,0],"2":[3,0],"3":[3,0],"4":[3,0],"5":[3,0],"6":[3,0],"7":[3,0],"8":[3,0],"9":[3,0],"10":[3,0],"11":[3,0]},"meta":{"lastBranch":12,"lastFunction":6,"lastStatement":12,"seen":{"f:26:22:26:43":0,"s:27:35:30:Infinity":0,"s:32:42:32:Infinity":1,"s:33:2:35:Infinity":2,"f:33:14:33:22":1,"s:34:4:34:Infinity":3,"s:37:17:40:Infinity":4,"f:38:5:38:12":2,"s:38:19:38:56":5,"f:39:5:39:11":3,"s:39:14:39:103":6,"b:39:22:39:58:39:58:39:65":0,"b:39:65:39:101:39:101:39:103":1,"s:42:32:63:Infinity":7,"f:42:39:42:44":4,"s:43:17:43:Infinity":8,"b:43:17:43:52:43:52:43:Infinity":2,"s:44:4:62:Infinity":9,"b:47:18:47:46:47:46:47:Infinity":3,"b:48:17:48:44:48:44:48:Infinity":4,"b:49:14:49:37:49:37:49:Infinity":5,"b:51:11:54:Infinity:55:10:55:Infinity":6,"f:54:21:54:31":5,"s:54:45:54:60":10,"b:56:23:56:60:56:60:56:Infinity":7,"b:57:27:57:64:57:64:57:Infinity":8,"b:58:29:58:68:58:68:58:Infinity":9,"b:59:18:59:48:59:48:59:Infinity":10,"b:60:18:60:48:60:48:60:Infinity":11,"s:65:2:72:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/voting.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/voting.ts","statementMap":{"0":{"start":{"line":30,"column":59},"end":{"line":34,"column":null}},"1":{"start":{"line":36,"column":17},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":21},"end":{"line":40,"column":null}},"3":{"start":{"line":42,"column":50},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":2},"end":{"line":51,"column":null}},"5":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"6":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"7":{"start":{"line":47,"column":19},"end":{"line":47,"column":null}},"8":{"start":{"line":48,"column":19},"end":{"line":48,"column":null}},"9":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"10":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"11":{"start":{"line":53,"column":27},"end":{"line":53,"column":null}},"12":{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},"13":{"start":{"line":57,"column":4},"end":{"line":62,"column":null}},"14":{"start":{"line":58,"column":6},"end":{"line":61,"column":null}},"15":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"16":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"18":{"start":{"line":64,"column":50},"end":{"line":64,"column":null}},"19":{"start":{"line":65,"column":4},"end":{"line":77,"column":null}},"20":{"start":{"line":66,"column":19},"end":{"line":66,"column":62}},"21":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"22":{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},"23":{"start":{"line":75,"column":10},"end":{"line":75,"column":null}},"24":{"start":{"line":78,"column":4},"end":{"line":85,"column":null}},"25":{"start":{"line":79,"column":18},"end":{"line":79,"column":null}},"26":{"start":{"line":80,"column":6},"end":{"line":84,"column":null}},"27":{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},"28":{"start":{"line":81,"column":23},"end":{"line":81,"column":null}},"29":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"30":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"31":{"start":{"line":88,"column":46},"end":{"line":101,"column":null}},"32":{"start":{"line":90,"column":25},"end":{"line":90,"column":null}},"33":{"start":{"line":90,"column":49},"end":{"line":90,"column":66}},"34":{"start":{"line":91,"column":23},"end":{"line":91,"column":null}},"35":{"start":{"line":91,"column":44},"end":{"line":91,"column":67}},"36":{"start":{"line":92,"column":20},"end":{"line":92,"column":null}},"37":{"start":{"line":92,"column":48},"end":{"line":92,"column":91}},"38":{"start":{"line":93,"column":24},"end":{"line":93,"column":null}},"39":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"40":{"start":{"line":95,"column":6},"end":{"line":99,"column":null}},"41":{"start":{"line":101,"column":17},"end":{"line":101,"column":36}},"42":{"start":{"line":103,"column":2},"end":{"line":114,"column":null}}},"fnMap":{"0":{"name":"loadVotingPatterns","decl":{"start":{"line":29,"column":22},"end":{"line":29,"column":41}},"loc":{"start":{"line":29,"column":84},"end":{"line":115,"column":null}},"line":29},"1":{"name":"(anonymous_1)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":12}},"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":45,"column":5},"end":{"line":45,"column":13}},"loc":{"start":{"line":45,"column":18},"end":{"line":51,"column":5}},"line":45},"3":{"name":"(anonymous_3)","decl":{"start":{"line":57,"column":29},"end":{"line":57,"column":33}},"loc":{"start":{"line":58,"column":6},"end":{"line":61,"column":null}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":58,"column":13},"end":{"line":58,"column":17}},"loc":{"start":{"line":58,"column":23},"end":{"line":61,"column":7}},"line":58},"5":{"name":"(anonymous_5)","decl":{"start":{"line":66,"column":7},"end":{"line":66,"column":14}},"loc":{"start":{"line":66,"column":19},"end":{"line":66,"column":62}},"line":66},"6":{"name":"(anonymous_6)","decl":{"start":{"line":67,"column":7},"end":{"line":67,"column":15}},"loc":{"start":{"line":67,"column":20},"end":{"line":77,"column":7}},"line":67},"7":{"name":"(anonymous_7)","decl":{"start":{"line":78,"column":29},"end":{"line":78,"column":33}},"loc":{"start":{"line":78,"column":39},"end":{"line":85,"column":5}},"line":78},"8":{"name":"(anonymous_8)","decl":{"start":{"line":80,"column":20},"end":{"line":80,"column":24}},"loc":{"start":{"line":80,"column":30},"end":{"line":84,"column":7}},"line":80},"9":{"name":"(anonymous_9)","decl":{"start":{"line":89,"column":5},"end":{"line":89,"column":9}},"loc":{"start":{"line":89,"column":18},"end":{"line":100,"column":5}},"line":89},"10":{"name":"(anonymous_10)","decl":{"start":{"line":90,"column":37},"end":{"line":90,"column":44}},"loc":{"start":{"line":90,"column":49},"end":{"line":90,"column":66}},"line":90},"11":{"name":"(anonymous_11)","decl":{"start":{"line":91,"column":34},"end":{"line":91,"column":39}},"loc":{"start":{"line":91,"column":44},"end":{"line":91,"column":67}},"line":91},"12":{"name":"(anonymous_12)","decl":{"start":{"line":92,"column":31},"end":{"line":92,"column":39}},"loc":{"start":{"line":92,"column":48},"end":{"line":92,"column":91}},"line":92},"13":{"name":"(anonymous_13)","decl":{"start":{"line":101,"column":5},"end":{"line":101,"column":12}},"loc":{"start":{"line":101,"column":17},"end":{"line":101,"column":36}},"line":101}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"type":"binary-expr","locations":[{"start":{"line":44,"column":17},"end":{"line":44,"column":65}},{"start":{"line":44,"column":65},"end":{"line":44,"column":109}}],"line":44},"1":{"loc":{"start":{"line":48,"column":32},"end":{"line":48,"column":68}},"type":"binary-expr","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":63}},{"start":{"line":48,"column":63},"end":{"line":48,"column":68}}],"line":48},"2":{"loc":{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},{"start":{"line":63,"column":9},"end":{"line":86,"column":null}}],"line":56},"3":{"loc":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"4":{"loc":{"start":{"line":60,"column":15},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":15},"end":{"line":60,"column":49}},{"start":{"line":60,"column":49},"end":{"line":60,"column":null}}],"line":60},"5":{"loc":{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":69},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},{"start":{"line":71,"column":11},"end":{"line":71,"column":null}},{"start":{"line":72,"column":12},"end":{"line":72,"column":null}},{"start":{"line":73,"column":13},"end":{"line":73,"column":null}}],"line":70},"7":{"loc":{"start":{"line":79,"column":18},"end":{"line":79,"column":null}},"type":"cond-expr","locations":[{"start":{"line":79,"column":39},"end":{"line":79,"column":83}},{"start":{"line":79,"column":83},"end":{"line":79,"column":null}}],"line":79},"8":{"loc":{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":81},"9":{"loc":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"type":"cond-expr","locations":[{"start":{"line":82,"column":41},"end":{"line":82,"column":85}},{"start":{"line":82,"column":85},"end":{"line":82,"column":null}}],"line":82},"10":{"loc":{"start":{"line":92,"column":54},"end":{"line":92,"column":91}},"type":"binary-expr","locations":[{"start":{"line":92,"column":54},"end":{"line":92,"column":87}},{"start":{"line":92,"column":87},"end":{"line":92,"column":91}}],"line":92},"11":{"loc":{"start":{"line":93,"column":24},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":36},"end":{"line":93,"column":75}},{"start":{"line":93,"column":75},"end":{"line":93,"column":null}}],"line":93},"12":{"loc":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":40},"end":{"line":94,"column":90}},{"start":{"line":94,"column":90},"end":{"line":94,"column":null}}],"line":94},"13":{"loc":{"start":{"line":98,"column":15},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":36},"end":{"line":98,"column":51}},{"start":{"line":98,"column":51},"end":{"line":98,"column":null}}],"line":98},"14":{"loc":{"start":{"line":98,"column":51},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":72},"end":{"line":98,"column":83}},{"start":{"line":98,"column":83},"end":{"line":98,"column":null}}],"line":98},"15":{"loc":{"start":{"line":105,"column":17},"end":{"line":107,"column":null}},"type":"cond-expr","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":null}},{"start":{"line":107,"column":8},"end":{"line":107,"column":null}}],"line":105}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":3,"13":2,"14":16,"15":128,"16":16,"17":112,"18":1,"19":1,"20":2,"21":2,"22":2,"23":2,"24":1,"25":8,"26":8,"27":64,"28":8,"29":56,"30":64,"31":3,"32":24,"33":32,"34":24,"35":2,"36":24,"37":4,"38":24,"39":24,"40":24,"41":24,"42":3},"f":{"0":3,"1":3,"2":3,"3":16,"4":128,"5":2,"6":2,"7":8,"8":64,"9":24,"10":32,"11":2,"12":4,"13":24},"b":{"0":[3,3],"1":[3,0],"2":[2,1],"3":[16,112],"4":[112,106],"5":[2,0],"6":[2,0,0,0],"7":[2,6],"8":[8,56],"9":[14,42],"10":[4,0],"11":[2,22],"12":[2,22],"13":[0,24],"14":[0,24],"15":[2,1]},"meta":{"lastBranch":16,"lastFunction":14,"lastStatement":43,"seen":{"f:29:22:29:41":0,"s:30:59:34:Infinity":0,"s:36:17:36:Infinity":1,"s:37:21:40:Infinity":2,"s:42:50:42:Infinity":3,"s:43:2:51:Infinity":4,"f:44:5:44:12":1,"s:44:17:44:109":5,"b:44:17:44:65:44:65:44:109":0,"f:45:5:45:13":2,"s:46:19:46:Infinity":6,"s:47:19:47:Infinity":7,"s:48:19:48:Infinity":8,"b:48:32:48:63:48:63:48:68":1,"s:49:6:49:Infinity":9,"s:50:6:50:Infinity":10,"s:53:27:53:Infinity":11,"b:56:2:86:Infinity:63:9:86:Infinity":2,"s:56:2:86:Infinity":12,"s:57:4:62:Infinity":13,"f:57:29:57:33":3,"s:58:6:61:Infinity":14,"f:58:13:58:17":4,"b:59:8:59:Infinity:undefined:undefined:undefined:undefined":3,"s:59:8:59:Infinity":15,"s:59:23:59:Infinity":16,"s:60:8:60:Infinity":17,"b:60:15:60:49:60:49:60:Infinity":4,"s:64:50:64:Infinity":18,"s:65:4:77:Infinity":19,"f:66:7:66:14":5,"s:66:19:66:62":20,"f:67:7:67:15":6,"s:68:22:68:Infinity":21,"b:69:8:76:Infinity:undefined:undefined:undefined:undefined":5,"s:69:8:76:Infinity":22,"b:70:10:70:Infinity:71:11:71:Infinity:72:12:72:Infinity:73:13:73:Infinity":6,"s:75:10:75:Infinity":23,"s:78:4:85:Infinity":24,"f:78:29:78:33":7,"s:79:18:79:Infinity":25,"b:79:39:79:83:79:83:79:Infinity":7,"s:80:6:84:Infinity":26,"f:80:20:80:24":8,"b:81:8:81:Infinity:undefined:undefined:undefined:undefined":8,"s:81:8:81:Infinity":27,"s:81:23:81:Infinity":28,"s:82:20:82:Infinity":29,"b:82:41:82:85:82:85:82:Infinity":9,"s:83:8:83:Infinity":30,"s:88:46:101:Infinity":31,"f:89:5:89:9":9,"s:90:25:90:Infinity":32,"f:90:37:90:44":10,"s:90:49:90:66":33,"s:91:23:91:Infinity":34,"f:91:34:91:39":11,"s:91:44:91:67":35,"s:92:20:92:Infinity":36,"f:92:31:92:39":12,"s:92:48:92:91":37,"b:92:54:92:87:92:87:92:91":10,"s:93:24:93:Infinity":38,"b:93:36:93:75:93:75:93:Infinity":11,"s:94:28:94:Infinity":39,"b:94:40:94:90:94:90:94:Infinity":12,"s:95:6:99:Infinity":40,"b:98:36:98:51:98:51:98:Infinity":13,"b:98:72:98:83:98:83:98:Infinity":14,"f:101:5:101:12":13,"s:101:17:101:36":41,"s:103:2:114:Infinity":42,"b:106:8:106:Infinity:107:8:107:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/lazy-loader.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/lazy-loader.ts","statementMap":{"0":{"start":{"line":35,"column":36},"end":{"line":35,"column":null}},"1":{"start":{"line":48,"column":35},"end":{"line":48,"column":null}},"2":{"start":{"line":51,"column":33},"end":{"line":51,"column":null}},"3":{"start":{"line":70,"column":36},"end":{"line":70,"column":null}},"4":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"5":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"6":{"start":{"line":81,"column":16},"end":{"line":81,"column":null}},"7":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"8":{"start":{"line":82,"column":14},"end":{"line":82,"column":null}},"9":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"10":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"11":{"start":{"line":84,"column":14},"end":{"line":84,"column":null}},"12":{"start":{"line":85,"column":16},"end":{"line":85,"column":null}},"13":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"14":{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},"15":{"start":{"line":118,"column":4},"end":{"line":134,"column":null}},"16":{"start":{"line":119,"column":17},"end":{"line":119,"column":null}},"17":{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},"18":{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},"19":{"start":{"line":122,"column":8},"end":{"line":122,"column":null}},"20":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"21":{"start":{"line":125,"column":6},"end":{"line":133,"column":null}},"22":{"start":{"line":126,"column":20},"end":{"line":126,"column":28}},"23":{"start":{"line":128,"column":10},"end":{"line":128,"column":null}},"24":{"start":{"line":131,"column":10},"end":{"line":131,"column":null}},"25":{"start":{"line":132,"column":10},"end":{"line":132,"column":null}},"26":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"27":{"start":{"line":138,"column":18},"end":{"line":138,"column":null}},"28":{"start":{"line":140,"column":19},"end":{"line":164,"column":null}},"29":{"start":{"line":141,"column":4},"end":{"line":163,"column":null}},"30":{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},"31":{"start":{"line":142,"column":33},"end":{"line":142,"column":null}},"32":{"start":{"line":144,"column":17},"end":{"line":144,"column":null}},"33":{"start":{"line":145,"column":6},"end":{"line":145,"column":null}},"34":{"start":{"line":147,"column":23},"end":{"line":147,"column":null}},"35":{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},"36":{"start":{"line":148,"column":21},"end":{"line":148,"column":null}},"37":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"38":{"start":{"line":151,"column":6},"end":{"line":151,"column":null}},"39":{"start":{"line":153,"column":6},"end":{"line":162,"column":null}},"40":{"start":{"line":154,"column":20},"end":{"line":154,"column":30}},"41":{"start":{"line":156,"column":10},"end":{"line":156,"column":null}},"42":{"start":{"line":157,"column":10},"end":{"line":157,"column":null}},"43":{"start":{"line":160,"column":10},"end":{"line":160,"column":null}},"44":{"start":{"line":161,"column":10},"end":{"line":161,"column":null}},"45":{"start":{"line":166,"column":2},"end":{"line":174,"column":null}},"46":{"start":{"line":167,"column":15},"end":{"line":167,"column":null}},"47":{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},"48":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"49":{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},"50":{"start":{"line":172,"column":4},"end":{"line":172,"column":null}},"51":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"52":{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},"53":{"start":{"line":187,"column":25},"end":{"line":187,"column":null}},"54":{"start":{"line":188,"column":4},"end":{"line":210,"column":null}},"55":{"start":{"line":189,"column":6},"end":{"line":209,"column":null}},"56":{"start":{"line":190,"column":22},"end":{"line":190,"column":null}},"57":{"start":{"line":191,"column":31},"end":{"line":191,"column":null}},"58":{"start":{"line":192,"column":27},"end":{"line":192,"column":null}},"59":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"60":{"start":{"line":193,"column":25},"end":{"line":193,"column":null}},"61":{"start":{"line":195,"column":8},"end":{"line":195,"column":null}},"62":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"63":{"start":{"line":198,"column":8},"end":{"line":198,"column":null}},"64":{"start":{"line":199,"column":8},"end":{"line":208,"column":null}},"65":{"start":{"line":200,"column":22},"end":{"line":200,"column":32}},"66":{"start":{"line":202,"column":12},"end":{"line":202,"column":null}},"67":{"start":{"line":203,"column":12},"end":{"line":203,"column":null}},"68":{"start":{"line":206,"column":12},"end":{"line":206,"column":null}},"69":{"start":{"line":207,"column":12},"end":{"line":207,"column":null}},"70":{"start":{"line":213,"column":2},"end":{"line":213,"column":null}}},"fnMap":{"0":{"name":"parseRootMarginPx","decl":{"start":{"line":79,"column":16},"end":{"line":79,"column":34}},"loc":{"start":{"line":79,"column":74},"end":{"line":87,"column":null}},"line":79},"1":{"name":"initLazyDashboards","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"loc":{"start":{"line":116,"column":36},"end":{"line":214,"column":null}},"line":116},"2":{"name":"(anonymous_2)","decl":{"start":{"line":126,"column":9},"end":{"line":126,"column":20}},"loc":{"start":{"line":126,"column":20},"end":{"line":126,"column":28}},"line":126},"3":{"name":"(anonymous_3)","decl":{"start":{"line":127,"column":9},"end":{"line":127,"column":20}},"loc":{"start":{"line":127,"column":20},"end":{"line":129,"column":9}},"line":127},"4":{"name":"(anonymous_4)","decl":{"start":{"line":130,"column":9},"end":{"line":130,"column":16}},"loc":{"start":{"line":130,"column":33},"end":{"line":133,"column":9}},"line":130},"5":{"name":"(anonymous_5)","decl":{"start":{"line":140,"column":23},"end":{"line":140,"column":45}},"loc":{"start":{"line":140,"column":86},"end":{"line":164,"column":5}},"line":140},"6":{"name":"(anonymous_6)","decl":{"start":{"line":154,"column":9},"end":{"line":154,"column":20}},"loc":{"start":{"line":154,"column":20},"end":{"line":154,"column":30}},"line":154},"7":{"name":"(anonymous_7)","decl":{"start":{"line":155,"column":9},"end":{"line":155,"column":20}},"loc":{"start":{"line":155,"column":20},"end":{"line":158,"column":9}},"line":155},"8":{"name":"(anonymous_8)","decl":{"start":{"line":159,"column":9},"end":{"line":159,"column":16}},"loc":{"start":{"line":159,"column":33},"end":{"line":162,"column":9}},"line":159},"9":{"name":"(anonymous_9)","decl":{"start":{"line":188,"column":11},"end":{"line":188,"column":39}},"loc":{"start":{"line":188,"column":39},"end":{"line":210,"column":5}},"line":188},"10":{"name":"(anonymous_10)","decl":{"start":{"line":200,"column":11},"end":{"line":200,"column":22}},"loc":{"start":{"line":200,"column":22},"end":{"line":200,"column":32}},"line":200},"11":{"name":"(anonymous_11)","decl":{"start":{"line":201,"column":11},"end":{"line":201,"column":22}},"loc":{"start":{"line":201,"column":22},"end":{"line":204,"column":11}},"line":201},"12":{"name":"(anonymous_12)","decl":{"start":{"line":205,"column":11},"end":{"line":205,"column":18}},"loc":{"start":{"line":205,"column":35},"end":{"line":208,"column":11}},"line":205}},"branchMap":{"0":{"loc":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"1":{"loc":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},{"start":{},"end":{}}],"line":82},"2":{"loc":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"3":{"loc":{"start":{"line":86,"column":9},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":34},"end":{"line":86,"column":42}},{"start":{"line":86,"column":42},"end":{"line":86,"column":null}}],"line":86},"4":{"loc":{"start":{"line":112,"column":2},"end":{"line":115,"column":null}},"type":"default-arg","locations":[{"start":{"line":112,"column":38},"end":{"line":115,"column":null}}],"line":112},"5":{"loc":{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":117},"6":{"loc":{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":120},"7":{"loc":{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":142},"8":{"loc":{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},{"start":{},"end":{}}],"line":148},"9":{"loc":{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},{"start":{},"end":{}}],"line":168},"10":{"loc":{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},"type":"if","locations":[{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},{"start":{},"end":{}}],"line":186},"11":{"loc":{"start":{"line":186,"column":6},"end":{"line":186,"column":91}},"type":"binary-expr","locations":[{"start":{"line":186,"column":6},"end":{"line":186,"column":39}},{"start":{"line":186,"column":39},"end":{"line":186,"column":91}}],"line":186},"12":{"loc":{"start":{"line":191,"column":31},"end":{"line":191,"column":null}},"type":"binary-expr","locations":[{"start":{"line":191,"column":31},"end":{"line":191,"column":53}},{"start":{"line":191,"column":53},"end":{"line":191,"column":94}},{"start":{"line":191,"column":94},"end":{"line":191,"column":null}}],"line":191},"13":{"loc":{"start":{"line":192,"column":27},"end":{"line":192,"column":null}},"type":"binary-expr","locations":[{"start":{"line":192,"column":27},"end":{"line":192,"column":59}},{"start":{"line":192,"column":59},"end":{"line":192,"column":null}}],"line":192},"14":{"loc":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":193}},"s":{"0":2,"1":2,"2":2,"3":2,"4":24,"5":2,"6":22,"7":22,"8":0,"9":22,"10":22,"11":3,"12":19,"13":19,"14":21,"15":6,"16":6,"17":6,"18":2,"19":2,"20":4,"21":4,"22":4,"23":3,"24":1,"25":1,"26":6,"27":15,"28":15,"29":11,"30":11,"31":1,"32":10,"33":10,"34":10,"35":10,"36":1,"37":9,"38":9,"39":9,"40":9,"41":7,"42":7,"43":2,"44":2,"45":15,"46":28,"47":28,"48":13,"49":13,"50":15,"51":15,"52":15,"53":15,"54":15,"55":15,"56":6,"57":6,"58":6,"59":6,"60":0,"61":6,"62":6,"63":6,"64":6,"65":6,"66":6,"67":6,"68":0,"69":0,"70":15},"f":{"0":24,"1":21,"2":4,"3":3,"4":1,"5":11,"6":9,"7":7,"8":2,"9":15,"10":6,"11":6,"12":0},"b":{"0":[2,22],"1":[0,22],"2":[3,19],"3":[19,0],"4":[21],"5":[6,15],"6":[2,4],"7":[1,10],"8":[1,9],"9":[13,15],"10":[15,0],"11":[15,15],"12":[6,0,0],"13":[6,6],"14":[0,6]},"meta":{"lastBranch":15,"lastFunction":13,"lastStatement":71,"seen":{"s:35:36:35:Infinity":0,"s:48:35:48:Infinity":1,"s:51:33:51:Infinity":2,"s:70:36:70:Infinity":3,"f:79:16:79:34":0,"b:80:2:80:Infinity:undefined:undefined:undefined:undefined":0,"s:80:2:80:Infinity":4,"s:80:19:80:Infinity":5,"s:81:16:81:Infinity":6,"b:82:2:82:Infinity:undefined:undefined:undefined:undefined":1,"s:82:2:82:Infinity":7,"s:82:14:82:Infinity":8,"s:83:16:83:Infinity":9,"b:84:2:84:Infinity:undefined:undefined:undefined:undefined":2,"s:84:2:84:Infinity":10,"s:84:14:84:Infinity":11,"s:85:16:85:Infinity":12,"s:86:2:86:Infinity":13,"b:86:34:86:42:86:42:86:Infinity":3,"f:110:16:110:Infinity":1,"b:112:38:115:Infinity":4,"b:117:2:136:Infinity:undefined:undefined:undefined:undefined":5,"s:117:2:136:Infinity":14,"s:118:4:134:Infinity":15,"s:119:17:119:Infinity":16,"b:120:6:123:Infinity:undefined:undefined:undefined:undefined":6,"s:120:6:123:Infinity":17,"s:121:8:121:Infinity":18,"s:122:8:122:Infinity":19,"s:124:6:124:Infinity":20,"s:125:6:133:Infinity":21,"f:126:9:126:20":2,"s:126:20:126:28":22,"f:127:9:127:20":3,"s:128:10:128:Infinity":23,"f:130:9:130:16":4,"s:131:10:131:Infinity":24,"s:132:10:132:Infinity":25,"s:135:4:135:Infinity":26,"s:138:18:138:Infinity":27,"s:140:19:164:Infinity":28,"f:140:23:140:45":5,"s:141:4:163:Infinity":29,"b:142:6:142:Infinity:undefined:undefined:undefined:undefined":7,"s:142:6:142:Infinity":30,"s:142:33:142:Infinity":31,"s:144:17:144:Infinity":32,"s:145:6:145:Infinity":33,"s:147:23:147:Infinity":34,"b:148:6:148:Infinity:undefined:undefined:undefined:undefined":8,"s:148:6:148:Infinity":35,"s:148:21:148:Infinity":36,"s:149:6:149:Infinity":37,"s:151:6:151:Infinity":38,"s:153:6:162:Infinity":39,"f:154:9:154:20":6,"s:154:20:154:30":40,"f:155:9:155:20":7,"s:156:10:156:Infinity":41,"s:157:10:157:Infinity":42,"f:159:9:159:16":8,"s:160:10:160:Infinity":43,"s:161:10:161:Infinity":44,"s:166:2:174:Infinity":45,"s:167:15:167:Infinity":46,"b:168:4:171:Infinity:undefined:undefined:undefined:undefined":9,"s:168:4:171:Infinity":47,"s:169:6:169:Infinity":48,"s:170:6:170:Infinity":49,"s:172:4:172:Infinity":50,"s:173:4:173:Infinity":51,"b:186:2:211:Infinity:undefined:undefined:undefined:undefined":10,"s:186:2:211:Infinity":52,"b:186:6:186:39:186:39:186:91":11,"s:187:25:187:Infinity":53,"s:188:4:210:Infinity":54,"f:188:11:188:39":9,"s:189:6:209:Infinity":55,"s:190:22:190:Infinity":56,"s:191:31:191:Infinity":57,"b:191:31:191:53:191:53:191:94:191:94:191:Infinity":12,"s:192:27:192:Infinity":58,"b:192:27:192:59:192:59:192:Infinity":13,"b:193:8:193:Infinity:undefined:undefined:undefined:undefined":14,"s:193:8:193:Infinity":59,"s:193:25:193:Infinity":60,"s:195:8:195:Infinity":61,"s:196:8:196:Infinity":62,"s:198:8:198:Infinity":63,"s:199:8:208:Infinity":64,"f:200:11:200:22":10,"s:200:22:200:32":65,"f:201:11:201:22":11,"s:202:12:202:Infinity":66,"s:203:12:203:Infinity":67,"f:205:11:205:18":12,"s:206:12:206:Infinity":68,"s:207:12:207:Infinity":69,"s:213:2:213:Infinity":70}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/visualizations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/visualizations.ts","statementMap":{"0":{"start":{"line":45,"column":15},"end":{"line":45,"column":null}},"1":{"start":{"line":76,"column":44},"end":{"line":76,"column":null}},"2":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"3":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"4":{"start":{"line":85,"column":25},"end":{"line":85,"column":null}},"5":{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},"6":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"7":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"8":{"start":{"line":92,"column":23},"end":{"line":92,"column":null}},"9":{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},"10":{"start":{"line":94,"column":6},"end":{"line":94,"column":null}},"11":{"start":{"line":96,"column":27},"end":{"line":96,"column":null}},"12":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"13":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"14":{"start":{"line":100,"column":24},"end":{"line":100,"column":null}},"15":{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},"16":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"17":{"start":{"line":104,"column":29},"end":{"line":104,"column":null}},"18":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"19":{"start":{"line":106,"column":6},"end":{"line":106,"column":null}},"20":{"start":{"line":109,"column":26},"end":{"line":109,"column":null}},"21":{"start":{"line":110,"column":28},"end":{"line":110,"column":null}},"22":{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},"23":{"start":{"line":112,"column":6},"end":{"line":112,"column":null}},"24":{"start":{"line":114,"column":25},"end":{"line":114,"column":null}},"25":{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},"26":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"27":{"start":{"line":118,"column":25},"end":{"line":118,"column":null}},"28":{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},"29":{"start":{"line":120,"column":6},"end":{"line":120,"column":null}},"30":{"start":{"line":126,"column":26},"end":{"line":126,"column":null}},"31":{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},"32":{"start":{"line":129,"column":6},"end":{"line":129,"column":null}},"33":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"34":{"start":{"line":133,"column":21},"end":{"line":133,"column":null}},"35":{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},"36":{"start":{"line":135,"column":30},"end":{"line":137,"column":null}},"37":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"38":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"39":{"start":{"line":139,"column":8},"end":{"line":139,"column":null}},"40":{"start":{"line":142,"column":6},"end":{"line":195,"column":null}},"41":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"42":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"43":{"start":{"line":198,"column":24},"end":{"line":198,"column":null}},"44":{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},"45":{"start":{"line":200,"column":29},"end":{"line":206,"column":null}},"46":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"47":{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},"48":{"start":{"line":208,"column":8},"end":{"line":208,"column":null}},"49":{"start":{"line":211,"column":6},"end":{"line":264,"column":null}},"50":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"51":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"52":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"53":{"start":{"line":270,"column":22},"end":{"line":270,"column":null}},"54":{"start":{"line":271,"column":22},"end":{"line":271,"column":null}},"55":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"56":{"start":{"line":273,"column":20},"end":{"line":273,"column":null}},"57":{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},"58":{"start":{"line":276,"column":6},"end":{"line":276,"column":null}},"59":{"start":{"line":277,"column":6},"end":{"line":277,"column":null}},"60":{"start":{"line":280,"column":4},"end":{"line":280,"column":null}},"61":{"start":{"line":281,"column":21},"end":{"line":281,"column":null}},"62":{"start":{"line":283,"column":4},"end":{"line":333,"column":null}},"63":{"start":{"line":284,"column":19},"end":{"line":284,"column":null}},"64":{"start":{"line":285,"column":6},"end":{"line":285,"column":null}},"65":{"start":{"line":287,"column":21},"end":{"line":287,"column":null}},"66":{"start":{"line":288,"column":6},"end":{"line":288,"column":null}},"67":{"start":{"line":289,"column":6},"end":{"line":289,"column":null}},"68":{"start":{"line":291,"column":19},"end":{"line":291,"column":null}},"69":{"start":{"line":292,"column":6},"end":{"line":292,"column":null}},"70":{"start":{"line":294,"column":19},"end":{"line":294,"column":null}},"71":{"start":{"line":295,"column":6},"end":{"line":295,"column":null}},"72":{"start":{"line":296,"column":6},"end":{"line":296,"column":null}},"73":{"start":{"line":298,"column":20},"end":{"line":298,"column":null}},"74":{"start":{"line":299,"column":6},"end":{"line":299,"column":null}},"75":{"start":{"line":300,"column":6},"end":{"line":300,"column":null}},"76":{"start":{"line":302,"column":19},"end":{"line":302,"column":null}},"77":{"start":{"line":303,"column":6},"end":{"line":303,"column":null}},"78":{"start":{"line":304,"column":6},"end":{"line":304,"column":null}},"79":{"start":{"line":306,"column":6},"end":{"line":306,"column":null}},"80":{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},"81":{"start":{"line":308,"column":6},"end":{"line":308,"column":null}},"82":{"start":{"line":310,"column":20},"end":{"line":310,"column":null}},"83":{"start":{"line":311,"column":6},"end":{"line":311,"column":null}},"84":{"start":{"line":313,"column":25},"end":{"line":313,"column":null}},"85":{"start":{"line":314,"column":6},"end":{"line":314,"column":null}},"86":{"start":{"line":316,"column":8},"end":{"line":318,"column":null}},"87":{"start":{"line":319,"column":6},"end":{"line":319,"column":null}},"88":{"start":{"line":321,"column":25},"end":{"line":321,"column":null}},"89":{"start":{"line":322,"column":6},"end":{"line":322,"column":null}},"90":{"start":{"line":323,"column":6},"end":{"line":323,"column":null}},"91":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"92":{"start":{"line":326,"column":6},"end":{"line":326,"column":null}},"93":{"start":{"line":328,"column":6},"end":{"line":328,"column":null}},"94":{"start":{"line":329,"column":6},"end":{"line":329,"column":null}},"95":{"start":{"line":330,"column":6},"end":{"line":330,"column":null}},"96":{"start":{"line":332,"column":6},"end":{"line":332,"column":null}},"97":{"start":{"line":335,"column":4},"end":{"line":335,"column":null}},"98":{"start":{"line":340,"column":31},"end":{"line":340,"column":null}},"99":{"start":{"line":341,"column":16},"end":{"line":341,"column":null}},"100":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},"101":{"start":{"line":343,"column":46},"end":{"line":343,"column":null}},"102":{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},"103":{"start":{"line":352,"column":6},"end":{"line":352,"column":null}},"104":{"start":{"line":353,"column":6},"end":{"line":353,"column":null}},"105":{"start":{"line":356,"column":19},"end":{"line":356,"column":null}},"106":{"start":{"line":358,"column":4},"end":{"line":389,"column":null}},"107":{"start":{"line":362,"column":76},"end":{"line":367,"column":10}},"108":{"start":{"line":394,"column":27},"end":{"line":394,"column":null}},"109":{"start":{"line":395,"column":22},"end":{"line":395,"column":null}},"110":{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},"111":{"start":{"line":397,"column":20},"end":{"line":397,"column":null}},"112":{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},"113":{"start":{"line":400,"column":6},"end":{"line":400,"column":null}},"114":{"start":{"line":401,"column":6},"end":{"line":401,"column":null}},"115":{"start":{"line":404,"column":4},"end":{"line":404,"column":null}},"116":{"start":{"line":405,"column":21},"end":{"line":405,"column":null}},"117":{"start":{"line":407,"column":4},"end":{"line":472,"column":null}},"118":{"start":{"line":408,"column":19},"end":{"line":408,"column":null}},"119":{"start":{"line":409,"column":6},"end":{"line":409,"column":null}},"120":{"start":{"line":411,"column":21},"end":{"line":411,"column":null}},"121":{"start":{"line":412,"column":6},"end":{"line":412,"column":null}},"122":{"start":{"line":413,"column":6},"end":{"line":413,"column":null}},"123":{"start":{"line":415,"column":20},"end":{"line":415,"column":null}},"124":{"start":{"line":416,"column":6},"end":{"line":416,"column":null}},"125":{"start":{"line":418,"column":12},"end":{"line":433,"column":null}},"126":{"start":{"line":419,"column":21},"end":{"line":419,"column":null}},"127":{"start":{"line":420,"column":8},"end":{"line":420,"column":null}},"128":{"start":{"line":422,"column":26},"end":{"line":422,"column":null}},"129":{"start":{"line":423,"column":8},"end":{"line":423,"column":null}},"130":{"start":{"line":424,"column":8},"end":{"line":424,"column":null}},"131":{"start":{"line":426,"column":26},"end":{"line":426,"column":null}},"132":{"start":{"line":427,"column":8},"end":{"line":427,"column":null}},"133":{"start":{"line":428,"column":8},"end":{"line":428,"column":null}},"134":{"start":{"line":430,"column":8},"end":{"line":430,"column":null}},"135":{"start":{"line":431,"column":8},"end":{"line":431,"column":null}},"136":{"start":{"line":432,"column":8},"end":{"line":432,"column":null}},"137":{"start":{"line":436,"column":8},"end":{"line":436,"column":null}},"138":{"start":{"line":438,"column":8},"end":{"line":440,"column":null}},"139":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"140":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"141":{"start":{"line":446,"column":6},"end":{"line":446,"column":null}},"142":{"start":{"line":447,"column":6},"end":{"line":447,"column":null}},"143":{"start":{"line":448,"column":6},"end":{"line":448,"column":null}},"144":{"start":{"line":449,"column":6},"end":{"line":449,"column":null}},"145":{"start":{"line":451,"column":21},"end":{"line":451,"column":null}},"146":{"start":{"line":452,"column":6},"end":{"line":452,"column":null}},"147":{"start":{"line":454,"column":28},"end":{"line":454,"column":null}},"148":{"start":{"line":455,"column":6},"end":{"line":455,"column":null}},"149":{"start":{"line":456,"column":6},"end":{"line":456,"column":null}},"150":{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},"151":{"start":{"line":459,"column":8},"end":{"line":464,"column":null}},"152":{"start":{"line":460,"column":22},"end":{"line":460,"column":null}},"153":{"start":{"line":461,"column":10},"end":{"line":461,"column":null}},"154":{"start":{"line":462,"column":10},"end":{"line":462,"column":null}},"155":{"start":{"line":463,"column":10},"end":{"line":463,"column":null}},"156":{"start":{"line":467,"column":6},"end":{"line":467,"column":null}},"157":{"start":{"line":468,"column":6},"end":{"line":468,"column":null}},"158":{"start":{"line":469,"column":6},"end":{"line":469,"column":null}},"159":{"start":{"line":471,"column":6},"end":{"line":471,"column":null}},"160":{"start":{"line":474,"column":4},"end":{"line":474,"column":null}},"161":{"start":{"line":476,"column":23},"end":{"line":476,"column":null}},"162":{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},"163":{"start":{"line":478,"column":6},"end":{"line":478,"column":null}},"164":{"start":{"line":480,"column":21},"end":{"line":480,"column":null}},"165":{"start":{"line":482,"column":17},"end":{"line":482,"column":null}},"166":{"start":{"line":483,"column":21},"end":{"line":483,"column":null}},"167":{"start":{"line":484,"column":6},"end":{"line":484,"column":null}},"168":{"start":{"line":485,"column":6},"end":{"line":485,"column":null}},"169":{"start":{"line":486,"column":6},"end":{"line":490,"column":null}},"170":{"start":{"line":492,"column":17},"end":{"line":492,"column":null}},"171":{"start":{"line":493,"column":6},"end":{"line":493,"column":null}},"172":{"start":{"line":495,"column":6},"end":{"line":495,"column":null}},"173":{"start":{"line":496,"column":6},"end":{"line":496,"column":null}},"174":{"start":{"line":497,"column":6},"end":{"line":497,"column":null}},"175":{"start":{"line":503,"column":25},"end":{"line":503,"column":null}},"176":{"start":{"line":504,"column":22},"end":{"line":504,"column":null}},"177":{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},"178":{"start":{"line":506,"column":20},"end":{"line":506,"column":null}},"179":{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},"180":{"start":{"line":509,"column":6},"end":{"line":509,"column":null}},"181":{"start":{"line":510,"column":6},"end":{"line":510,"column":null}},"182":{"start":{"line":513,"column":4},"end":{"line":513,"column":null}},"183":{"start":{"line":514,"column":21},"end":{"line":514,"column":null}},"184":{"start":{"line":516,"column":4},"end":{"line":559,"column":null}},"185":{"start":{"line":517,"column":19},"end":{"line":517,"column":null}},"186":{"start":{"line":518,"column":6},"end":{"line":518,"column":null}},"187":{"start":{"line":520,"column":21},"end":{"line":520,"column":null}},"188":{"start":{"line":521,"column":6},"end":{"line":521,"column":null}},"189":{"start":{"line":522,"column":6},"end":{"line":522,"column":null}},"190":{"start":{"line":524,"column":20},"end":{"line":524,"column":null}},"191":{"start":{"line":525,"column":6},"end":{"line":525,"column":null}},"192":{"start":{"line":527,"column":12},"end":{"line":539,"column":null}},"193":{"start":{"line":528,"column":21},"end":{"line":528,"column":null}},"194":{"start":{"line":529,"column":8},"end":{"line":529,"column":null}},"195":{"start":{"line":530,"column":26},"end":{"line":530,"column":null}},"196":{"start":{"line":531,"column":8},"end":{"line":531,"column":null}},"197":{"start":{"line":532,"column":8},"end":{"line":532,"column":null}},"198":{"start":{"line":533,"column":26},"end":{"line":533,"column":null}},"199":{"start":{"line":534,"column":8},"end":{"line":534,"column":null}},"200":{"start":{"line":535,"column":8},"end":{"line":535,"column":null}},"201":{"start":{"line":536,"column":8},"end":{"line":536,"column":null}},"202":{"start":{"line":537,"column":8},"end":{"line":537,"column":null}},"203":{"start":{"line":538,"column":8},"end":{"line":538,"column":null}},"204":{"start":{"line":541,"column":6},"end":{"line":541,"column":null}},"205":{"start":{"line":542,"column":6},"end":{"line":542,"column":null}},"206":{"start":{"line":543,"column":6},"end":{"line":543,"column":null}},"207":{"start":{"line":545,"column":25},"end":{"line":545,"column":null}},"208":{"start":{"line":546,"column":6},"end":{"line":546,"column":null}},"209":{"start":{"line":547,"column":28},"end":{"line":547,"column":null}},"210":{"start":{"line":548,"column":6},"end":{"line":548,"column":null}},"211":{"start":{"line":549,"column":6},"end":{"line":549,"column":null}},"212":{"start":{"line":550,"column":18},"end":{"line":550,"column":null}},"213":{"start":{"line":551,"column":6},"end":{"line":551,"column":null}},"214":{"start":{"line":552,"column":6},"end":{"line":552,"column":null}},"215":{"start":{"line":553,"column":6},"end":{"line":553,"column":null}},"216":{"start":{"line":555,"column":6},"end":{"line":555,"column":null}},"217":{"start":{"line":556,"column":6},"end":{"line":556,"column":null}},"218":{"start":{"line":557,"column":6},"end":{"line":557,"column":null}},"219":{"start":{"line":558,"column":6},"end":{"line":558,"column":null}},"220":{"start":{"line":561,"column":4},"end":{"line":561,"column":null}},"221":{"start":{"line":566,"column":29},"end":{"line":566,"column":null}},"222":{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},"223":{"start":{"line":573,"column":6},"end":{"line":573,"column":null}},"224":{"start":{"line":574,"column":6},"end":{"line":574,"column":null}},"225":{"start":{"line":577,"column":22},"end":{"line":577,"column":null}},"226":{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},"227":{"start":{"line":579,"column":29},"end":{"line":579,"column":null}},"228":{"start":{"line":580,"column":23},"end":{"line":583,"column":null}},"229":{"start":{"line":581,"column":22},"end":{"line":581,"column":null}},"230":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"231":{"start":{"line":582,"column":8},"end":{"line":582,"column":null}},"232":{"start":{"line":584,"column":25},"end":{"line":587,"column":null}},"233":{"start":{"line":585,"column":22},"end":{"line":585,"column":null}},"234":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"235":{"start":{"line":586,"column":8},"end":{"line":586,"column":null}},"236":{"start":{"line":589,"column":6},"end":{"line":625,"column":null}},"237":{"start":{"line":628,"column":19},"end":{"line":628,"column":null}},"238":{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},"239":{"start":{"line":630,"column":29},"end":{"line":630,"column":null}},"240":{"start":{"line":631,"column":21},"end":{"line":633,"column":null}},"241":{"start":{"line":631,"column":73},"end":{"line":631,"column":90}},"242":{"start":{"line":633,"column":24},"end":{"line":633,"column":42}},"243":{"start":{"line":634,"column":21},"end":{"line":641,"column":null}},"244":{"start":{"line":643,"column":6},"end":{"line":672,"column":null}},"245":{"start":{"line":647,"column":46},"end":{"line":655,"column":12}},"246":{"start":{"line":648,"column":80},"end":{"line":648,"column":95}},"247":{"start":{"line":650,"column":28},"end":{"line":650,"column":null}},"248":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"249":{"start":{"line":651,"column":14},"end":{"line":651,"column":null}},"250":{"start":{"line":678,"column":33},"end":{"line":678,"column":null}},"251":{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},"252":{"start":{"line":685,"column":6},"end":{"line":685,"column":null}},"253":{"start":{"line":686,"column":6},"end":{"line":686,"column":null}},"254":{"start":{"line":689,"column":19},"end":{"line":689,"column":null}},"255":{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},"256":{"start":{"line":691,"column":24},"end":{"line":691,"column":null}},"257":{"start":{"line":692,"column":20},"end":{"line":692,"column":null}},"258":{"start":{"line":692,"column":72},"end":{"line":692,"column":78}},"259":{"start":{"line":693,"column":26},"end":{"line":693,"column":null}},"260":{"start":{"line":695,"column":6},"end":{"line":730,"column":null}},"261":{"start":{"line":700,"column":27},"end":{"line":700,"column":null}},"262":{"start":{"line":701,"column":12},"end":{"line":713,"column":null}},"263":{"start":{"line":704,"column":30},"end":{"line":704,"column":null}},"264":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"265":{"start":{"line":705,"column":16},"end":{"line":705,"column":null}},"266":{"start":{"line":736,"column":30},"end":{"line":736,"column":null}},"267":{"start":{"line":737,"column":22},"end":{"line":737,"column":null}},"268":{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},"269":{"start":{"line":739,"column":20},"end":{"line":739,"column":null}},"270":{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},"271":{"start":{"line":742,"column":6},"end":{"line":742,"column":null}},"272":{"start":{"line":743,"column":6},"end":{"line":743,"column":null}},"273":{"start":{"line":746,"column":4},"end":{"line":746,"column":null}},"274":{"start":{"line":747,"column":21},"end":{"line":747,"column":null}},"275":{"start":{"line":749,"column":71},"end":{"line":749,"column":null}},"276":{"start":{"line":750,"column":4},"end":{"line":754,"column":null}},"277":{"start":{"line":751,"column":21},"end":{"line":751,"column":null}},"278":{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},"279":{"start":{"line":752,"column":33},"end":{"line":752,"column":null}},"280":{"start":{"line":753,"column":6},"end":{"line":753,"column":null}},"281":{"start":{"line":756,"column":4},"end":{"line":786,"column":null}},"282":{"start":{"line":757,"column":26},"end":{"line":757,"column":44}},"283":{"start":{"line":759,"column":21},"end":{"line":759,"column":null}},"284":{"start":{"line":760,"column":8},"end":{"line":760,"column":null}},"285":{"start":{"line":762,"column":23},"end":{"line":762,"column":null}},"286":{"start":{"line":763,"column":8},"end":{"line":763,"column":null}},"287":{"start":{"line":764,"column":8},"end":{"line":764,"column":null}},"288":{"start":{"line":766,"column":22},"end":{"line":766,"column":null}},"289":{"start":{"line":767,"column":8},"end":{"line":767,"column":null}},"290":{"start":{"line":769,"column":8},"end":{"line":781,"column":null}},"291":{"start":{"line":770,"column":23},"end":{"line":770,"column":null}},"292":{"start":{"line":771,"column":10},"end":{"line":771,"column":null}},"293":{"start":{"line":772,"column":24},"end":{"line":772,"column":null}},"294":{"start":{"line":773,"column":10},"end":{"line":773,"column":null}},"295":{"start":{"line":774,"column":10},"end":{"line":774,"column":null}},"296":{"start":{"line":775,"column":24},"end":{"line":775,"column":null}},"297":{"start":{"line":776,"column":10},"end":{"line":776,"column":null}},"298":{"start":{"line":777,"column":10},"end":{"line":777,"column":null}},"299":{"start":{"line":778,"column":10},"end":{"line":778,"column":null}},"300":{"start":{"line":779,"column":10},"end":{"line":779,"column":null}},"301":{"start":{"line":780,"column":10},"end":{"line":780,"column":null}},"302":{"start":{"line":783,"column":8},"end":{"line":783,"column":null}},"303":{"start":{"line":784,"column":8},"end":{"line":784,"column":null}},"304":{"start":{"line":785,"column":8},"end":{"line":785,"column":null}},"305":{"start":{"line":788,"column":4},"end":{"line":788,"column":null}},"306":{"start":{"line":793,"column":4},"end":{"line":797,"column":null}},"307":{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},"308":{"start":{"line":795,"column":8},"end":{"line":795,"column":null}},"309":{"start":{"line":798,"column":4},"end":{"line":798,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":78,"column":2},"end":{"line":78,"column":14}},"loc":{"start":{"line":78,"column":34},"end":{"line":81,"column":null}},"line":78},"1":{"name":"(anonymous_1)","decl":{"start":{"line":84,"column":2},"end":{"line":84,"column":27}},"loc":{"start":{"line":84,"column":27},"end":{"line":122,"column":null}},"line":84},"2":{"name":"(anonymous_2)","decl":{"start":{"line":125,"column":2},"end":{"line":125,"column":33}},"loc":{"start":{"line":125,"column":33},"end":{"line":266,"column":null}},"line":125},"3":{"name":"(anonymous_3)","decl":{"start":{"line":135,"column":48},"end":{"line":135,"column":null}},"loc":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"line":136},"4":{"name":"(anonymous_4)","decl":{"start":{"line":145,"column":36},"end":{"line":145,"column":40}},"loc":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"line":145},"5":{"name":"(anonymous_5)","decl":{"start":{"line":149,"column":38},"end":{"line":149,"column":42}},"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"line":150},"6":{"name":"(anonymous_6)","decl":{"start":{"line":200,"column":47},"end":{"line":200,"column":null}},"loc":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"line":202},"7":{"name":"(anonymous_7)","decl":{"start":{"line":214,"column":36},"end":{"line":214,"column":40}},"loc":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"line":214},"8":{"name":"(anonymous_8)","decl":{"start":{"line":218,"column":38},"end":{"line":218,"column":42}},"loc":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"line":219},"9":{"name":"(anonymous_9)","decl":{"start":{"line":232,"column":38},"end":{"line":232,"column":42}},"loc":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"line":233},"10":{"name":"(anonymous_10)","decl":{"start":{"line":269,"column":2},"end":{"line":269,"column":30}},"loc":{"start":{"line":269,"column":30},"end":{"line":336,"column":null}},"line":269},"11":{"name":"(anonymous_11)","decl":{"start":{"line":283,"column":19},"end":{"line":283,"column":28}},"loc":{"start":{"line":283,"column":46},"end":{"line":333,"column":5}},"line":283},"12":{"name":"(anonymous_12)","decl":{"start":{"line":339,"column":2},"end":{"line":339,"column":31}},"loc":{"start":{"line":339,"column":31},"end":{"line":390,"column":null}},"line":339},"13":{"name":"(anonymous_13)","decl":{"start":{"line":362,"column":41},"end":{"line":362,"column":46}},"loc":{"start":{"line":362,"column":76},"end":{"line":367,"column":10}},"line":362},"14":{"name":"(anonymous_14)","decl":{"start":{"line":393,"column":2},"end":{"line":393,"column":33}},"loc":{"start":{"line":393,"column":33},"end":{"line":499,"column":null}},"line":393},"15":{"name":"(anonymous_15)","decl":{"start":{"line":407,"column":26},"end":{"line":407,"column":35}},"loc":{"start":{"line":407,"column":65},"end":{"line":472,"column":5}},"line":407},"16":{"name":"(anonymous_16)","decl":{"start":{"line":418,"column":12},"end":{"line":418,"column":26}},"loc":{"start":{"line":418,"column":84},"end":{"line":433,"column":null}},"line":418},"17":{"name":"(anonymous_17)","decl":{"start":{"line":459,"column":28},"end":{"line":459,"column":37}},"loc":{"start":{"line":459,"column":55},"end":{"line":464,"column":9}},"line":459},"18":{"name":"(anonymous_18)","decl":{"start":{"line":502,"column":2},"end":{"line":502,"column":36}},"loc":{"start":{"line":502,"column":36},"end":{"line":562,"column":null}},"line":502},"19":{"name":"(anonymous_19)","decl":{"start":{"line":516,"column":24},"end":{"line":516,"column":32}},"loc":{"start":{"line":516,"column":37},"end":{"line":559,"column":5}},"line":516},"20":{"name":"(anonymous_20)","decl":{"start":{"line":527,"column":12},"end":{"line":527,"column":26}},"loc":{"start":{"line":527,"column":84},"end":{"line":539,"column":null}},"line":527},"21":{"name":"(anonymous_21)","decl":{"start":{"line":565,"column":2},"end":{"line":565,"column":29}},"loc":{"start":{"line":565,"column":29},"end":{"line":674,"column":null}},"line":565},"22":{"name":"(anonymous_22)","decl":{"start":{"line":580,"column":38},"end":{"line":580,"column":42}},"loc":{"start":{"line":580,"column":47},"end":{"line":583,"column":7}},"line":580},"23":{"name":"(anonymous_23)","decl":{"start":{"line":581,"column":49},"end":{"line":581,"column":54}},"loc":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"line":581},"24":{"name":"(anonymous_24)","decl":{"start":{"line":584,"column":40},"end":{"line":584,"column":44}},"loc":{"start":{"line":584,"column":49},"end":{"line":587,"column":7}},"line":584},"25":{"name":"(anonymous_25)","decl":{"start":{"line":585,"column":49},"end":{"line":585,"column":54}},"loc":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"line":585},"26":{"name":"(anonymous_26)","decl":{"start":{"line":631,"column":64},"end":{"line":631,"column":68}},"loc":{"start":{"line":631,"column":73},"end":{"line":631,"column":90}},"line":631},"27":{"name":"(anonymous_27)","decl":{"start":{"line":633,"column":9},"end":{"line":633,"column":15}},"loc":{"start":{"line":633,"column":24},"end":{"line":633,"column":42}},"line":633},"28":{"name":"(anonymous_28)","decl":{"start":{"line":647,"column":27},"end":{"line":647,"column":32}},"loc":{"start":{"line":647,"column":46},"end":{"line":655,"column":12}},"line":647},"29":{"name":"(anonymous_29)","decl":{"start":{"line":648,"column":66},"end":{"line":648,"column":75}},"loc":{"start":{"line":648,"column":80},"end":{"line":648,"column":95}},"line":648},"30":{"name":"(anonymous_30)","decl":{"start":{"line":649,"column":33},"end":{"line":649,"column":37}},"loc":{"start":{"line":649,"column":42},"end":{"line":652,"column":13}},"line":649},"31":{"name":"(anonymous_31)","decl":{"start":{"line":650,"column":59},"end":{"line":650,"column":64}},"loc":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"line":650},"32":{"name":"(anonymous_32)","decl":{"start":{"line":677,"column":2},"end":{"line":677,"column":33}},"loc":{"start":{"line":677,"column":33},"end":{"line":732,"column":null}},"line":677},"33":{"name":"(anonymous_33)","decl":{"start":{"line":692,"column":63},"end":{"line":692,"column":67}},"loc":{"start":{"line":692,"column":72},"end":{"line":692,"column":78}},"line":692},"34":{"name":"(anonymous_34)","decl":{"start":{"line":699,"column":30},"end":{"line":699,"column":35}},"loc":{"start":{"line":699,"column":47},"end":{"line":714,"column":11}},"line":699},"35":{"name":"(anonymous_35)","decl":{"start":{"line":703,"column":32},"end":{"line":703,"column":36}},"loc":{"start":{"line":703,"column":41},"end":{"line":706,"column":15}},"line":703},"36":{"name":"(anonymous_36)","decl":{"start":{"line":704,"column":61},"end":{"line":704,"column":66}},"loc":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"line":704},"37":{"name":"(anonymous_37)","decl":{"start":{"line":735,"column":2},"end":{"line":735,"column":30}},"loc":{"start":{"line":735,"column":30},"end":{"line":789,"column":null}},"line":735},"38":{"name":"(anonymous_38)","decl":{"start":{"line":750,"column":26},"end":{"line":750,"column":34}},"loc":{"start":{"line":750,"column":39},"end":{"line":754,"column":5}},"line":750},"39":{"name":"(anonymous_39)","decl":{"start":{"line":757,"column":7},"end":{"line":757,"column":13}},"loc":{"start":{"line":757,"column":26},"end":{"line":757,"column":44}},"line":757},"40":{"name":"(anonymous_40)","decl":{"start":{"line":758,"column":7},"end":{"line":758,"column":16}},"loc":{"start":{"line":758,"column":38},"end":{"line":786,"column":7}},"line":758},"41":{"name":"(anonymous_41)","decl":{"start":{"line":769,"column":16},"end":{"line":769,"column":24}},"loc":{"start":{"line":769,"column":29},"end":{"line":781,"column":9}},"line":769},"42":{"name":"(anonymous_42)","decl":{"start":{"line":792,"column":2},"end":{"line":792,"column":18}},"loc":{"start":{"line":792,"column":18},"end":{"line":799,"column":null}},"line":792},"43":{"name":"(anonymous_43)","decl":{"start":{"line":793,"column":31},"end":{"line":793,"column":39}},"loc":{"start":{"line":793,"column":48},"end":{"line":797,"column":5}},"line":793}},"branchMap":{"0":{"loc":{"start":{"line":85,"column":25},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":25},"end":{"line":85,"column":38}},{"start":{"line":85,"column":38},"end":{"line":85,"column":null}}],"line":85},"1":{"loc":{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":87},"2":{"loc":{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":93},"3":{"loc":{"start":{"line":93,"column":8},"end":{"line":93,"column":43}},"type":"binary-expr","locations":[{"start":{"line":93,"column":8},"end":{"line":93,"column":22}},{"start":{"line":93,"column":22},"end":{"line":93,"column":43}}],"line":93},"4":{"loc":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":97},"5":{"loc":{"start":{"line":97,"column":8},"end":{"line":97,"column":47}},"type":"binary-expr","locations":[{"start":{"line":97,"column":8},"end":{"line":97,"column":26}},{"start":{"line":97,"column":26},"end":{"line":97,"column":47}}],"line":97},"6":{"loc":{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":101},"7":{"loc":{"start":{"line":101,"column":8},"end":{"line":101,"column":44}},"type":"binary-expr","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":23}},{"start":{"line":101,"column":23},"end":{"line":101,"column":44}}],"line":101},"8":{"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":105},"9":{"loc":{"start":{"line":105,"column":8},"end":{"line":105,"column":49}},"type":"binary-expr","locations":[{"start":{"line":105,"column":8},"end":{"line":105,"column":28}},{"start":{"line":105,"column":28},"end":{"line":105,"column":49}}],"line":105},"10":{"loc":{"start":{"line":109,"column":26},"end":{"line":109,"column":null}},"type":"binary-expr","locations":[{"start":{"line":109,"column":26},"end":{"line":109,"column":49}},{"start":{"line":109,"column":49},"end":{"line":109,"column":null}}],"line":109},"11":{"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":111},"12":{"loc":{"start":{"line":111,"column":8},"end":{"line":111,"column":42}},"type":"binary-expr","locations":[{"start":{"line":111,"column":8},"end":{"line":111,"column":27}},{"start":{"line":111,"column":27},"end":{"line":111,"column":42}}],"line":111},"13":{"loc":{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":115},"14":{"loc":{"start":{"line":115,"column":8},"end":{"line":115,"column":39}},"type":"binary-expr","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":24}},{"start":{"line":115,"column":24},"end":{"line":115,"column":39}}],"line":115},"15":{"loc":{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":119},"16":{"loc":{"start":{"line":119,"column":8},"end":{"line":119,"column":39}},"type":"binary-expr","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":24}},{"start":{"line":119,"column":24},"end":{"line":119,"column":39}}],"line":119},"17":{"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":128},"18":{"loc":{"start":{"line":128,"column":8},"end":{"line":128,"column":57}},"type":"binary-expr","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":22}},{"start":{"line":128,"column":22},"end":{"line":128,"column":57}}],"line":128},"19":{"loc":{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":134},"20":{"loc":{"start":{"line":134,"column":8},"end":{"line":134,"column":50}},"type":"binary-expr","locations":[{"start":{"line":134,"column":8},"end":{"line":134,"column":20}},{"start":{"line":134,"column":20},"end":{"line":134,"column":50}}],"line":134},"21":{"loc":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"type":"binary-expr","locations":[{"start":{"line":136,"column":13},"end":{"line":136,"column":18}},{"start":{"line":136,"column":18},"end":{"line":136,"column":31}},{"start":{"line":136,"column":31},"end":{"line":136,"column":null}}],"line":136},"22":{"loc":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":138},"23":{"loc":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"type":"binary-expr","locations":[{"start":{"line":145,"column":45},"end":{"line":145,"column":60}},{"start":{"line":145,"column":60},"end":{"line":145,"column":69}}],"line":145},"24":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":150,"column":72},"end":{"line":150,"column":90}},{"start":{"line":150,"column":90},"end":{"line":150,"column":null}}],"line":150},"25":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":72}},"type":"binary-expr","locations":[{"start":{"line":150,"column":16},"end":{"line":150,"column":21}},{"start":{"line":150,"column":21},"end":{"line":150,"column":34}},{"start":{"line":150,"column":34},"end":{"line":150,"column":72}}],"line":150},"26":{"loc":{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},"type":"if","locations":[{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},{"start":{},"end":{}}],"line":199},"27":{"loc":{"start":{"line":199,"column":8},"end":{"line":199,"column":53}},"type":"binary-expr","locations":[{"start":{"line":199,"column":8},"end":{"line":199,"column":23}},{"start":{"line":199,"column":23},"end":{"line":199,"column":53}}],"line":199},"28":{"loc":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"type":"binary-expr","locations":[{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},{"start":{"line":203,"column":10},"end":{"line":203,"column":null}},{"start":{"line":204,"column":10},"end":{"line":204,"column":null}},{"start":{"line":205,"column":10},"end":{"line":205,"column":null}}],"line":202},"29":{"loc":{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},{"start":{},"end":{}}],"line":207},"30":{"loc":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"type":"binary-expr","locations":[{"start":{"line":214,"column":45},"end":{"line":214,"column":60}},{"start":{"line":214,"column":60},"end":{"line":214,"column":69}}],"line":214},"31":{"loc":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"type":"cond-expr","locations":[{"start":{"line":220,"column":20},"end":{"line":220,"column":null}},{"start":{"line":221,"column":20},"end":{"line":221,"column":null}}],"line":219},"32":{"loc":{"start":{"line":219,"column":16},"end":{"line":219,"column":null}},"type":"binary-expr","locations":[{"start":{"line":219,"column":16},"end":{"line":219,"column":21}},{"start":{"line":219,"column":21},"end":{"line":219,"column":33}},{"start":{"line":219,"column":33},"end":{"line":219,"column":null}}],"line":219},"33":{"loc":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"type":"cond-expr","locations":[{"start":{"line":234,"column":20},"end":{"line":234,"column":null}},{"start":{"line":235,"column":20},"end":{"line":235,"column":null}}],"line":233},"34":{"loc":{"start":{"line":233,"column":16},"end":{"line":233,"column":null}},"type":"binary-expr","locations":[{"start":{"line":233,"column":16},"end":{"line":233,"column":21}},{"start":{"line":233,"column":21},"end":{"line":233,"column":33}},{"start":{"line":233,"column":33},"end":{"line":233,"column":null}}],"line":233},"35":{"loc":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"type":"if","locations":[{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},{"start":{},"end":{}}],"line":273},"36":{"loc":{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},"type":"if","locations":[{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},{"start":{},"end":{}}],"line":275},"37":{"loc":{"start":{"line":275,"column":8},"end":{"line":275,"column":50}},"type":"binary-expr","locations":[{"start":{"line":275,"column":8},"end":{"line":275,"column":18}},{"start":{"line":275,"column":18},"end":{"line":275,"column":50}}],"line":275},"38":{"loc":{"start":{"line":316,"column":8},"end":{"line":318,"column":null}},"type":"cond-expr","locations":[{"start":{"line":317,"column":12},"end":{"line":317,"column":null}},{"start":{"line":318,"column":12},"end":{"line":318,"column":null}}],"line":316},"39":{"loc":{"start":{"line":316,"column":8},"end":{"line":316,"column":null}},"type":"binary-expr","locations":[{"start":{"line":316,"column":8},"end":{"line":316,"column":14}},{"start":{"line":316,"column":14},"end":{"line":316,"column":55}},{"start":{"line":316,"column":55},"end":{"line":316,"column":null}}],"line":316},"40":{"loc":{"start":{"line":319,"column":31},"end":{"line":319,"column":null}},"type":"cond-expr","locations":[{"start":{"line":319,"column":57},"end":{"line":319,"column":85}},{"start":{"line":319,"column":85},"end":{"line":319,"column":null}}],"line":319},"41":{"loc":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},"type":"if","locations":[{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},{"start":{},"end":{}}],"line":343},"42":{"loc":{"start":{"line":343,"column":8},"end":{"line":343,"column":46}},"type":"binary-expr","locations":[{"start":{"line":343,"column":8},"end":{"line":343,"column":16}},{"start":{"line":343,"column":16},"end":{"line":343,"column":46}}],"line":343},"43":{"loc":{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},"type":"if","locations":[{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},{"start":{},"end":{}}],"line":345},"44":{"loc":{"start":{"line":346,"column":6},"end":{"line":350,"column":null}},"type":"binary-expr","locations":[{"start":{"line":346,"column":6},"end":{"line":346,"column":null}},{"start":{"line":347,"column":6},"end":{"line":347,"column":null}},{"start":{"line":348,"column":6},"end":{"line":348,"column":null}},{"start":{"line":349,"column":6},"end":{"line":349,"column":null}},{"start":{"line":350,"column":6},"end":{"line":350,"column":null}}],"line":346},"45":{"loc":{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},"type":"if","locations":[{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},{"start":{},"end":{}}],"line":397},"46":{"loc":{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},"type":"if","locations":[{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},{"start":{},"end":{}}],"line":399},"47":{"loc":{"start":{"line":399,"column":8},"end":{"line":399,"column":62}},"type":"binary-expr","locations":[{"start":{"line":399,"column":8},"end":{"line":399,"column":23}},{"start":{"line":399,"column":23},"end":{"line":399,"column":62}}],"line":399},"48":{"loc":{"start":{"line":436,"column":8},"end":{"line":436,"column":null}},"type":"cond-expr","locations":[{"start":{"line":436,"column":52},"end":{"line":436,"column":76}},{"start":{"line":436,"column":76},"end":{"line":436,"column":null}}],"line":436},"49":{"loc":{"start":{"line":438,"column":8},"end":{"line":440,"column":null}},"type":"cond-expr","locations":[{"start":{"line":439,"column":12},"end":{"line":439,"column":null}},{"start":{"line":440,"column":12},"end":{"line":440,"column":null}}],"line":438},"50":{"loc":{"start":{"line":438,"column":8},"end":{"line":438,"column":null}},"type":"binary-expr","locations":[{"start":{"line":438,"column":8},"end":{"line":438,"column":56}},{"start":{"line":438,"column":56},"end":{"line":438,"column":null}}],"line":438},"51":{"loc":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"type":"cond-expr","locations":[{"start":{"line":442,"column":56},"end":{"line":442,"column":84}},{"start":{"line":442,"column":84},"end":{"line":442,"column":null}}],"line":442},"52":{"loc":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"type":"cond-expr","locations":[{"start":{"line":444,"column":59},"end":{"line":444,"column":90}},{"start":{"line":444,"column":90},"end":{"line":444,"column":null}}],"line":444},"53":{"loc":{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},"type":"if","locations":[{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},{"start":{},"end":{}}],"line":458},"54":{"loc":{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},"type":"if","locations":[{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},{"start":{},"end":{}}],"line":477},"55":{"loc":{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},"type":"if","locations":[{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},{"start":{},"end":{}}],"line":506},"56":{"loc":{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},"type":"if","locations":[{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},{"start":{},"end":{}}],"line":508},"57":{"loc":{"start":{"line":508,"column":8},"end":{"line":508,"column":94}},"type":"binary-expr","locations":[{"start":{"line":508,"column":8},"end":{"line":508,"column":21}},{"start":{"line":508,"column":21},"end":{"line":508,"column":60}},{"start":{"line":508,"column":60},"end":{"line":508,"column":94}}],"line":508},"58":{"loc":{"start":{"line":552,"column":24},"end":{"line":552,"column":null}},"type":"binary-expr","locations":[{"start":{"line":552,"column":24},"end":{"line":552,"column":43}},{"start":{"line":552,"column":43},"end":{"line":552,"column":null}}],"line":552},"59":{"loc":{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},"type":"if","locations":[{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},{"start":{},"end":{}}],"line":568},"60":{"loc":{"start":{"line":569,"column":6},"end":{"line":571,"column":null}},"type":"binary-expr","locations":[{"start":{"line":569,"column":6},"end":{"line":569,"column":null}},{"start":{"line":570,"column":6},"end":{"line":570,"column":null}},{"start":{"line":571,"column":6},"end":{"line":571,"column":null}}],"line":569},"61":{"loc":{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},"type":"if","locations":[{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},{"start":{},"end":{}}],"line":578},"62":{"loc":{"start":{"line":578,"column":8},"end":{"line":578,"column":92}},"type":"binary-expr","locations":[{"start":{"line":578,"column":8},"end":{"line":578,"column":21}},{"start":{"line":578,"column":21},"end":{"line":578,"column":53}},{"start":{"line":578,"column":53},"end":{"line":578,"column":92}}],"line":578},"63":{"loc":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"type":"binary-expr","locations":[{"start":{"line":581,"column":59},"end":{"line":581,"column":76}},{"start":{"line":581,"column":76},"end":{"line":581,"column":94}}],"line":581},"64":{"loc":{"start":{"line":582,"column":15},"end":{"line":582,"column":null}},"type":"cond-expr","locations":[{"start":{"line":582,"column":23},"end":{"line":582,"column":37}},{"start":{"line":582,"column":37},"end":{"line":582,"column":null}}],"line":582},"65":{"loc":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"type":"binary-expr","locations":[{"start":{"line":585,"column":59},"end":{"line":585,"column":76}},{"start":{"line":585,"column":76},"end":{"line":585,"column":97}}],"line":585},"66":{"loc":{"start":{"line":586,"column":15},"end":{"line":586,"column":null}},"type":"cond-expr","locations":[{"start":{"line":586,"column":23},"end":{"line":586,"column":37}},{"start":{"line":586,"column":37},"end":{"line":586,"column":null}}],"line":586},"67":{"loc":{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},"type":"if","locations":[{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},{"start":{},"end":{}}],"line":629},"68":{"loc":{"start":{"line":629,"column":8},"end":{"line":629,"column":93}},"type":"binary-expr","locations":[{"start":{"line":629,"column":8},"end":{"line":629,"column":18}},{"start":{"line":629,"column":18},"end":{"line":629,"column":50}},{"start":{"line":629,"column":50},"end":{"line":629,"column":93}}],"line":629},"69":{"loc":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"type":"binary-expr","locations":[{"start":{"line":650,"column":69},"end":{"line":650,"column":86}},{"start":{"line":650,"column":86},"end":{"line":650,"column":113}}],"line":650},"70":{"loc":{"start":{"line":651,"column":21},"end":{"line":651,"column":null}},"type":"cond-expr","locations":[{"start":{"line":651,"column":29},"end":{"line":651,"column":53}},{"start":{"line":651,"column":53},"end":{"line":651,"column":null}}],"line":651},"71":{"loc":{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},"type":"if","locations":[{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},{"start":{},"end":{}}],"line":680},"72":{"loc":{"start":{"line":681,"column":6},"end":{"line":683,"column":null}},"type":"binary-expr","locations":[{"start":{"line":681,"column":6},"end":{"line":681,"column":null}},{"start":{"line":682,"column":6},"end":{"line":682,"column":null}},{"start":{"line":683,"column":6},"end":{"line":683,"column":null}}],"line":681},"73":{"loc":{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},"type":"if","locations":[{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},{"start":{},"end":{}}],"line":690},"74":{"loc":{"start":{"line":690,"column":8},"end":{"line":690,"column":93}},"type":"binary-expr","locations":[{"start":{"line":690,"column":8},"end":{"line":690,"column":18}},{"start":{"line":690,"column":18},"end":{"line":690,"column":50}},{"start":{"line":690,"column":50},"end":{"line":690,"column":93}}],"line":690},"75":{"loc":{"start":{"line":702,"column":21},"end":{"line":702,"column":null}},"type":"cond-expr","locations":[{"start":{"line":702,"column":38},"end":{"line":702,"column":50}},{"start":{"line":702,"column":50},"end":{"line":702,"column":null}}],"line":702},"76":{"loc":{"start":{"line":702,"column":50},"end":{"line":702,"column":null}},"type":"cond-expr","locations":[{"start":{"line":702,"column":67},"end":{"line":702,"column":89}},{"start":{"line":702,"column":89},"end":{"line":702,"column":null}}],"line":702},"77":{"loc":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"type":"binary-expr","locations":[{"start":{"line":704,"column":71},"end":{"line":704,"column":87}},{"start":{"line":704,"column":87},"end":{"line":704,"column":110}}],"line":704},"78":{"loc":{"start":{"line":705,"column":23},"end":{"line":705,"column":null}},"type":"cond-expr","locations":[{"start":{"line":705,"column":31},"end":{"line":705,"column":48}},{"start":{"line":705,"column":48},"end":{"line":705,"column":null}}],"line":705},"79":{"loc":{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},"type":"if","locations":[{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},{"start":{},"end":{}}],"line":739},"80":{"loc":{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},"type":"if","locations":[{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},{"start":{},"end":{}}],"line":741},"81":{"loc":{"start":{"line":741,"column":8},"end":{"line":741,"column":103}},"type":"binary-expr","locations":[{"start":{"line":741,"column":8},"end":{"line":741,"column":26}},{"start":{"line":741,"column":26},"end":{"line":741,"column":67}},{"start":{"line":741,"column":67},"end":{"line":741,"column":103}}],"line":741},"82":{"loc":{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},"type":"if","locations":[{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},{"start":{},"end":{}}],"line":752},"83":{"loc":{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},"type":"if","locations":[{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},{"start":{},"end":{}}],"line":794},"84":{"loc":{"start":{"line":794,"column":10},"end":{"line":794,"column":56}},"type":"binary-expr","locations":[{"start":{"line":794,"column":10},"end":{"line":794,"column":19}},{"start":{"line":794,"column":19},"end":{"line":794,"column":56}}],"line":794}},"s":{"0":32,"1":32,"2":32,"3":32,"4":4,"5":4,"6":1,"7":1,"8":3,"9":3,"10":3,"11":3,"12":3,"13":2,"14":3,"15":3,"16":2,"17":3,"18":3,"19":2,"20":3,"21":4,"22":4,"23":2,"24":3,"25":3,"26":2,"27":3,"28":3,"29":2,"30":6,"31":6,"32":1,"33":1,"34":5,"35":5,"36":4,"37":25,"38":4,"39":1,"40":4,"41":32,"42":32,"43":5,"44":5,"45":4,"46":25,"47":4,"48":1,"49":4,"50":32,"51":32,"52":32,"53":5,"54":5,"55":5,"56":1,"57":4,"58":1,"59":1,"60":3,"61":3,"62":3,"63":9,"64":9,"65":9,"66":9,"67":9,"68":9,"69":9,"70":9,"71":9,"72":9,"73":9,"74":9,"75":9,"76":9,"77":9,"78":9,"79":9,"80":9,"81":9,"82":9,"83":9,"84":9,"85":9,"86":9,"87":9,"88":9,"89":9,"90":9,"91":9,"92":9,"93":9,"94":9,"95":9,"96":9,"97":3,"98":4,"99":4,"100":4,"101":1,"102":3,"103":1,"104":1,"105":2,"106":2,"107":6,"108":5,"109":5,"110":5,"111":1,"112":4,"113":1,"114":1,"115":3,"116":3,"117":3,"118":3,"119":3,"120":3,"121":3,"122":3,"123":3,"124":3,"125":3,"126":12,"127":12,"128":12,"129":12,"130":12,"131":12,"132":12,"133":12,"134":12,"135":12,"136":12,"137":3,"138":3,"139":3,"140":3,"141":3,"142":3,"143":3,"144":3,"145":3,"146":3,"147":3,"148":3,"149":3,"150":3,"151":3,"152":6,"153":6,"154":6,"155":6,"156":3,"157":3,"158":3,"159":3,"160":3,"161":3,"162":3,"163":2,"164":2,"165":2,"166":2,"167":2,"168":2,"169":2,"170":2,"171":2,"172":2,"173":2,"174":2,"175":4,"176":4,"177":4,"178":0,"179":4,"180":1,"181":1,"182":3,"183":3,"184":3,"185":3,"186":3,"187":3,"188":3,"189":3,"190":3,"191":3,"192":3,"193":9,"194":9,"195":9,"196":9,"197":9,"198":9,"199":9,"200":9,"201":9,"202":9,"203":9,"204":3,"205":3,"206":3,"207":3,"208":3,"209":3,"210":3,"211":3,"212":3,"213":3,"214":3,"215":3,"216":3,"217":3,"218":3,"219":3,"220":3,"221":4,"222":4,"223":1,"224":1,"225":3,"226":3,"227":2,"228":2,"229":16,"230":56,"231":16,"232":2,"233":16,"234":60,"235":16,"236":2,"237":3,"238":3,"239":2,"240":2,"241":6,"242":2,"243":2,"244":2,"245":4,"246":4,"247":32,"248":90,"249":32,"250":3,"251":3,"252":1,"253":1,"254":2,"255":2,"256":2,"257":2,"258":8,"259":2,"260":2,"261":6,"262":6,"263":12,"264":36,"265":12,"266":4,"267":4,"268":4,"269":1,"270":3,"271":1,"272":1,"273":2,"274":2,"275":2,"276":2,"277":6,"278":6,"279":4,"280":6,"281":2,"282":2,"283":4,"284":4,"285":4,"286":4,"287":4,"288":4,"289":4,"290":4,"291":6,"292":6,"293":6,"294":6,"295":6,"296":6,"297":6,"298":6,"299":6,"300":6,"301":6,"302":4,"303":4,"304":4,"305":2,"306":4,"307":8,"308":8,"309":4},"f":{"0":32,"1":4,"2":6,"3":25,"4":32,"5":32,"6":25,"7":32,"8":32,"9":32,"10":5,"11":9,"12":4,"13":6,"14":5,"15":3,"16":12,"17":6,"18":4,"19":3,"20":9,"21":4,"22":16,"23":56,"24":16,"25":60,"26":6,"27":2,"28":4,"29":4,"30":32,"31":90,"32":3,"33":8,"34":6,"35":12,"36":36,"37":4,"38":6,"39":2,"40":4,"41":6,"42":4,"43":8},"b":{"0":[4,0],"1":[1,3],"2":[3,0],"3":[3,3],"4":[2,1],"5":[3,2],"6":[2,1],"7":[3,2],"8":[2,1],"9":[3,2],"10":[3,2],"11":[2,2],"12":[4,3],"13":[2,1],"14":[3,2],"15":[2,1],"16":[3,2],"17":[1,5],"18":[6,5],"19":[4,1],"20":[5,5],"21":[25,25,25],"22":[1,3],"23":[32,1],"24":[31,1],"25":[32,32,32],"26":[4,1],"27":[5,5],"28":[25,25,25,24],"29":[1,3],"30":[32,1],"31":[31,1],"32":[32,32,32],"33":[31,1],"34":[32,32,32],"35":[1,4],"36":[1,3],"37":[4,3],"38":[8,1],"39":[9,9,9],"40":[8,1],"41":[1,3],"42":[4,3],"43":[1,2],"44":[3,3,2,2,2],"45":[1,4],"46":[1,3],"47":[4,3],"48":[2,1],"49":[2,1],"50":[3,3],"51":[3,0],"52":[3,0],"53":[3,0],"54":[2,1],"55":[0,4],"56":[1,3],"57":[4,4,4],"58":[3,1],"59":[1,3],"60":[4,3,3],"61":[2,1],"62":[3,2,2],"63":[56,4],"64":[4,12],"65":[60,8],"66":[4,12],"67":[2,1],"68":[3,2,2],"69":[90,10],"70":[6,26],"71":[1,2],"72":[3,2,2],"73":[2,0],"74":[2,2,2],"75":[2,4],"76":[2,2],"77":[36,18],"78":[8,4],"79":[1,3],"80":[1,2],"81":[3,3,3],"82":[4,2],"83":[8,0],"84":[8,8]},"meta":{"lastBranch":85,"lastFunction":44,"lastStatement":310,"seen":{"s:45:15:45:Infinity":0,"s:76:44:76:Infinity":1,"f:78:2:78:14":0,"s:79:4:79:Infinity":2,"s:80:4:80:Infinity":3,"f:84:2:84:27":1,"s:85:25:85:Infinity":4,"b:85:25:85:38:85:38:85:Infinity":0,"b:87:4:90:Infinity:undefined:undefined:undefined:undefined":1,"s:87:4:90:Infinity":5,"s:88:6:88:Infinity":6,"s:89:6:89:Infinity":7,"s:92:23:92:Infinity":8,"b:93:4:95:Infinity:undefined:undefined:undefined:undefined":2,"s:93:4:95:Infinity":9,"b:93:8:93:22:93:22:93:43":3,"s:94:6:94:Infinity":10,"s:96:27:96:Infinity":11,"b:97:4:99:Infinity:undefined:undefined:undefined:undefined":4,"s:97:4:99:Infinity":12,"b:97:8:97:26:97:26:97:47":5,"s:98:6:98:Infinity":13,"s:100:24:100:Infinity":14,"b:101:4:103:Infinity:undefined:undefined:undefined:undefined":6,"s:101:4:103:Infinity":15,"b:101:8:101:23:101:23:101:44":7,"s:102:6:102:Infinity":16,"s:104:29:104:Infinity":17,"b:105:4:107:Infinity:undefined:undefined:undefined:undefined":8,"s:105:4:107:Infinity":18,"b:105:8:105:28:105:28:105:49":9,"s:106:6:106:Infinity":19,"s:109:26:109:Infinity":20,"b:109:26:109:49:109:49:109:Infinity":10,"s:110:28:110:Infinity":21,"b:111:4:113:Infinity:undefined:undefined:undefined:undefined":11,"s:111:4:113:Infinity":22,"b:111:8:111:27:111:27:111:42":12,"s:112:6:112:Infinity":23,"s:114:25:114:Infinity":24,"b:115:4:117:Infinity:undefined:undefined:undefined:undefined":13,"s:115:4:117:Infinity":25,"b:115:8:115:24:115:24:115:39":14,"s:116:6:116:Infinity":26,"s:118:25:118:Infinity":27,"b:119:4:121:Infinity:undefined:undefined:undefined:undefined":15,"s:119:4:121:Infinity":28,"b:119:8:119:24:119:24:119:39":16,"s:120:6:120:Infinity":29,"f:125:2:125:33":2,"s:126:26:126:Infinity":30,"b:128:4:131:Infinity:undefined:undefined:undefined:undefined":17,"s:128:4:131:Infinity":31,"b:128:8:128:22:128:22:128:57":18,"s:129:6:129:Infinity":32,"s:130:6:130:Infinity":33,"s:133:21:133:Infinity":34,"b:134:4:196:Infinity:undefined:undefined:undefined:undefined":19,"s:134:4:196:Infinity":35,"b:134:8:134:20:134:20:134:50":20,"s:135:30:137:Infinity":36,"f:135:48:135:Infinity":3,"s:136:13:136:Infinity":37,"b:136:13:136:18:136:18:136:31:136:31:136:Infinity":21,"b:138:6:140:Infinity:undefined:undefined:undefined:undefined":22,"s:138:6:140:Infinity":38,"s:139:8:139:Infinity":39,"s:142:6:195:Infinity":40,"f:145:36:145:40":4,"s:145:45:145:69":41,"b:145:45:145:60:145:60:145:69":23,"f:149:38:149:42":5,"s:150:16:150:Infinity":42,"b:150:72:150:90:150:90:150:Infinity":24,"b:150:16:150:21:150:21:150:34:150:34:150:72":25,"s:198:24:198:Infinity":43,"b:199:4:265:Infinity:undefined:undefined:undefined:undefined":26,"s:199:4:265:Infinity":44,"b:199:8:199:23:199:23:199:53":27,"s:200:29:206:Infinity":45,"f:200:47:200:Infinity":6,"s:202:10:205:Infinity":46,"b:202:10:202:Infinity:203:10:203:Infinity:204:10:204:Infinity:205:10:205:Infinity":28,"b:207:6:209:Infinity:undefined:undefined:undefined:undefined":29,"s:207:6:209:Infinity":47,"s:208:8:208:Infinity":48,"s:211:6:264:Infinity":49,"f:214:36:214:40":7,"s:214:45:214:69":50,"b:214:45:214:60:214:60:214:69":30,"f:218:38:218:42":8,"s:219:16:221:Infinity":51,"b:220:20:220:Infinity:221:20:221:Infinity":31,"b:219:16:219:21:219:21:219:33:219:33:219:Infinity":32,"f:232:38:232:42":9,"s:233:16:235:Infinity":52,"b:234:20:234:Infinity:235:20:235:Infinity":33,"b:233:16:233:21:233:21:233:33:233:33:233:Infinity":34,"f:269:2:269:30":10,"s:270:22:270:Infinity":53,"s:271:22:271:Infinity":54,"b:273:4:273:Infinity:undefined:undefined:undefined:undefined":35,"s:273:4:273:Infinity":55,"s:273:20:273:Infinity":56,"b:275:4:278:Infinity:undefined:undefined:undefined:undefined":36,"s:275:4:278:Infinity":57,"b:275:8:275:18:275:18:275:50":37,"s:276:6:276:Infinity":58,"s:277:6:277:Infinity":59,"s:280:4:280:Infinity":60,"s:281:21:281:Infinity":61,"s:283:4:333:Infinity":62,"f:283:19:283:28":11,"s:284:19:284:Infinity":63,"s:285:6:285:Infinity":64,"s:287:21:287:Infinity":65,"s:288:6:288:Infinity":66,"s:289:6:289:Infinity":67,"s:291:19:291:Infinity":68,"s:292:6:292:Infinity":69,"s:294:19:294:Infinity":70,"s:295:6:295:Infinity":71,"s:296:6:296:Infinity":72,"s:298:20:298:Infinity":73,"s:299:6:299:Infinity":74,"s:300:6:300:Infinity":75,"s:302:19:302:Infinity":76,"s:303:6:303:Infinity":77,"s:304:6:304:Infinity":78,"s:306:6:306:Infinity":79,"s:307:6:307:Infinity":80,"s:308:6:308:Infinity":81,"s:310:20:310:Infinity":82,"s:311:6:311:Infinity":83,"s:313:25:313:Infinity":84,"s:314:6:314:Infinity":85,"s:316:8:318:Infinity":86,"b:317:12:317:Infinity:318:12:318:Infinity":38,"b:316:8:316:14:316:14:316:55:316:55:316:Infinity":39,"s:319:6:319:Infinity":87,"b:319:57:319:85:319:85:319:Infinity":40,"s:321:25:321:Infinity":88,"s:322:6:322:Infinity":89,"s:323:6:323:Infinity":90,"s:325:6:325:Infinity":91,"s:326:6:326:Infinity":92,"s:328:6:328:Infinity":93,"s:329:6:329:Infinity":94,"s:330:6:330:Infinity":95,"s:332:6:332:Infinity":96,"s:335:4:335:Infinity":97,"f:339:2:339:31":12,"s:340:31:340:Infinity":98,"s:341:16:341:Infinity":99,"b:343:4:343:Infinity:undefined:undefined:undefined:undefined":41,"s:343:4:343:Infinity":100,"b:343:8:343:16:343:16:343:46":42,"s:343:46:343:Infinity":101,"b:345:4:354:Infinity:undefined:undefined:undefined:undefined":43,"s:345:4:354:Infinity":102,"b:346:6:346:Infinity:347:6:347:Infinity:348:6:348:Infinity:349:6:349:Infinity:350:6:350:Infinity":44,"s:352:6:352:Infinity":103,"s:353:6:353:Infinity":104,"s:356:19:356:Infinity":105,"s:358:4:389:Infinity":106,"f:362:41:362:46":13,"s:362:76:367:10":107,"f:393:2:393:33":14,"s:394:27:394:Infinity":108,"s:395:22:395:Infinity":109,"b:397:4:397:Infinity:undefined:undefined:undefined:undefined":45,"s:397:4:397:Infinity":110,"s:397:20:397:Infinity":111,"b:399:4:402:Infinity:undefined:undefined:undefined:undefined":46,"s:399:4:402:Infinity":112,"b:399:8:399:23:399:23:399:62":47,"s:400:6:400:Infinity":113,"s:401:6:401:Infinity":114,"s:404:4:404:Infinity":115,"s:405:21:405:Infinity":116,"s:407:4:472:Infinity":117,"f:407:26:407:35":15,"s:408:19:408:Infinity":118,"s:409:6:409:Infinity":119,"s:411:21:411:Infinity":120,"s:412:6:412:Infinity":121,"s:413:6:413:Infinity":122,"s:415:20:415:Infinity":123,"s:416:6:416:Infinity":124,"s:418:12:433:Infinity":125,"f:418:12:418:26":16,"s:419:21:419:Infinity":126,"s:420:8:420:Infinity":127,"s:422:26:422:Infinity":128,"s:423:8:423:Infinity":129,"s:424:8:424:Infinity":130,"s:426:26:426:Infinity":131,"s:427:8:427:Infinity":132,"s:428:8:428:Infinity":133,"s:430:8:430:Infinity":134,"s:431:8:431:Infinity":135,"s:432:8:432:Infinity":136,"s:436:8:436:Infinity":137,"b:436:52:436:76:436:76:436:Infinity":48,"s:438:8:440:Infinity":138,"b:439:12:439:Infinity:440:12:440:Infinity":49,"b:438:8:438:56:438:56:438:Infinity":50,"s:442:8:442:Infinity":139,"b:442:56:442:84:442:84:442:Infinity":51,"s:444:8:444:Infinity":140,"b:444:59:444:90:444:90:444:Infinity":52,"s:446:6:446:Infinity":141,"s:447:6:447:Infinity":142,"s:448:6:448:Infinity":143,"s:449:6:449:Infinity":144,"s:451:21:451:Infinity":145,"s:452:6:452:Infinity":146,"s:454:28:454:Infinity":147,"s:455:6:455:Infinity":148,"s:456:6:456:Infinity":149,"b:458:6:465:Infinity:undefined:undefined:undefined:undefined":53,"s:458:6:465:Infinity":150,"s:459:8:464:Infinity":151,"f:459:28:459:37":17,"s:460:22:460:Infinity":152,"s:461:10:461:Infinity":153,"s:462:10:462:Infinity":154,"s:463:10:463:Infinity":155,"s:467:6:467:Infinity":156,"s:468:6:468:Infinity":157,"s:469:6:469:Infinity":158,"s:471:6:471:Infinity":159,"s:474:4:474:Infinity":160,"s:476:23:476:Infinity":161,"b:477:4:498:Infinity:undefined:undefined:undefined:undefined":54,"s:477:4:498:Infinity":162,"s:478:6:478:Infinity":163,"s:480:21:480:Infinity":164,"s:482:17:482:Infinity":165,"s:483:21:483:Infinity":166,"s:484:6:484:Infinity":167,"s:485:6:485:Infinity":168,"s:486:6:490:Infinity":169,"s:492:17:492:Infinity":170,"s:493:6:493:Infinity":171,"s:495:6:495:Infinity":172,"s:496:6:496:Infinity":173,"s:497:6:497:Infinity":174,"f:502:2:502:36":18,"s:503:25:503:Infinity":175,"s:504:22:504:Infinity":176,"b:506:4:506:Infinity:undefined:undefined:undefined:undefined":55,"s:506:4:506:Infinity":177,"s:506:20:506:Infinity":178,"b:508:4:511:Infinity:undefined:undefined:undefined:undefined":56,"s:508:4:511:Infinity":179,"b:508:8:508:21:508:21:508:60:508:60:508:94":57,"s:509:6:509:Infinity":180,"s:510:6:510:Infinity":181,"s:513:4:513:Infinity":182,"s:514:21:514:Infinity":183,"s:516:4:559:Infinity":184,"f:516:24:516:32":19,"s:517:19:517:Infinity":185,"s:518:6:518:Infinity":186,"s:520:21:520:Infinity":187,"s:521:6:521:Infinity":188,"s:522:6:522:Infinity":189,"s:524:20:524:Infinity":190,"s:525:6:525:Infinity":191,"s:527:12:539:Infinity":192,"f:527:12:527:26":20,"s:528:21:528:Infinity":193,"s:529:8:529:Infinity":194,"s:530:26:530:Infinity":195,"s:531:8:531:Infinity":196,"s:532:8:532:Infinity":197,"s:533:26:533:Infinity":198,"s:534:8:534:Infinity":199,"s:535:8:535:Infinity":200,"s:536:8:536:Infinity":201,"s:537:8:537:Infinity":202,"s:538:8:538:Infinity":203,"s:541:6:541:Infinity":204,"s:542:6:542:Infinity":205,"s:543:6:543:Infinity":206,"s:545:25:545:Infinity":207,"s:546:6:546:Infinity":208,"s:547:28:547:Infinity":209,"s:548:6:548:Infinity":210,"s:549:6:549:Infinity":211,"s:550:18:550:Infinity":212,"s:551:6:551:Infinity":213,"s:552:6:552:Infinity":214,"b:552:24:552:43:552:43:552:Infinity":58,"s:553:6:553:Infinity":215,"s:555:6:555:Infinity":216,"s:556:6:556:Infinity":217,"s:557:6:557:Infinity":218,"s:558:6:558:Infinity":219,"s:561:4:561:Infinity":220,"f:565:2:565:29":21,"s:566:29:566:Infinity":221,"b:568:4:575:Infinity:undefined:undefined:undefined:undefined":59,"s:568:4:575:Infinity":222,"b:569:6:569:Infinity:570:6:570:Infinity:571:6:571:Infinity":60,"s:573:6:573:Infinity":223,"s:574:6:574:Infinity":224,"s:577:22:577:Infinity":225,"b:578:4:626:Infinity:undefined:undefined:undefined:undefined":61,"s:578:4:626:Infinity":226,"b:578:8:578:21:578:21:578:53:578:53:578:92":62,"s:579:29:579:Infinity":227,"s:580:23:583:Infinity":228,"f:580:38:580:42":22,"s:581:22:581:Infinity":229,"f:581:49:581:54":23,"s:581:59:581:94":230,"b:581:59:581:76:581:76:581:94":63,"s:582:8:582:Infinity":231,"b:582:23:582:37:582:37:582:Infinity":64,"s:584:25:587:Infinity":232,"f:584:40:584:44":24,"s:585:22:585:Infinity":233,"f:585:49:585:54":25,"s:585:59:585:97":234,"b:585:59:585:76:585:76:585:97":65,"s:586:8:586:Infinity":235,"b:586:23:586:37:586:37:586:Infinity":66,"s:589:6:625:Infinity":236,"s:628:19:628:Infinity":237,"b:629:4:673:Infinity:undefined:undefined:undefined:undefined":67,"s:629:4:673:Infinity":238,"b:629:8:629:18:629:18:629:50:629:50:629:93":68,"s:630:29:630:Infinity":239,"s:631:21:633:Infinity":240,"f:631:64:631:68":26,"s:631:73:631:90":241,"f:633:9:633:15":27,"s:633:24:633:42":242,"s:634:21:641:Infinity":243,"s:643:6:672:Infinity":244,"f:647:27:647:32":28,"s:647:46:655:12":245,"f:648:66:648:75":29,"s:648:80:648:95":246,"f:649:33:649:37":30,"s:650:28:650:Infinity":247,"f:650:59:650:64":31,"s:650:69:650:113":248,"b:650:69:650:86:650:86:650:113":69,"s:651:14:651:Infinity":249,"b:651:29:651:53:651:53:651:Infinity":70,"f:677:2:677:33":32,"s:678:33:678:Infinity":250,"b:680:4:687:Infinity:undefined:undefined:undefined:undefined":71,"s:680:4:687:Infinity":251,"b:681:6:681:Infinity:682:6:682:Infinity:683:6:683:Infinity":72,"s:685:6:685:Infinity":252,"s:686:6:686:Infinity":253,"s:689:19:689:Infinity":254,"b:690:4:731:Infinity:undefined:undefined:undefined:undefined":73,"s:690:4:731:Infinity":255,"b:690:8:690:18:690:18:690:50:690:50:690:93":74,"s:691:24:691:Infinity":256,"s:692:20:692:Infinity":257,"f:692:63:692:67":33,"s:692:72:692:78":258,"s:693:26:693:Infinity":259,"s:695:6:730:Infinity":260,"f:699:30:699:35":34,"s:700:27:700:Infinity":261,"s:701:12:713:Infinity":262,"b:702:38:702:50:702:50:702:Infinity":75,"b:702:67:702:89:702:89:702:Infinity":76,"f:703:32:703:36":35,"s:704:30:704:Infinity":263,"f:704:61:704:66":36,"s:704:71:704:110":264,"b:704:71:704:87:704:87:704:110":77,"s:705:16:705:Infinity":265,"b:705:31:705:48:705:48:705:Infinity":78,"f:735:2:735:30":37,"s:736:30:736:Infinity":266,"s:737:22:737:Infinity":267,"b:739:4:739:Infinity:undefined:undefined:undefined:undefined":79,"s:739:4:739:Infinity":268,"s:739:20:739:Infinity":269,"b:741:4:744:Infinity:undefined:undefined:undefined:undefined":80,"s:741:4:744:Infinity":270,"b:741:8:741:26:741:26:741:67:741:67:741:103":81,"s:742:6:742:Infinity":271,"s:743:6:743:Infinity":272,"s:746:4:746:Infinity":273,"s:747:21:747:Infinity":274,"s:749:71:749:Infinity":275,"s:750:4:754:Infinity":276,"f:750:26:750:34":38,"s:751:21:751:Infinity":277,"b:752:6:752:Infinity:undefined:undefined:undefined:undefined":82,"s:752:6:752:Infinity":278,"s:752:33:752:Infinity":279,"s:753:6:753:Infinity":280,"s:756:4:786:Infinity":281,"f:757:7:757:13":39,"s:757:26:757:44":282,"f:758:7:758:16":40,"s:759:21:759:Infinity":283,"s:760:8:760:Infinity":284,"s:762:23:762:Infinity":285,"s:763:8:763:Infinity":286,"s:764:8:764:Infinity":287,"s:766:22:766:Infinity":288,"s:767:8:767:Infinity":289,"s:769:8:781:Infinity":290,"f:769:16:769:24":41,"s:770:23:770:Infinity":291,"s:771:10:771:Infinity":292,"s:772:24:772:Infinity":293,"s:773:10:773:Infinity":294,"s:774:10:774:Infinity":295,"s:775:24:775:Infinity":296,"s:776:10:776:Infinity":297,"s:777:10:777:Infinity":298,"s:778:10:778:Infinity":299,"s:779:10:779:Infinity":300,"s:780:10:780:Infinity":301,"s:783:8:783:Infinity":302,"s:784:8:784:Infinity":303,"s:785:8:785:Infinity":304,"s:788:4:788:Infinity":305,"f:792:2:792:18":42,"s:793:4:797:Infinity":306,"f:793:31:793:39":43,"b:794:6:796:Infinity:undefined:undefined:undefined:undefined":83,"s:794:6:796:Infinity":307,"b:794:10:794:19:794:19:794:56":84,"s:795:8:795:Infinity":308,"s:798:4:798:Infinity":309}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/sources.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/sources.ts","statementMap":{"0":{"start":{"line":21,"column":50},"end":{"line":23,"column":null}},"1":{"start":{"line":26,"column":69},"end":{"line":45,"column":null}},"2":{"start":{"line":51,"column":51},"end":{"line":51,"column":null}},"3":{"start":{"line":60,"column":38},"end":{"line":165,"column":null}},"4":{"start":{"line":168,"column":51},"end":{"line":172,"column":null}},"5":{"start":{"line":170,"column":58},"end":{"line":170,"column":92}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":170,"column":36},"end":{"line":170,"column":41}},"loc":{"start":{"line":170,"column":58},"end":{"line":170,"column":92}},"line":170}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":130},"f":{"0":130},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":6,"seen":{"s:21:50:23:Infinity":0,"s:26:69:45:Infinity":1,"s:51:51:51:Infinity":2,"s:60:38:165:Infinity":3,"s:168:51:172:Infinity":4,"f:170:36:170:41":0,"s:170:58:170:92":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/error-boundary.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/error-boundary.ts","statementMap":{"0":{"start":{"line":53,"column":23},"end":{"line":53,"column":null}},"1":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"2":{"start":{"line":55,"column":23},"end":{"line":55,"column":null}},"3":{"start":{"line":57,"column":18},"end":{"line":106,"column":null}},"4":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"5":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"9":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"10":{"start":{"line":69,"column":27},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"14":{"start":{"line":74,"column":32},"end":{"line":74,"column":null}},"15":{"start":{"line":75,"column":28},"end":{"line":75,"column":null}},"16":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"17":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"18":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"19":{"start":{"line":81,"column":4},"end":{"line":81,"column":null}},"20":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"21":{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},"22":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"23":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"24":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"25":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"26":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"27":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"28":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"29":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"30":{"start":{"line":94,"column":4},"end":{"line":105,"column":null}},"31":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"32":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"33":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"34":{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},"35":{"start":{"line":101,"column":8},"end":{"line":101,"column":null}},"36":{"start":{"line":103,"column":6},"end":{"line":103,"column":null}},"37":{"start":{"line":104,"column":6},"end":{"line":104,"column":null}},"38":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}}},"fnMap":{"0":{"name":"renderWithFallback","decl":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"loc":{"start":{"line":52,"column":17},"end":{"line":109,"column":null}},"line":52},"1":{"name":"(anonymous_1)","decl":{"start":{"line":57,"column":18},"end":{"line":57,"column":45}},"loc":{"start":{"line":57,"column":45},"end":{"line":106,"column":null}},"line":57}},"branchMap":{"0":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"default-arg","locations":[{"start":{"line":50,"column":20},"end":{"line":50,"column":null}}],"line":50},"1":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"default-arg","locations":[{"start":{"line":51,"column":39},"end":{"line":51,"column":null}}],"line":51},"2":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"4":{"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76},"5":{"loc":{"start":{"line":76,"column":8},"end":{"line":76,"column":64}},"type":"binary-expr","locations":[{"start":{"line":76,"column":8},"end":{"line":76,"column":34}},{"start":{"line":76,"column":34},"end":{"line":76,"column":64}}],"line":76},"6":{"loc":{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":100}},"s":{"0":14,"1":14,"2":14,"3":14,"4":18,"5":1,"6":17,"7":17,"8":3,"9":17,"10":17,"11":17,"12":17,"13":17,"14":17,"15":17,"16":17,"17":17,"18":17,"19":17,"20":17,"21":17,"22":17,"23":17,"24":17,"25":17,"26":17,"27":17,"28":17,"29":17,"30":17,"31":17,"32":9,"33":9,"34":17,"35":4,"36":17,"37":17,"38":14},"f":{"0":14,"1":18},"b":{"0":[14],"1":[14],"2":[1,17],"3":[3,14],"4":[17,0],"5":[17,0],"6":[4,13]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":39,"seen":{"f:47:22:47:Infinity":0,"b:50:20:50:Infinity":0,"b:51:39:51:Infinity":1,"s:53:23:53:Infinity":0,"s:54:17:54:Infinity":1,"s:55:23:55:Infinity":2,"s:57:18:106:Infinity":3,"f:57:18:57:45":1,"b:58:4:60:Infinity:undefined:undefined:undefined:undefined":2,"s:58:4:60:Infinity":4,"s:59:6:59:Infinity":5,"s:62:4:62:Infinity":6,"b:64:4:66:Infinity:undefined:undefined:undefined:undefined":3,"s:64:4:66:Infinity":7,"s:65:6:65:Infinity":8,"s:67:4:67:Infinity":9,"s:69:27:69:Infinity":10,"s:70:4:70:Infinity":11,"s:71:4:71:Infinity":12,"s:72:4:72:Infinity":13,"s:74:32:74:Infinity":14,"s:75:28:75:Infinity":15,"b:76:4:78:Infinity:undefined:undefined:undefined:undefined":4,"s:76:4:78:Infinity":16,"b:76:8:76:34:76:34:76:64":5,"s:77:6:77:Infinity":17,"s:80:4:80:Infinity":18,"s:81:4:81:Infinity":19,"s:82:4:82:Infinity":20,"s:83:4:83:Infinity":21,"s:84:4:84:Infinity":22,"s:85:4:85:Infinity":23,"s:86:4:86:Infinity":24,"s:87:4:87:Infinity":25,"s:88:4:88:Infinity":26,"s:89:4:89:Infinity":27,"s:91:4:91:Infinity":28,"s:92:4:92:Infinity":29,"s:94:4:105:Infinity":30,"s:95:6:95:Infinity":31,"s:97:6:97:Infinity":32,"s:98:6:98:Infinity":33,"b:100:6:102:Infinity:undefined:undefined:undefined:undefined":6,"s:100:6:102:Infinity":34,"s:101:8:101:Infinity":35,"s:103:6:103:Infinity":36,"s:104:6:104:Infinity":37,"s:108:2:108:Infinity":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/fallback-ui.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/fallback-ui.ts","statementMap":{"0":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"1":{"start":{"line":31,"column":15},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"5":{"start":{"line":36,"column":15},"end":{"line":36,"column":null}},"6":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"8":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"9":{"start":{"line":41,"column":15},"end":{"line":41,"column":null}},"10":{"start":{"line":42,"column":2},"end":{"line":42,"column":null}},"11":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"12":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"13":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"14":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"15":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"21":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"22":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"23":{"start":{"line":67,"column":18},"end":{"line":67,"column":null}},"24":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"25":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"26":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"27":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"28":{"start":{"line":73,"column":2},"end":{"line":77,"column":null}},"29":{"start":{"line":73,"column":15},"end":{"line":73,"column":18}},"30":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"31":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"32":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"33":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"renderErrorFallback","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":null}},"loc":{"start":{"line":28,"column":8},"end":{"line":58,"column":null}},"line":28},"1":{"name":"renderLoadingFallback","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":38}},"loc":{"start":{"line":64,"column":95},"end":{"line":80,"column":null}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"default-arg","locations":[{"start":{"line":25,"column":12},"end":{"line":25,"column":null}}],"line":25},"1":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"default-arg","locations":[{"start":{"line":27,"column":15},"end":{"line":27,"column":null}}],"line":27},"2":{"loc":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":64,"column":62},"end":{"line":64,"column":95}},"type":"default-arg","locations":[{"start":{"line":64,"column":77},"end":{"line":64,"column":95}}],"line":64}},"s":{"0":19,"1":19,"2":19,"3":19,"4":19,"5":19,"6":19,"7":19,"8":19,"9":19,"10":19,"11":19,"12":19,"13":19,"14":19,"15":13,"16":13,"17":13,"18":13,"19":13,"20":13,"21":19,"22":23,"23":23,"24":23,"25":23,"26":23,"27":23,"28":23,"29":23,"30":69,"31":69,"32":69,"33":23},"f":{"0":19,"1":23},"b":{"0":[19],"1":[19],"2":[13,6],"3":[23]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":34,"seen":{"f:23:16:23:Infinity":0,"b:25:12:25:Infinity":0,"b:27:15:27:Infinity":1,"s:29:2:29:Infinity":0,"s:31:15:31:Infinity":1,"s:32:2:32:Infinity":2,"s:33:2:33:Infinity":3,"s:34:2:34:Infinity":4,"s:36:15:36:Infinity":5,"s:37:2:37:Infinity":6,"s:38:2:38:Infinity":7,"s:39:2:39:Infinity":8,"s:41:15:41:Infinity":9,"s:42:2:42:Infinity":10,"s:43:2:43:Infinity":11,"s:45:2:45:Infinity":12,"s:46:2:46:Infinity":13,"b:48:2:55:Infinity:undefined:undefined:undefined:undefined":2,"s:48:2:55:Infinity":14,"s:49:16:49:Infinity":15,"s:50:4:50:Infinity":16,"s:51:4:51:Infinity":17,"s:52:4:52:Infinity":18,"s:53:4:53:Infinity":19,"s:54:4:54:Infinity":20,"s:57:2:57:Infinity":21,"f:64:16:64:38":1,"b:64:77:64:95":3,"s:65:2:65:Infinity":22,"s:67:18:67:Infinity":23,"s:68:2:68:Infinity":24,"s:69:2:69:Infinity":25,"s:70:2:70:Infinity":26,"s:71:2:71:Infinity":27,"s:73:2:77:Infinity":28,"s:73:15:73:18":29,"s:74:16:74:Infinity":30,"s:75:4:75:Infinity":31,"s:76:4:76:Infinity":32,"s:79:2:79:Infinity":33}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/global-libs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/global-libs.ts","statementMap":{"0":{"start":{"line":49,"column":23},"end":{"line":49,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":4},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:49:23:49:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/safe-storage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/safe-storage.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":23,"column":36},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":50,"column":2},"end":{"line":58,"column":null}},"4":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"6":{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},"7":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"8":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"9":{"start":{"line":60,"column":59},"end":{"line":60,"column":null}},"10":{"start":{"line":61,"column":2},"end":{"line":79,"column":null}},"11":{"start":{"line":62,"column":4},"end":{"line":76,"column":null}},"12":{"start":{"line":62,"column":17},"end":{"line":62,"column":20}},"13":{"start":{"line":63,"column":16},"end":{"line":63,"column":null}},"14":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"15":{"start":{"line":64,"column":60},"end":{"line":64,"column":null}},"16":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"17":{"start":{"line":66,"column":6},"end":{"line":74,"column":null}},"18":{"start":{"line":67,"column":20},"end":{"line":67,"column":null}},"19":{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},"20":{"start":{"line":69,"column":25},"end":{"line":69,"column":null}},"21":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"22":{"start":{"line":70,"column":52},"end":{"line":70,"column":null}},"23":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"24":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"25":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"26":{"start":{"line":81,"column":28},"end":{"line":81,"column":53}},"27":{"start":{"line":82,"column":22},"end":{"line":82,"column":null}},"28":{"start":{"line":83,"column":2},"end":{"line":85,"column":null}},"29":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"30":{"start":{"line":84,"column":10},"end":{"line":84,"column":46}},"31":{"start":{"line":87,"column":2},"end":{"line":96,"column":null}},"32":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"33":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"34":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"35":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"36":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"37":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}}},"fnMap":{"0":{"name":"isQuotaError","decl":{"start":{"line":22,"column":9},"end":{"line":22,"column":22}},"loc":{"start":{"line":22,"column":43},"end":{"line":30,"column":null}},"line":22},"1":{"name":"safeSetItem","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"loc":{"start":{"line":49,"column":11},"end":{"line":97,"column":null}},"line":49},"2":{"name":"(anonymous_2)","decl":{"start":{"line":81,"column":13},"end":{"line":81,"column":19}},"loc":{"start":{"line":81,"column":28},"end":{"line":81,"column":53}},"line":81}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23},"1":{"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":null}},"type":"binary-expr","locations":[{"start":{"line":25,"column":4},"end":{"line":25,"column":null}},{"start":{"line":26,"column":4},"end":{"line":26,"column":null}},{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},{"start":{"line":28,"column":4},"end":{"line":28,"column":null}}],"line":25},"2":{"loc":{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":54},"3":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":64},"4":{"loc":{"start":{"line":64,"column":10},"end":{"line":64,"column":60}},"type":"binary-expr","locations":[{"start":{"line":64,"column":10},"end":{"line":64,"column":16}},{"start":{"line":64,"column":16},"end":{"line":64,"column":49}},{"start":{"line":64,"column":49},"end":{"line":64,"column":60}}],"line":64},"5":{"loc":{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":68},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":70},"7":{"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":91}},"s":{"0":6,"1":0,"2":6,"3":6,"4":6,"5":6,"6":5,"7":2,"8":2,"9":3,"10":3,"11":3,"12":3,"13":9,"14":9,"15":3,"16":6,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"23":6,"24":0,"25":3,"26":3,"27":3,"28":3,"29":4,"30":4,"31":3,"32":3,"33":3,"34":1,"35":1,"36":0,"37":0},"f":{"0":6,"1":6,"2":3},"b":{"0":[0,6],"1":[6,2,2,2],"2":[2,3],"3":[3,6],"4":[9,9,6],"5":[6,0],"6":[6,0],"7":[1,0]},"meta":{"lastBranch":8,"lastFunction":3,"lastStatement":38,"seen":{"f:22:9:22:22":0,"b:23:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:23:2:23:Infinity":0,"s:23:36:23:Infinity":1,"s:24:2:28:Infinity":2,"b:25:4:25:Infinity:26:4:26:Infinity:27:4:27:Infinity:28:4:28:Infinity":1,"f:45:16:45:Infinity":1,"s:50:2:58:Infinity":3,"s:51:4:51:Infinity":4,"s:52:4:52:Infinity":5,"b:54:4:57:Infinity:undefined:undefined:undefined:undefined":2,"s:54:4:57:Infinity":6,"s:55:6:55:Infinity":7,"s:56:6:56:Infinity":8,"s:60:59:60:Infinity":9,"s:61:2:79:Infinity":10,"s:62:4:76:Infinity":11,"s:62:17:62:20":12,"s:63:16:63:Infinity":13,"b:64:6:64:Infinity:undefined:undefined:undefined:undefined":3,"s:64:6:64:Infinity":14,"b:64:10:64:16:64:16:64:49:64:49:64:60":4,"s:64:60:64:Infinity":15,"s:65:15:65:Infinity":16,"s:66:6:74:Infinity":17,"s:67:20:67:Infinity":18,"b:68:8:71:Infinity:undefined:undefined:undefined:undefined":5,"s:68:8:71:Infinity":19,"s:69:25:69:Infinity":20,"b:70:10:70:Infinity:undefined:undefined:undefined:undefined":6,"s:70:10:70:Infinity":21,"s:70:52:70:Infinity":22,"s:75:6:75:Infinity":23,"s:78:4:78:Infinity":24,"s:81:2:81:Infinity":25,"f:81:13:81:19":2,"s:81:28:81:53":26,"s:82:22:82:Infinity":27,"s:83:2:85:Infinity":28,"s:84:4:84:Infinity":29,"s:84:10:84:46":30,"s:87:2:96:Infinity":31,"s:88:4:88:Infinity":32,"s:89:4:89:Infinity":33,"b:91:4:93:Infinity:undefined:undefined:undefined:undefined":7,"s:91:4:93:Infinity":34,"s:92:6:92:Infinity":35,"s:94:4:94:Infinity":36,"s:95:4:95:Infinity":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/register-globals-bootstrap.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/register-globals-bootstrap.ts","statementMap":{"0":{"start":{"line":29,"column":0},"end":{"line":29,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":0},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:29:0:29:Infinity":0}}}}} \ No newline at end of file +{"numTotalTestSuites":1615,"numPassedTestSuites":1615,"numFailedTestSuites":0,"numPendingTestSuites":0,"numTotalTests":7605,"numPassedTests":7571,"numFailedTests":0,"numPendingTests":34,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1787953656920,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface the safety doc itself exists and is the only allowlisted source of pattern strings","status":"passed","title":"the safety doc itself exists and is the only allowlisted source of pattern strings","duration":4.229150000000004,"failureMessages":[],"location":{"line":255,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-committee-reports.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-committee-reports.md contains no banned bash patterns in fenced code blocks","duration":1.7056140000000255,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-election-cycle.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-election-cycle.md contains no banned bash patterns in fenced code blocks","duration":0.7225730000000112,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-evening-analysis.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-evening-analysis.md contains no banned bash patterns in fenced code blocks","duration":0.6791809999999714,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-interpellations.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-interpellations.md contains no banned bash patterns in fenced code blocks","duration":0.5793239999999855,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-month-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-month-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.5301330000000348,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-monthly-review.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-monthly-review.md contains no banned bash patterns in fenced code blocks","duration":0.5585149999999999,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-motions.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-motions.md contains no banned bash patterns in fenced code blocks","duration":0.49733200000002853,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-propositions.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-propositions.md contains no banned bash patterns in fenced code blocks","duration":0.6525220000000331,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-quarter-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-quarter-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.5025210000000015,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-realtime-monitor.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-realtime-monitor.md contains no banned bash patterns in fenced code blocks","duration":0.567924000000005,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-translate.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-translate.md contains no banned bash patterns in fenced code blocks","duration":0.5972489999999766,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-week-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-week-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.4668350000000032,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-weekly-review.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-weekly-review.md contains no banned bash patterns in fenced code blocks","duration":0.46835699999996905,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/workflows/news-year-ahead.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/workflows/news-year-ahead.md contains no banned bash patterns in fenced code blocks","duration":0.44745799999998326,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/00-base-contract.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/00-base-contract.md contains no banned bash patterns in fenced code blocks","duration":1.2079709999999864,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/02-mcp-access.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/02-mcp-access.md contains no banned bash patterns in fenced code blocks","duration":0.6259320000000343,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/03-data-download.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/03-data-download.md contains no banned bash patterns in fenced code blocks","duration":1.2184520000000134,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/04-analysis-pipeline.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/04-analysis-pipeline.md contains no banned bash patterns in fenced code blocks","duration":0.6528119999999831,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/05-analysis-gate.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/05-analysis-gate.md contains no banned bash patterns in fenced code blocks","duration":2.420812999999953,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/06-article-generation.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/06-article-generation.md contains no banned bash patterns in fenced code blocks","duration":1.0866750000000138,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/07-commit-and-pr.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/07-commit-and-pr.md contains no banned bash patterns in fenced code blocks","duration":1.0482330000000388,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/README.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/README.md contains no banned bash patterns in fenced code blocks","duration":0.7051500000000033,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/prompts/seo-metadata-contract.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/prompts/seo-metadata-contract.md contains no banned bash patterns in fenced code blocks","duration":0.6248499999999808,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/advanced-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/advanced-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5267370000000255,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5621719999999755,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ai-governance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ai-governance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6534440000000359,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/api-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/api-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6589239999999563,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/automated-content-generation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/automated-content-generation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5915479999999889,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/behavioral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/behavioral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9244419999999991,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/business-development/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/business-development/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.869117000000017,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/business-model-canvas/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/business-model-canvas/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7162910000000124,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/c4-architecture-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/c4-architecture-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7536510000000476,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/change-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/change-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.67897099999999,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ci-cd-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ci-cd-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.636743000000024,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/cia-data-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/cia-data-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6531130000000189,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/cis-controls/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/cis-controls/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7748920000000226,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/code-quality-checks/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/code-quality-checks/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6438160000000153,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/code-review-practices/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/code-review-practices/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6387860000000387,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/comparative-politics-reporting/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/comparative-politics-reporting/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8401339999999777,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/compliance-checklist/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/compliance-checklist/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9732319999999959,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/contribution-guidelines/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/contribution-guidelines/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7038080000000377,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/copilot-agent-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/copilot-agent-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6644139999999652,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-pipeline-engineering/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-pipeline-engineering/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7263409999999908,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-protection/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-protection/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8212280000000192,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-science-for-intelligence/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-science-for-intelligence/SKILL.md contains no banned bash patterns in fenced code blocks","duration":4.007734999999968,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/data-visualization-principles/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/data-visualization-principles/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6225650000000087,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/design-system-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/design-system-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5822299999999814,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/documentation-portfolio/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/documentation-portfolio/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6393080000000282,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/documentation-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/documentation-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6205319999999688,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/economic-policy-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/economic-policy-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7019050000000107,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/editorial-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/editorial-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6770970000000034,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/electoral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/electoral-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.7847300000000246,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/european-parliament-api/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/european-parliament-api/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.5985610000000179,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gdpr-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gdpr-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.6492749999999887,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-authentication-credentials/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-authentication-credentials/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8699290000000133,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-containerization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-containerization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8708409999999844,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-continuous-ai-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-continuous-ai-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9371649999999931,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-firewall/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-firewall/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1155799999999658,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-github-actions-integration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-github-actions-integration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1723049999999944,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-logging-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-logging-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9354220000000169,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-mcp-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-mcp-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1180329999999685,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-mcp-gateway/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-mcp-gateway/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.507474000000002,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-safe-outputs/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-safe-outputs/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8753389999999968,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-security-architecture/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-security-architecture/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.218691999999976,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-tools-ecosystem/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-tools-ecosystem/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0211330000000203,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/gh-aw-workflow-authoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/gh-aw-workflow-authoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0575410000000147,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/github-actions-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/github-actions-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8017320000000154,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/github-agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/github-agentic-workflows/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4229050000000143,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/global-government-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/global-government-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.853398000000027,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/hack23-future-architecture-standards/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/hack23-future-architecture-standards/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4127960000000144,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/hack23-isms-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/hack23-isms-compliance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9560299999999984,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/html-accessibility/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/html-accessibility/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9073700000000144,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/incident-response/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/incident-response/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8746380000000045,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/information-security-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/information-security-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.8829840000000218,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/input-validation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/input-validation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.9019490000000019,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/intelligence-analysis-techniques/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/intelligence-analysis-techniques/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1421589999999924,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/investigative-journalism/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/investigative-journalism/SKILL.md contains no banned bash patterns in fenced code blocks","duration":0.969244999999944,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/iso-27001-controls/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/iso-27001-controls/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.0953210000000126,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/issue-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/issue-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2023619999999937,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/language-expertise/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/language-expertise/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.1178330000000187,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/legislative-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/legislative-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":2.563431000000037,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/marketing/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/marketing/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9252749999999423,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-gateway-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-gateway-configuration/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5888349999999036,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-gateway-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-gateway-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2853569999999763,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/mcp-server-development/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/mcp-server-development/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.139242999999965,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/multi-language-localization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/multi-language-localization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.203873999999928,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/myndigheter-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/myndigheter-monitoring/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2088940000001003,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/nist-csf-mapping/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/nist-csf-mapping/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.148800999999935,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/open-source-governance/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/open-source-governance/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.186001000000033,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/osint-methodologies/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/osint-methodologies/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2982110000000375,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/performance-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/performance-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2048269999999093,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/playwright-testing/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/playwright-testing/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2482969999999796,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/political-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/political-data-visualization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.3226359999999886,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/political-science-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/political-science-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.4144679999999425,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/product-management-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/product-management-patterns/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.2724319999999807,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/prospective-news-coverage/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/prospective-news-coverage/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.3396189999999706,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/regulatory-affairs/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/regulatory-affairs/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9861590000000433,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/responsive-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/responsive-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.8174129999999877,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/riksdag-regering-mcp/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/riksdag-regering-mcp/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.996609000000035,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/risk-assessment-frameworks/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/risk-assessment-frameworks/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9838449999999739,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secrets-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secrets-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7709760000000188,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-code-review/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-code-review/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.935944999999947,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-development-lifecycle/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-development-lifecycle/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7451579999999467,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/secure-development-policy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/secure-development-policy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5365880000000516,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/security-by-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/security-by-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5589599999999564,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/security-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/security-documentation/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5178319999999985,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/seo-best-practices/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/seo-best-practices/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5242739999999912,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/seo-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/seo-optimization/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.5541109999999208,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/static-site-security/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/static-site-security/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7893909999999096,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/strategic-communication-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/strategic-communication-analysis/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7121559999999363,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/swedish-political-system/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/swedish-political-system/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.71358900000007,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/testing-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/testing-strategy/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.614663999999948,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/threat-modeling/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/threat-modeling/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7588739999999916,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/ui-ux-design/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/ui-ux-design/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.7814560000000483,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Banned bash patterns are absent from agent-visible prompt surface"],"fullName":"Agentic Workflow Bash & Shell Safety Banned bash patterns are absent from agent-visible prompt surface .github/skills/vulnerability-management/SKILL.md contains no banned bash patterns in fenced code blocks","status":"passed","title":".github/skills/vulnerability-management/SKILL.md contains no banned bash patterns in fenced code blocks","duration":1.9136140000000523,"failureMessages":[],"location":{"line":270,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Allowed eval replacements are documented and self-consistent"],"fullName":"Agentic Workflow Bash & Shell Safety Allowed eval replacements are documented and self-consistent safety doc still names the three allowed eval replacements","status":"passed","title":"safety doc still names the three allowed eval replacements","duration":2.643269999999916,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow Bash & Shell Safety","Allowed eval replacements are documented and self-consistent"],"fullName":"Agentic Workflow Bash & Shell Safety Allowed eval replacements are documented and self-consistent no agent-visible file authorises a fourth eval-replacement shape","status":"passed","title":"no agent-visible file authorises a fourth eval-replacement shape","duration":16.867084999999975,"failureMessages":[],"location":{"line":299,"column":5},"meta":{},"tags":[]}],"startTime":1787953807235,"endTime":1787953807385.8672,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic-workflow-bash-safety.test.ts"},{"assertionResults":[{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-evening-analysis.md should document get_sync_status() call","status":"passed","title":"news-evening-analysis.md should document get_sync_status() call","duration":7.120672000000013,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-evening-analysis.md should warn about stale data","status":"passed","title":"news-evening-analysis.md should warn about stale data","duration":1.7746319999999969,"failureMessages":[],"location":{"line":58,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-realtime-monitor.md should document get_sync_status() call","status":"passed","title":"news-realtime-monitor.md should document get_sync_status() call","duration":2.2326400000000035,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Data Freshness Validation"],"fullName":"Agentic Workflow MCP Query Patterns Data Freshness Validation news-realtime-monitor.md should warn about stale data","status":"passed","title":"news-realtime-monitor.md should warn about stale data","duration":1.4788990000000126,"failureMessages":[],"location":{"line":58,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-evening-analysis.md should document explicit date parameters","status":"passed","title":"news-evening-analysis.md should document explicit date parameters","duration":2.585050000000024,"failureMessages":[],"location":{"line":81,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-evening-analysis.md should NOT rely on implicit \"latest\" patterns","status":"passed","title":"news-evening-analysis.md should NOT rely on implicit \"latest\" patterns","duration":2.472578999999996,"failureMessages":[],"location":{"line":98,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-realtime-monitor.md should document explicit date parameters","status":"passed","title":"news-realtime-monitor.md should document explicit date parameters","duration":2.273285000000044,"failureMessages":[],"location":{"line":81,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Explicit Date Filtering"],"fullName":"Agentic Workflow MCP Query Patterns Explicit Date Filtering news-realtime-monitor.md should NOT rely on implicit \"latest\" patterns","status":"passed","title":"news-realtime-monitor.md should NOT rely on implicit \"latest\" patterns","duration":1.9193729999999505,"failureMessages":[],"location":{"line":98,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation news-evening-analysis.md should document post-query filtering","status":"passed","title":"news-evening-analysis.md should document post-query filtering","duration":2.043274999999994,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation workflows should annotate tools with date support","status":"passed","title":"workflows should annotate tools with date support","duration":2.008100000000013,"failureMessages":[],"location":{"line":164,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Post-Query Date Filtering Documentation"],"fullName":"Agentic Workflow MCP Query Patterns Post-Query Date Filtering Documentation news-evening-analysis.md should document post-query fromDate filtering guidance","status":"passed","title":"news-evening-analysis.md should document post-query fromDate filtering guidance","duration":1.8616549999999847,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Cross-Referencing Strategy"],"fullName":"Agentic Workflow MCP Query Patterns Cross-Referencing Strategy news-evening-analysis.md should document cross-referencing of data sources","status":"passed","title":"news-evening-analysis.md should document cross-referencing of data sources","duration":3.5262420000000247,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-evening-analysis.md should document error scenarios","status":"passed","title":"news-evening-analysis.md should document error scenarios","duration":1.2753979999999956,"failureMessages":[],"location":{"line":219,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-evening-analysis.md should document stale/partial data handling","status":"passed","title":"news-evening-analysis.md should document stale/partial data handling","duration":1.6391489999999749,"failureMessages":[],"location":{"line":241,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-realtime-monitor.md should document error scenarios","status":"passed","title":"news-realtime-monitor.md should document error scenarios","duration":1.134333999999967,"failureMessages":[],"location":{"line":219,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Error Handling"],"fullName":"Agentic Workflow MCP Query Patterns Error Handling news-realtime-monitor.md should document stale/partial data handling","status":"passed","title":"news-realtime-monitor.md should document stale/partial data handling","duration":1.5181820000000243,"failureMessages":[],"location":{"line":241,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-evening-analysis.md should document the MCP surface inline or via prompt modules","status":"passed","title":"news-evening-analysis.md should document the MCP surface inline or via prompt modules","duration":1.2584959999999796,"failureMessages":[],"location":{"line":263,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-evening-analysis.md should emphasize get_sync_status() first","status":"passed","title":"news-evening-analysis.md should emphasize get_sync_status() first","duration":1.1235940000000255,"failureMessages":[],"location":{"line":294,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-realtime-monitor.md should document the MCP surface inline or via prompt modules","status":"passed","title":"news-realtime-monitor.md should document the MCP surface inline or via prompt modules","duration":1.1142059999999674,"failureMessages":[],"location":{"line":263,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","MCP Tool Documentation Quality"],"fullName":"Agentic Workflow MCP Query Patterns MCP Tool Documentation Quality news-realtime-monitor.md should emphasize get_sync_status() first","status":"passed","title":"news-realtime-monitor.md should emphasize get_sync_status() first","duration":1.4319710000000327,"failureMessages":[],"location":{"line":294,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices workflows should have date calculation examples","status":"passed","title":"workflows should have date calculation examples","duration":1.6785320000000183,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices workflows should include dynamic riksmöte calculation instructions","status":"passed","title":"workflows should include dynamic riksmöte calculation instructions","duration":1.6541070000000104,"failureMessages":[],"location":{"line":328,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Date Filtering Best Practices"],"fullName":"Agentic Workflow MCP Query Patterns Date Filtering Best Practices all news workflows should not hardcode the parliamentary session year","status":"passed","title":"all news workflows should not hardcode the parliamentary session year","duration":9.407573000000014,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Workflow Compilation"],"fullName":"Agentic Workflow MCP Query Patterns Workflow Compilation news-evening-analysis.md should compile without errors","status":"passed","title":"news-evening-analysis.md should compile without errors","duration":2.018429000000026,"failureMessages":[],"location":{"line":360,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Workflow Compilation"],"fullName":"Agentic Workflow MCP Query Patterns Workflow Compilation news-realtime-monitor.md should compile without errors","status":"passed","title":"news-realtime-monitor.md should compile without errors","duration":3.7051969999999983,"failureMessages":[],"location":{"line":360,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Regression Prevention"],"fullName":"Agentic Workflow MCP Query Patterns Regression Prevention evening analysis should maintain enhanced query patterns","status":"passed","title":"evening analysis should maintain enhanced query patterns","duration":1.197170999999969,"failureMessages":[],"location":{"line":386,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Agentic Workflow MCP Query Patterns","Regression Prevention"],"fullName":"Agentic Workflow MCP Query Patterns Regression Prevention workflows should not use ambiguous \"latest\" language","status":"passed","title":"workflows should not use ambiguous \"latest\" language","duration":1.4189360000000306,"failureMessages":[],"location":{"line":408,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Tool Date Parameter Support Matrix"],"fullName":"MCP Tool Date Parameter Support Matrix effective prompt for evening analysis should scope MCP queries by date","status":"passed","title":"effective prompt for evening analysis should scope MCP queries by date","duration":1.0432839999999715,"failureMessages":[],"location":{"line":463,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-committee-reports.md should import the MCP access prompt module","status":"passed","title":"news-committee-reports.md should import the MCP access prompt module","duration":0.5726119999999923,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-committee-reports.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-committee-reports.md should not embed inline python3 JSON-parsing scripts","duration":1.309020999999973,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-evening-analysis.md should import the MCP access prompt module","status":"passed","title":"news-evening-analysis.md should import the MCP access prompt module","duration":0.678910999999971,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-evening-analysis.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-evening-analysis.md should not embed inline python3 JSON-parsing scripts","duration":0.9703460000000064,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-interpellations.md should import the MCP access prompt module","status":"passed","title":"news-interpellations.md should import the MCP access prompt module","duration":0.47906699999998636,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-interpellations.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-interpellations.md should not embed inline python3 JSON-parsing scripts","duration":0.556822000000011,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-month-ahead.md should import the MCP access prompt module","status":"passed","title":"news-month-ahead.md should import the MCP access prompt module","duration":0.47168299999998453,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-month-ahead.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-month-ahead.md should not embed inline python3 JSON-parsing scripts","duration":0.5634660000000054,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-monthly-review.md should import the MCP access prompt module","status":"passed","title":"news-monthly-review.md should import the MCP access prompt module","duration":0.4721139999999764,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-monthly-review.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-monthly-review.md should not embed inline python3 JSON-parsing scripts","duration":0.6159139999999752,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-motions.md should import the MCP access prompt module","status":"passed","title":"news-motions.md should import the MCP access prompt module","duration":0.4916210000000092,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-motions.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-motions.md should not embed inline python3 JSON-parsing scripts","duration":0.5864879999999744,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-propositions.md should import the MCP access prompt module","status":"passed","title":"news-propositions.md should import the MCP access prompt module","duration":0.493344000000036,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-propositions.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-propositions.md should not embed inline python3 JSON-parsing scripts","duration":0.6698440000000119,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-realtime-monitor.md should import the MCP access prompt module","status":"passed","title":"news-realtime-monitor.md should import the MCP access prompt module","duration":0.5894729999999981,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-realtime-monitor.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-realtime-monitor.md should not embed inline python3 JSON-parsing scripts","duration":0.5937910000000102,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-week-ahead.md should import the MCP access prompt module","status":"passed","title":"news-week-ahead.md should import the MCP access prompt module","duration":0.5471949999999879,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-week-ahead.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-week-ahead.md should not embed inline python3 JSON-parsing scripts","duration":0.6167639999999892,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-weekly-review.md should import the MCP access prompt module","status":"passed","title":"news-weekly-review.md should import the MCP access prompt module","duration":0.675423999999964,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards news-weekly-review.md should not embed inline python3 JSON-parsing scripts","status":"passed","title":"news-weekly-review.md should not embed inline python3 JSON-parsing scripts","duration":0.6459300000000212,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCP Prompt-Module Anti-Pattern Guards"],"fullName":"MCP Prompt-Module Anti-Pattern Guards prompts/02-mcp-access.md should define the canonical MCP access contract","status":"passed","title":"prompts/02-mcp-access.md should define the canonical MCP access contract","duration":0.7086570000000165,"failureMessages":[],"location":{"line":548,"column":3},"meta":{},"tags":[]}],"startTime":1787953667246,"endTime":1787953667324.7087,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic-workflow-mcp-queries.test.ts"},{"assertionResults":[{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation renders a localised navigation table with one row per available artifact + audit appendix","status":"passed","title":"renders a localised navigation table with one row per available artifact + audit appendix","duration":6.4800840000000335,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation localises the heading per language (sv)","status":"passed","title":"localises the heading per language (sv)","duration":0.6548860000000332,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation omits per-document row when no documents/*-analysis.md artifacts present","status":"passed","title":"omits per-document row when no documents/*-analysis.md artifacts present","duration":0.5446100000000342,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation includes per-document row when documents/*-analysis.md present","status":"passed","title":"includes per-document row when documents/*-analysis.md present","duration":0.6226659999999811,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation always includes the audit-appendix row even when no curated artifacts matched","status":"passed","title":"always includes the audit-appendix row even when no curated artifacts matched","duration":0.5295810000000074,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation points the audit row at political-classification when that is the available audit artifact","status":"passed","title":"points the audit row at political-classification when that is the available audit artifact","duration":0.7306180000000495,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation renders rows for ALL analysis artifacts, not just the curated lenses","status":"passed","title":"renders rows for ALL analysis artifacts, not just the curated lenses","duration":0.9459410000000616,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation uses the localised colIcon header for the icon column (not hard-coded English \"Icon\")","status":"passed","title":"uses the localised colIcon header for the icon column (not hard-coded English \"Icon\")","duration":0.7366389999999683,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation skips JSON artifacts and unknown extensions (no broken in-page anchors)","status":"passed","title":"skips JSON artifacts and unknown extensions (no broken in-page anchors)","duration":0.6240179999999782,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation de-duplicates filename-variant alias groups (election-2026-analysis vs election-cycle-analysis)","status":"passed","title":"de-duplicates filename-variant alias groups (election-2026-analysis vs election-cycle-analysis)","duration":0.7651019999999562,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderReaderNavigation"],"fullName":"article-aside — renderReaderNavigation skips README.md and article*.md aggregator outputs","status":"passed","title":"skips README.md and article*.md aggregator outputs","duration":0.6531739999999218,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderAnalysisArtifactsReference"],"fullName":"article-aside — renderAnalysisArtifactsReference returns the empty string when no artifacts supplied","status":"passed","title":"returns the empty string when no artifacts supplied","duration":0.4747989999999618,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderAnalysisArtifactsReference"],"fullName":"article-aside — renderAnalysisArtifactsReference renders one source card per artifact with icon, i18n title, and GitHub blob url","status":"passed","title":"renders one source card per artifact with icon, i18n title, and GitHub blob url","duration":0.7371799999999666,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderMethodsReference"],"fullName":"article-aside — renderMethodsReference renders the four methodology cards plus a CTA back to political-intelligence","status":"passed","title":"renders the four methodology cards plus a CTA back to political-intelligence","duration":0.6880690000000413,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-aside — renderMethodsReference"],"fullName":"article-aside — renderMethodsReference points the CTA to the language-specific catalogue page (sv)","status":"passed","title":"points the CTA to the language-specific catalogue page (sv)","duration":0.40649100000007365,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders rm-article-sources strictly BEFORE rm-methods-reference","status":"passed","title":"renders rm-article-sources strictly BEFORE rm-methods-reference","duration":49.441985000000045,"failureMessages":[],"location":{"line":268,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders the navigation table BEFORE the analysis-artifacts reference","status":"passed","title":"renders the navigation table BEFORE the analysis-artifacts reference","duration":5.55018199999995,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article — analysis-artifacts → methods ordering at the article foot"],"fullName":"article — analysis-artifacts → methods ordering at the article foot renders the methods reference for all 14 languages","status":"passed","title":"renders the methods reference for all 14 languages","duration":44.41408100000001,"failureMessages":[],"location":{"line":298,"column":3},"meta":{},"tags":[]}],"startTime":1787953793416,"endTime":1787953793531.414,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-aside.test.ts"},{"assertionResults":[{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections removes every embedded carrier section while keeping analytical sections","status":"passed","title":"removes every embedded carrier section while keeping analytical sections","duration":4.398975999999948,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections collapses the blank-line gap left by removed carriers and ends with a single newline","status":"passed","title":"collapses the blank-line gap left by removed carriers and ends with a single newline","duration":0.7116829999999936,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections is a no-op for a body with no carrier sections","status":"passed","title":"is a no-op for a body with no carrier sections","duration":0.7009620000000041,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections strips a stray `## Executive Brief En` carrier (executive-brief_en.md) so it never leaks into the TOC","status":"passed","title":"strips a stray `## Executive Brief En` carrier (executive-brief_en.md) so it never leaks into the TOC","duration":0.555940000000021,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripEmbeddedLocalizedBriefSections"],"fullName":"stripEmbeddedLocalizedBriefSections preserves the legacy unsuffixed `## Executive Brief` lead heading (no language suffix)","status":"passed","title":"preserves the legacy unsuffixed `## Executive Brief` lead heading (no language suffix)","duration":0.46960999999998876,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead English: strips carriers but keeps the canonical English lead verbatim","status":"passed","title":"English: strips carriers but keeps the canonical English lead verbatim","duration":0.549018999999987,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead English: also strips a stray `## Executive Brief En` carrier while keeping the canonical lead","status":"passed","title":"English: also strips a stray `## Executive Brief En` carrier while keeping the canonical lead","duration":0.5395300000000134,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English with a brief: swaps the lead body to localized prose under the stable H2","status":"passed","title":"non-English with a brief: swaps the lead body to localized prose under the stable H2","duration":14.320760000000007,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English brief: cleaning strips front-matter and the first H1, demotes ## to ###","status":"passed","title":"non-English brief: cleaning strips front-matter and the first H1, demotes ## to ###","duration":0.9329270000000065,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English brief: repoints the lead provenance comment at executive-brief_<lang>.md","status":"passed","title":"non-English brief: repoints the lead provenance comment at executive-brief_<lang>.md","duration":0.6263529999999946,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English without a brief: keeps the English lead (localized-if-exists, English-otherwise)","status":"passed","title":"non-English without a brief: keeps the English lead (localized-if-exists, English-otherwise)","duration":0.4694390000000226,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead non-English with an empty/whitespace brief: falls back to the English lead","status":"passed","title":"non-English with an empty/whitespace brief: falls back to the English lead","duration":0.36242899999996325,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead does not inject English normalize-terminology glosses into localized prose","status":"passed","title":"does not inject English normalize-terminology glosses into localized prose","duration":0.5103659999999763,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead targets the first H2 generically (legacy `## Executive Brief` lead heading)","status":"passed","title":"targets the first H2 generically (legacy `## Executive Brief` lead heading)","duration":0.5483969999999658,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizeExecutiveBriefLead"],"fullName":"localizeExecutiveBriefLead handles a lead section that is the only H2 (no trailing analytical section)","status":"passed","title":"handles a lead section that is the only H2 (no trailing analytical section)","duration":0.5438490000000229,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]}],"startTime":1787953826389,"endTime":1787953826416.544,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-brief-lead.test.ts"},{"assertionResults":[{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata returns the raw front-matter values verbatim","status":"passed","title":"returns the raw front-matter values verbatim","duration":11.22403300000002,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata parses the front-matter date into YYYY-MM-DD","status":"passed","title":"parses the front-matter date into YYYY-MM-DD","duration":0.861233000000027,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata infers the article type from the canonical path (committee-reports)","status":"passed","title":"infers the article type from the canonical path (committee-reports)","duration":0.8138739999999984,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata produces a branded <title> with brand suffix and NO date prefix","status":"passed","title":"produces a branded <title> with brand suffix and NO date prefix","duration":1.1119619999999486,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata forwards keywords / description into the buildArticleSeoMetadata output","status":"passed","title":"forwards keywords / description into the buildArticleSeoMetadata output","duration":0.7065230000000042,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata falls back to \"today\" when the front-matter date is missing","status":"passed","title":"falls back to \"today\" when the front-matter date is missing","duration":1.021532000000036,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata"],"fullName":"computeArticleHeadMetadata exposes articleSection matching the value buildChrome passes to article:section","status":"passed","title":"exposes articleSection matching the value buildChrome passes to article:section","duration":0.6365509999999972,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) accepts an ISO Date instance","status":"passed","title":"accepts an ISO Date instance","duration":0.5125499999999761,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) accepts a YYYY-MM-DD string","status":"passed","title":"accepts a YYYY-MM-DD string","duration":0.48171100000001843,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate (re-exported)"],"fullName":"parseFrontMatterDate (re-exported) falls back to the injected \"now\" when the input is missing","status":"passed","title":"falls back to the injected \"now\" when the input is missing","duration":0.4928530000000251,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["inferArticleType (re-exported)"],"fullName":"inferArticleType (re-exported) recognises realtime-pulse canonical paths","status":"passed","title":"recognises realtime-pulse canonical paths","duration":0.744213000000002,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["inferArticleType (re-exported)"],"fullName":"inferArticleType (re-exported) falls back to political-intelligence for unknown paths","status":"passed","title":"falls back to political-intelligence for unknown paths","duration":0.47831500000000915,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget audit regression: max=88 EN title no longer overshoots the 70-char hardMax","status":"passed","title":"audit regression: max=88 EN title no longer overshoots the 70-char hardMax","duration":2.779092999999989,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget short H1 ships with the brand suffix and NO date prefix","status":"passed","title":"short H1 ships with the brand suffix and NO date prefix","duration":1.0189579999999978,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=en never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=en never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8367269999999962,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=sv never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=sv never overshoots titleWindowForLanguage(lang).hardMax","duration":0.9817980000000261,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=da never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=da never overshoots titleWindowForLanguage(lang).hardMax","duration":1.0872549999999706,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=no never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=no never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8238129999999728,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=fi never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=fi never overshoots titleWindowForLanguage(lang).hardMax","duration":0.6863250000000107,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=de never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=de never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7179639999999949,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=fr never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=fr never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8237219999999752,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=es never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=es never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7528599999999983,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=nl never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=nl never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7558449999999652,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ar never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ar never overshoots titleWindowForLanguage(lang).hardMax","duration":1.121690000000001,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=he never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=he never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7201780000000326,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ja never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ja never overshoots titleWindowForLanguage(lang).hardMax","duration":0.8372669999999971,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=ko never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=ko never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7334829999999783,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget over-budget H1 in lang=zh never overshoots titleWindowForLanguage(lang).hardMax","status":"passed","title":"over-budget H1 in lang=zh never overshoots titleWindowForLanguage(lang).hardMax","duration":0.7618969999999763,"failureMessages":[],"location":{"line":217,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["computeArticleHeadMetadata — branded <title> respects per-language SERP budget"],"fullName":"computeArticleHeadMetadata — branded <title> respects per-language SERP budget truncated branded title from the news/index card regression no longer reads \"…Five… — Riksdagsmonitor\"","status":"passed","title":"truncated branded title from the news/index card regression no longer reads \"…Five… — Riksdagsmonitor\"","duration":0.8229709999999386,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]}],"startTime":1787953825362,"endTime":1787953825398.823,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-head-metadata.test.ts"},{"assertionResults":[{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish returns English markdown unchanged when lang === \"en\"","status":"passed","title":"returns English markdown unchanged when lang === \"en\"","duration":5.007345999999984,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish overlays localized title/language but keeps English executive-brief description","status":"passed","title":"overlays localized title/language but keeps English executive-brief description","duration":8.358641000000034,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish keeps canonical-identity front-matter fields from the English source","status":"passed","title":"keeps canonical-identity front-matter fields from the English source","duration":1.8800800000000208,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish places the localized body BEFORE the English body, separated by the boundary heading","status":"passed","title":"places the localized body BEFORE the English body, separated by the boundary heading","duration":1.1795590000000402,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish preserves every English body section in the merged output","status":"passed","title":"preserves every English body section in the merged output","duration":1.1544920000000047,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish preserves the localized body content verbatim","status":"passed","title":"preserves the localized body content verbatim","duration":0.7631590000000301,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish emits the localized aside note on the boundary line so readers know why English follows","status":"passed","title":"emits the localized aside note on the boundary line so readers know why English follows","duration":0.8689570000000231,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish falls back to the English body when the localized file has no body content (FM only)","status":"passed","title":"falls back to the English body when the localized file has no body content (FM only)","duration":1.5063499999999976,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish forces language: <lang> even when the localized file forgot to set it","status":"passed","title":"forces language: <lang> even when the localized file forgot to set it","duration":1.3221859999999879,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores empty-string localized title/description so English fallback wins","status":"passed","title":"ignores empty-string localized title/description so English fallback wins","duration":1.428754999999967,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores localizedBriefMarkdown — does NOT rewrite title/description from the brief","status":"passed","title":"ignores localizedBriefMarkdown — does NOT rewrite title/description from the brief","duration":0.7737989999999968,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish ignores localizedBriefMarkdown even when the localized article is missing","status":"passed","title":"ignores localizedBriefMarkdown even when the localized article is missing","duration":1.1150779999999827,"failureMessages":[],"location":{"line":292,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish"],"fullName":"mergeLocalizedWithEnglish falls back to English title/description when both localized inputs are missing","status":"passed","title":"falls back to English title/description when both localized inputs are missing","duration":0.6857840000000124,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"sv\"","status":"passed","title":"emits a non-empty H2 + aside note for \"sv\"","duration":0.6601059999999848,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"da\"","status":"passed","title":"emits a non-empty H2 + aside note for \"da\"","duration":0.5625739999999837,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"no\"","status":"passed","title":"emits a non-empty H2 + aside note for \"no\"","duration":0.5231090000000336,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"fi\"","status":"passed","title":"emits a non-empty H2 + aside note for \"fi\"","duration":0.5486169999999788,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"de\"","status":"passed","title":"emits a non-empty H2 + aside note for \"de\"","duration":0.48360499999995454,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"fr\"","status":"passed","title":"emits a non-empty H2 + aside note for \"fr\"","duration":0.5049559999999929,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"es\"","status":"passed","title":"emits a non-empty H2 + aside note for \"es\"","duration":0.5158959999999979,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"nl\"","status":"passed","title":"emits a non-empty H2 + aside note for \"nl\"","duration":0.5177290000000312,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ar\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ar\"","duration":0.5282589999999914,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"he\"","status":"passed","title":"emits a non-empty H2 + aside note for \"he\"","duration":0.5093339999999671,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ja\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ja\"","duration":0.49261200000000827,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"ko\"","status":"passed","title":"emits a non-empty H2 + aside note for \"ko\"","duration":0.5261449999999854,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]},{"ancestorTitles":["buildEnglishCoverageBoundary"],"fullName":"buildEnglishCoverageBoundary emits a non-empty H2 + aside note for \"zh\"","status":"passed","title":"emits a non-empty H2 + aside note for \"zh\"","duration":0.6841309999999794,"failureMessages":[],"location":{"line":339,"column":47},"meta":{},"tags":[]}],"startTime":1787953795304,"endTime":1787953795337.684,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-merge.test.ts"},{"assertionResults":[{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult success branch has ok=true and value","status":"passed","title":"PipelineResult success branch has ok=true and value","duration":4.335527999999954,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult failure branch has ok=false and error","status":"passed","title":"PipelineResult failure branch has ok=false and error","duration":0.9173779999999851,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult success branch supports optional warnings","status":"passed","title":"PipelineResult success branch supports optional warnings","duration":1.5384599999999864,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts PipelineResult failure branch supports optional warnings","status":"passed","title":"PipelineResult failure branch supports optional warnings","duration":0.6308909999999059,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts ValidationDiagnostic supports all severity levels","status":"passed","title":"ValidationDiagnostic supports all severity levels","duration":0.7718449999999848,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["pipeline interfaces — type contracts"],"fullName":"pipeline interfaces — type contracts ArticleSection ties markdown to its source file","status":"passed","title":"ArticleSection ties markdown to its source file","duration":0.7817239999999401,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path produces a successful result with minimal analysis folder","status":"passed","title":"produces a successful result with minimal analysis folder","duration":34.01702999999998,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path extracts title from the executive-brief H1","status":"passed","title":"extracts title from the executive-brief H1","duration":3.1966449999999895,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path extracts description from the BLUF paragraph","status":"passed","title":"extracts description from the BLUF paragraph","duration":1.9959370000000263,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path includes YAML front-matter with required fields","status":"passed","title":"includes YAML front-matter with required fields","duration":2.4262730000000374,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path config overrides are wired into the front-matter","status":"passed","title":"config overrides are wired into the front-matter","duration":2.604155999999989,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — happy path"],"fullName":"runArticlePipeline — happy path aggregates multiple artifacts in canonical order","status":"passed","title":"aggregates multiple artifacts in canonical order","duration":20.333439999999996,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases returns error when subfolder does not exist","status":"passed","title":"returns error when subfolder does not exist","duration":0.7383929999999737,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases returns error when executive-brief.md is missing","status":"passed","title":"returns error when executive-brief.md is missing","duration":0.8017610000000559,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases handles empty executive-brief.md gracefully","status":"passed","title":"handles empty executive-brief.md gracefully","duration":2.091316000000006,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — error cases"],"fullName":"runArticlePipeline — error cases handles executive-brief.md with only YAML front-matter","status":"passed","title":"handles executive-brief.md with only YAML front-matter","duration":6.066368000000011,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases excludes README.md from aggregation","status":"passed","title":"excludes README.md from aggregation","duration":1.9094450000000052,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases excludes article.md and article.<lang>.md from aggregation","status":"passed","title":"excludes article.md and article.<lang>.md from aggregation","duration":1.9630450000000792,"failureMessages":[],"location":{"line":324,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases handles artifacts with malformed YAML front-matter","status":"passed","title":"handles artifacts with malformed YAML front-matter","duration":1.278925000000072,"failureMessages":[],"location":{"line":339,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runArticlePipeline — edge cases"],"fullName":"runArticlePipeline — edge cases handles supplementary artifacts not in AGGREGATION_ORDER","status":"passed","title":"handles supplementary artifacts not in AGGREGATION_ORDER","duration":2.05973599999993,"failureMessages":[],"location":{"line":366,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) demotes ## to ###","status":"passed","title":"demotes ## to ###","duration":0.7142979999999852,"failureMessages":[],"location":{"line":387,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) demotes ### to ####","status":"passed","title":"demotes ### to ####","duration":0.6263030000000072,"failureMessages":[],"location":{"line":391,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) caps at ###### (does not produce #######)","status":"passed","title":"caps at ###### (does not produce #######)","duration":0.595956000000001,"failureMessages":[],"location":{"line":395,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) leaves H1 untouched (already stripped upstream)","status":"passed","title":"leaves H1 untouched (already stripped upstream)","duration":0.6196199999999408,"failureMessages":[],"location":{"line":399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) preserves headings inside fenced code blocks","status":"passed","title":"preserves headings inside fenced code blocks","duration":0.6019370000000208,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) preserves headings inside tilde-fenced code blocks","status":"passed","title":"preserves headings inside tilde-fenced code blocks","duration":0.549398999999994,"failureMessages":[],"location":{"line":408,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles multiple headings at different levels","status":"passed","title":"handles multiple headings at different levels","duration":0.6114140000000816,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles empty string","status":"passed","title":"handles empty string","duration":0.574226000000067,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) handles text without headings","status":"passed","title":"handles text without headings","duration":0.6797819999999319,"failureMessages":[],"location":{"line":423,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["heading-demotion (extracted module)"],"fullName":"heading-demotion (extracted module) does not demote hash characters in non-heading context","status":"passed","title":"does not demote hash characters in non-heading context","duration":0.6319229999999152,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) rewrites relative .md links to GitHub blob URLs","status":"passed","title":"rewrites relative .md links to GitHub blob URLs","duration":0.7033969999999954,"failureMessages":[],"location":{"line":437,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves absolute https:// links","status":"passed","title":"preserves absolute https:// links","duration":0.7323010000000068,"failureMessages":[],"location":{"line":443,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves fragment-only links","status":"passed","title":"preserves fragment-only links","duration":0.9518820000000687,"failureMessages":[],"location":{"line":448,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) preserves mailto: links","status":"passed","title":"preserves mailto: links","duration":0.5668809999999667,"failureMessages":[],"location":{"line":453,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles relative links with anchors","status":"passed","title":"handles relative links with anchors","duration":0.5637749999999642,"failureMessages":[],"location":{"line":458,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles relative paths with ../","status":"passed","title":"handles relative paths with ../","duration":0.592640000000074,"failureMessages":[],"location":{"line":464,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles empty body","status":"passed","title":"handles empty body","duration":0.5960159999999632,"failureMessages":[],"location":{"line":470,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["link-rewriting (extracted module)"],"fullName":"link-rewriting (extracted module) handles multiple links in the same line","status":"passed","title":"handles multiple links in the same line","duration":0.6040219999999863,"failureMessages":[],"location":{"line":474,"column":3},"meta":{},"tags":[]}],"startTime":1787953735539,"endTime":1787953735645.604,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-pipeline.test.ts"},{"assertionResults":[{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps HIGH confidence in a green chip","status":"passed","title":"wraps HIGH confidence in a green chip","duration":4.095128000000045,"failureMessages":[],"location":{"line":17,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps MEDIUM confidence in an amber chip","status":"passed","title":"wraps MEDIUM confidence in an amber chip","duration":0.6299089999999978,"failureMessages":[],"location":{"line":24,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips wraps LOW confidence in a red chip","status":"passed","title":"wraps LOW confidence in a red chip","duration":0.48821399999997084,"failureMessages":[],"location":{"line":30,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips handles multiple confidence levels in same string","status":"passed","title":"handles multiple confidence levels in same string","duration":0.5228089999999952,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.5215870000000109,"failureMessages":[],"location":{"line":43,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not modify heading id attributes containing high/medium/low","status":"passed","title":"does not modify heading id attributes containing high/medium/low","duration":0.5889129999999909,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not modify href attributes containing high/medium/low","status":"passed","title":"does not modify href attributes containing high/medium/low","duration":0.49079000000000406,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformConfidenceChips"],"fullName":"Article Scannability Transforms transformConfidenceChips does not inject spans into class or data attributes","status":"passed","title":"does not inject spans into class or data attributes","duration":0.5123199999999883,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges wraps Admiralty codes in styled badges with tooltips","status":"passed","title":"wraps Admiralty codes in styled badges with tooltips","duration":0.8726390000000492,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges handles multiple codes","status":"passed","title":"handles multiple codes","duration":0.6911049999999932,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges does not match non-Admiralty patterns","status":"passed","title":"does not match non-Admiralty patterns","duration":0.7104800000000182,"failureMessages":[],"location":{"line":91,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformAdmiraltyBadges"],"fullName":"Article Scannability Transforms transformAdmiraltyBadges does not modify attributes containing Admiralty-like patterns","status":"passed","title":"does not modify attributes containing Admiralty-like patterns","duration":0.5417640000000006,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+7d as urgent","status":"passed","title":"wraps T+7d as urgent","duration":0.6570999999999572,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+30d as near","status":"passed","title":"wraps T+30d as near","duration":0.46278599999999415,"failureMessages":[],"location":{"line":112,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators wraps T+90d as horizon","status":"passed","title":"wraps T+90d as horizon","duration":0.4607029999999668,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators preserves original text inside span","status":"passed","title":"preserves original text inside span","duration":0.44260799999995015,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformTimelineIndicators"],"fullName":"Article Scannability Transforms transformTimelineIndicators does not modify attributes containing timeline-like patterns","status":"passed","title":"does not modify attributes containing timeline-like patterns","duration":0.47020099999997456,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure wraps Document Analysis H2 in details element","status":"passed","title":"wraps Document Analysis H2 in details element","duration":1.4615359999999669,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure wraps Intelligence Notes in details element","status":"passed","title":"wraps Intelligence Notes in details element","duration":0.5404819999999972,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure does not wrap non-matching headings","status":"passed","title":"does not wrap non-matching headings","duration":0.5762389999999868,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure escapes residual markup in the disclosure summary","status":"passed","title":"escapes residual markup in the disclosure summary","duration":0.7264299999999935,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure strips overlapping tags without reconstituting markup in the summary","status":"passed","title":"strips overlapping tags without reconstituting markup in the summary","duration":0.5682140000000118,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","transformProgressiveDisclosure"],"fullName":"Article Scannability Transforms transformProgressiveDisclosure handles Swedish headings","status":"passed","title":"handles Swedish headings","duration":0.5226289999999949,"failureMessages":[],"location":{"line":182,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc generates TOC from H2 headings","status":"passed","title":"generates TOC from H2 headings","duration":1.4731479999999806,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc wraps the TOC in a collapsible sidebar disclosure","status":"passed","title":"wraps the TOC in a collapsible sidebar disclosure","duration":0.5855660000000285,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc assigns canonical icons and reading-depth layers from the section id","status":"passed","title":"assigns canonical icons and reading-depth layers from the section id","duration":0.7190160000000105,"failureMessages":[],"location":{"line":210,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc falls back to a default icon for unknown dynamic sections","status":"passed","title":"falls back to a default icon for unknown dynamic sections","duration":0.6223449999999957,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc returns empty string for single-section articles","status":"passed","title":"returns empty string for single-section articles","duration":0.5838229999999953,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc uses Swedish label for sv lang","status":"passed","title":"uses Swedish label for sv lang","duration":0.6539539999999988,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc localizes the layer badge label for non-English languages","status":"passed","title":"localizes the layer badge label for non-English languages","duration":0.6148110000000315,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc escapes residual markup in TOC link text","status":"passed","title":"escapes residual markup in TOC link text","duration":0.7900500000000079,"failureMessages":[],"location":{"line":253,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc localizes TOC entry text by language-stable section id for non-English","status":"passed","title":"localizes TOC entry text by language-stable section id for non-English","duration":0.9432360000000131,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc keeps English TOC entry text byte-identical to the body heading","status":"passed","title":"keeps English TOC entry text byte-identical to the body heading","duration":0.6480829999999855,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc reuses the reader-guide per-document label for the per-document section","status":"passed","title":"reuses the reader-guide per-document label for the per-document section","duration":0.6497460000000501,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","generateArticleToc"],"fullName":"Article Scannability Transforms generateArticleToc falls back to the heading text for sections without a curated localisation","status":"passed","title":"falls back to the heading text for sections without a curated localisation","duration":0.5895739999999705,"failureMessages":[],"location":{"line":292,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter renders English methodology footer","status":"passed","title":"renders English methodology footer","duration":0.7690299999999866,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter renders Swedish methodology footer","status":"passed","title":"renders Swedish methodology footer","duration":0.5565819999999917,"failureMessages":[],"location":{"line":310,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","renderMethodologyFooter"],"fullName":"Article Scannability Transforms renderMethodologyFooter falls back to English for unsupported languages","status":"passed","title":"falls back to English for unsupported languages","duration":0.5539880000000039,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Article Scannability Transforms","applyScannabilityTransforms"],"fullName":"Article Scannability Transforms applyScannabilityTransforms applies inline transforms and returns TOC + footer (no progressive disclosure)","status":"passed","title":"applies inline transforms and returns TOC + footer (no progressive disclosure)","duration":0.9673710000000142,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]}],"startTime":1787953788443,"endTime":1787953788472.9673,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-scannability.test.ts"},{"assertionResults":[{"ancestorTitles":["buildArticleKeywords — EN path (regression baseline)"],"fullName":"buildArticleKeywords — EN path (regression baseline) keeps the original EN ordering and includes the EN core keyword set","status":"passed","title":"keeps the original EN ordering and includes the EN core keyword set","duration":4.888503999999955,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English frontmatter `keywords:` seed","status":"passed","title":"does NOT include the English frontmatter `keywords:` seed","duration":1.0770770000000311,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English Language-Meta `name`","status":"passed","title":"does NOT include the English Language-Meta `name`","duration":0.6129280000000108,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include the English article-type ID hyphen-slug","status":"passed","title":"does NOT include the English article-type ID hyphen-slug","duration":0.5645470000000046,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT include English canonical-path slug parts","status":"passed","title":"does NOT include English canonical-path slug parts","duration":0.6287680000000364,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks DOES include the German core keyword set","status":"passed","title":"DOES include the German core keyword set","duration":0.7993170000000305,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT inject any English `update` word in the publication keyword","status":"passed","title":"does NOT inject any English `update` word in the publication keyword","duration":0.6393279999999777,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks includes the German government keyword (institutional floor)","status":"passed","title":"includes the German government keyword (institutional floor)","duration":0.5175889999999868,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks surfaces the localized article-type label","status":"passed","title":"surfaces the localized article-type label","duration":0.6643640000000346,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — non-EN path drops EN seed leaks"],"fullName":"buildArticleKeywords — non-EN path drops EN seed leaks does NOT leak EN title tokens (Enshrines / Protection / Abortion) under DE","status":"passed","title":"does NOT leak EN title tokens (Enshrines / Protection / Abortion) under DE","duration":0.5261849999999981,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — Arabic (RTL) localization"],"fullName":"buildArticleKeywords — Arabic (RTL) localization uses native Arabic core keywords and no English leakage","status":"passed","title":"uses native Arabic core keywords and no English leakage","duration":1.3207729999999742,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — Japanese (CJK) localization"],"fullName":"buildArticleKeywords — Japanese (CJK) localization uses native Japanese core keywords and no English leakage","status":"passed","title":"uses native Japanese core keywords and no English leakage","duration":0.7230429999999615,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=en including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=en including Riksdagsmonitor","duration":0.6755559999999718,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=sv including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=sv including Riksdagsmonitor","duration":0.45394999999996344,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=da including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=da including Riksdagsmonitor","duration":0.5163969999999836,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=no including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=no including Riksdagsmonitor","duration":0.4419680000000312,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=fi including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=fi including Riksdagsmonitor","duration":0.5153940000000148,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=de including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=de including Riksdagsmonitor","duration":0.47003100000000586,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=fr including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=fr including Riksdagsmonitor","duration":0.5101960000000076,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=es including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=es including Riksdagsmonitor","duration":0.4838970000000131,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=nl including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=nl including Riksdagsmonitor","duration":0.6627809999999954,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ar including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ar including Riksdagsmonitor","duration":0.5599379999999883,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=he including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=he including Riksdagsmonitor","duration":0.6255820000000085,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ja including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ja including Riksdagsmonitor","duration":0.5051559999999995,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=ko including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=ko including Riksdagsmonitor","duration":0.4894170000000031,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — covers every supported language"],"fullName":"buildArticleKeywords — covers every supported language returns a non-empty keyword string for lang=zh including Riksdagsmonitor","status":"passed","title":"returns a non-empty keyword string for lang=zh including Riksdagsmonitor","duration":0.5987509999999929,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]}],"startTime":1787953830951,"endTime":1787953830971.5986,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-seo-localized-keywords.test.ts"},{"assertionResults":[{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips a trailing \"and\" connector left after word-boundary truncation","status":"passed","title":"strips a trailing \"and\" connector left after word-boundary truncation","duration":6.6264659999999935,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips a trailing \"with\" connector","status":"passed","title":"strips a trailing \"with\" connector","duration":2.2467169999999896,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression ships short brief H1s as \"{H1} — Riksdagsmonitor\" with NO date prefix","status":"passed","title":"ships short brief H1s as \"{H1} — Riksdagsmonitor\" with NO date prefix","duration":0.9580339999999978,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips trailing connector AND date prefix when H1 just fits without brand","status":"passed","title":"strips trailing connector AND date prefix when H1 just fits without brand","duration":0.5535669999999868,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression never prepends a localized date prefix in any of the 14 supported languages","status":"passed","title":"never prepends a localized date prefix in any of the 14 supported languages","duration":1.9180510000000481,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips Swedish connector \"och\" when truncating a Swedish H1","status":"passed","title":"strips Swedish connector \"och\" when truncating a Swedish H1","duration":0.608019000000013,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression strips German connector \"und\" when truncating a German H1","status":"passed","title":"strips German connector \"und\" when truncating a German H1","duration":0.5581549999999993,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — trailing-connector regression"],"fullName":"buildSeoTitle — trailing-connector regression preserves a bare trailing uppercase `A` (live: `Plan A`, `Section A`, `Group A`)","status":"passed","title":"preserves a bare trailing uppercase `A` (live: `Plan A`, `Section A`, `Group A`)","duration":0.7114220000000273,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard strips a 2-word noun-phrase tail after the last comma","status":"passed","title":"strips a 2-word noun-phrase tail after the last comma","duration":0.6426240000000121,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard strips a 1-word noun tail (`the`-style determiner is a connector and is already stripped upstream)","status":"passed","title":"strips a 1-word noun tail (`the`-style determiner is a connector and is already stripped upstream)","duration":0.7876640000000066,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves the original text when the tail is too long (likely real clause)","status":"passed","title":"preserves the original text when the tail is too long (likely real clause)","duration":0.5269059999999968,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves the text when the head is short (would over-strip)","status":"passed","title":"preserves the text when the head is short (would over-strip)","duration":0.43124699999998484,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves text with no comma","status":"passed","title":"preserves text with no comma","duration":0.44062500000001137,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripTrailingCommaStub — comma-trailing fragment guard"],"fullName":"stripTrailingCommaStub — comma-trailing fragment guard preserves a tail that ends with a sentence terminator (real prose)","status":"passed","title":"preserves a tail that ends with a sentence terminator (real prose)","duration":0.45865799999995716,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]}],"startTime":1787953823322,"endTime":1787953823340.4587,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-seo-title-truncation.test.ts"},{"assertionResults":[{"ancestorTitles":["article-type-i18n","coverage"],"fullName":"article-type-i18n coverage every map entry covers all 14 languages with a non-empty string","status":"passed","title":"every map entry covers all 14 languages with a non-empty string","duration":15.611520999999982,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","coverage"],"fullName":"article-type-i18n coverage every registry article-type id has a localised label map","status":"passed","title":"every registry article-type id has a localised label map","duration":1.177124000000049,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() returns the localised label when both type and language are registered","status":"passed","title":"returns the localised label when both type and language are registered","duration":0.6559080000000108,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() falls back to the supplied English label for unknown type ids","status":"passed","title":"falls back to the supplied English label for unknown type ids","duration":0.391413,"failureMessages":[],"location":{"line":51,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() returns the English entry when lang is \"en\"","status":"passed","title":"returns the English entry when lang is \"en\"","duration":0.5538569999999936,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeLabel()"],"fullName":"article-type-i18n articleTypeLabel() preserves RTL strings exactly (Arabic, Hebrew)","status":"passed","title":"preserves RTL strings exactly (Arabic, Hebrew)","duration":0.5181709999999953,"failureMessages":[],"location":{"line":59,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() returns a distinct emoji icon for every registered article type","status":"passed","title":"returns a distinct emoji icon for every registered article type","duration":1.4289359999999647,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() falls back to 🔍 for unknown article-type ids","status":"passed","title":"falls back to 🔍 for unknown article-type ids","duration":0.441737000000046,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-type-i18n","articleTypeIcon()"],"fullName":"article-type-i18n articleTypeIcon() returns the registered icon for known types","status":"passed","title":"returns the registered icon for known types","duration":0.5764289999999619,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]}],"startTime":1787953907316,"endTime":1787953907337.5764,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-type-i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity parses as JSON and declares a semantic version","status":"passed","title":"parses as JSON and declares a semantic version","duration":4.780238999999995,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity declares at least the 13 known article types","status":"passed","title":"declares at least the 13 known article types","duration":2.3227190000000064,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity every type id is unique","status":"passed","title":"every type id is unique","duration":0.520183999999972,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — structural validity"],"fullName":"article-types registry — structural validity every subfolder is unique","status":"passed","title":"every subfolder is unique","duration":0.4132940000000076,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — workflow ↔ registry parity"],"fullName":"article-types registry — workflow ↔ registry parity every type with a workflow points to a real news-*.md source","status":"passed","title":"every type with a workflow points to a real news-*.md source","duration":0.8708300000000122,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — workflow ↔ registry parity"],"fullName":"article-types registry — workflow ↔ registry parity every news-*.md (except news-translate) has a registry entry","status":"passed","title":"every news-*.md (except news-translate) has a registry entry","duration":0.643714999999986,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules every long-horizon-forecast declares longHorizonRules","status":"passed","title":"every long-horizon-forecast declares longHorizonRules","duration":0.6919060000000172,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules quarter / year / cycle have ascending tier-C multipliers","status":"passed","title":"quarter / year / cycle have ascending tier-C multipliers","duration":0.6726400000000012,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules cycle horizon is at least 4 years (1460 days)","status":"passed","title":"cycle horizon is at least 4 years (1460 days)","duration":0.6115550000000098,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules election-cycle declares cycle-trajectory.md as an extra artifact","status":"passed","title":"election-cycle declares cycle-trajectory.md as an extra artifact","duration":0.5166169999999966,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — long-horizon rules"],"fullName":"article-types registry — long-horizon rules year-ahead and election-cycle mandate PESTLE","status":"passed","title":"year-ahead and election-cycle mandate PESTLE","duration":0.5750170000000026,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence current cycle ends where next cycle begins","status":"passed","title":"current cycle ends where next cycle begins","duration":0.4512149999999906,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence current cycle covers Tidö mandate (2022-09-11 → 2026-09-13)","status":"passed","title":"current cycle covers Tidö mandate (2022-09-11 → 2026-09-13)","duration":0.5021399999999971,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — election cycle coherence"],"fullName":"article-types registry — election cycle coherence next cycle ends 2030-09-08","status":"passed","title":"next cycle ends 2030-09-08","duration":0.4196359999999686,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — horizon bands"],"fullName":"article-types registry — horizon bands declares the canonical seven horizon bands","status":"passed","title":"declares the canonical seven horizon bands","duration":0.7836670000000368,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — horizon bands"],"fullName":"article-types registry — horizon bands each band has ascending or equal day-count by horizon","status":"passed","title":"each band has ascending or equal day-count by horizon","duration":0.5740949999999998,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — reference-quality-thresholds parity"],"fullName":"article-types registry — reference-quality-thresholds parity quarter-ahead, year-ahead, election-cycle have threshold blocks","status":"passed","title":"quarter-ahead, year-ahead, election-cycle have threshold blocks","duration":0.517879999999991,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"year-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":1.2777119999999513,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: every declared band exists in horizonBands registry","status":"passed","title":"year-ahead: every declared band exists in horizonBands registry","duration":0.5691560000000209,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts year-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"year-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.6327549999999746,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: forwardIndicatorHorizons matches fixture (4 bands)","status":"passed","title":"election-cycle: forwardIndicatorHorizons matches fixture (4 bands)","duration":0.6142600000000016,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: every declared band exists in horizonBands registry","status":"passed","title":"election-cycle: every declared band exists in horizonBands registry","duration":0.5226180000000227,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts election-cycle: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"election-cycle: WEP ceilings in fixture match horizonBands registry","duration":0.48982699999999113,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"week-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":0.5591670000000022,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: every declared band exists in horizonBands registry","status":"passed","title":"week-ahead: every declared band exists in horizonBands registry","duration":0.6927569999999719,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts week-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"week-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.5345009999999775,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: forwardIndicatorHorizons matches fixture (6 bands)","status":"passed","title":"month-ahead: forwardIndicatorHorizons matches fixture (6 bands)","duration":0.5785130000000436,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: every declared band exists in horizonBands registry","status":"passed","title":"month-ahead: every declared band exists in horizonBands registry","duration":0.5340199999999982,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts month-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"month-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.5762789999999995,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: forwardIndicatorHorizons matches fixture (5 bands)","status":"passed","title":"quarter-ahead: forwardIndicatorHorizons matches fixture (5 bands)","duration":0.5633450000000266,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: every declared band exists in horizonBands registry","status":"passed","title":"quarter-ahead: every declared band exists in horizonBands registry","duration":0.6365910000000099,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts quarter-ahead: WEP ceilings in fixture match horizonBands registry","status":"passed","title":"quarter-ahead: WEP ceilings in fixture match horizonBands registry","duration":0.6871470000000386,"failureMessages":[],"location":{"line":270,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts six-band coverage: month-ahead declares all 6 bands (72h, week, month, quarter, year, election)","status":"passed","title":"six-band coverage: month-ahead declares all 6 bands (72h, week, month, quarter, year, election)","duration":0.9590049999999906,"failureMessages":[],"location":{"line":280,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article-types registry — forward-indicator horizon band counts"],"fullName":"article-types registry — forward-indicator horizon band counts back-compat: single-type articles retain 4-band legacy schema","status":"passed","title":"back-compat: single-type articles retain 4-band legacy schema","duration":0.7652520000000322,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]}],"startTime":1787953822339,"endTime":1787953822366.7651,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n defaults to null when flag is absent","status":"passed","title":"defaults to null when flag is absent","duration":4.601725999999985,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses integer value correctly","status":"passed","title":"parses integer value correctly","duration":0.9285489999999754,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n accepts value 0 (explicit disable)","status":"passed","title":"accepts value 0 (explicit disable)","duration":0.5899740000000975,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n accepts larger values","status":"passed","title":"accepts larger values","duration":0.4595510000000331,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on negative value","status":"passed","title":"throws on negative value","duration":1.5456040000000257,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on non-integer value","status":"passed","title":"throws on non-integer value","duration":0.7887560000000349,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws on fractional value","status":"passed","title":"throws on fractional value","duration":0.7621669999999767,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n combines correctly with other flags","status":"passed","title":"combines correctly with other flags","duration":0.7539620000000014,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses --full-text-for-all as a boolean flag","status":"passed","title":"parses --full-text-for-all as a boolean flag","duration":0.5617419999999811,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveAutoFullTextTopN"],"fullName":"resolveAutoFullTextTopN raises long-horizon top-N requests to the floor of 10","status":"passed","title":"raises long-horizon top-N requests to the floor of 10","duration":0.606555999999955,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveAutoFullTextTopN"],"fullName":"resolveAutoFullTextTopN uses all selected documents when --full-text-for-all is enabled","status":"passed","title":"uses all selected documents when --full-text-for-all is enabled","duration":0.5267360000000281,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN returns empty array when topN is 0","status":"passed","title":"returns empty array when topN is 0","duration":1.8535200000000032,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN returns empty array when docs list is empty","status":"passed","title":"returns empty array when docs list is empty","duration":0.7195169999999962,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN fetches full text for top-N documents and persists to full-text/ dir","status":"passed","title":"fetches full text for top-N documents and persists to full-text/ dir","duration":3.1307520000000295,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN only fetches top-N documents even when more docs provided","status":"passed","title":"only fetches top-N documents even when more docs provided","duration":2.611780000000067,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN"],"fullName":"fetchFullTextForTopN creates full-text directory automatically","status":"passed","title":"creates full-text directory automatically","duration":1.2204649999999901,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response records success=false when content is below FULL_TEXT_MIN_LENGTH","status":"passed","title":"records success=false when content is below FULL_TEXT_MIN_LENGTH","duration":1.3589439999999513,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response falls back from text to fullText field when text is too short","status":"passed","title":"falls back from text to fullText field when text is too short","duration":1.2770600000000059,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — metadata-only response"],"fullName":"fetchFullTextForTopN graceful degradation — metadata-only response falls back to html field when text and fullText are too short","status":"passed","title":"falls back to html field when text and fullText are too short","duration":1.2906860000000506,"failureMessages":[],"location":{"line":267,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — fetchDocumentDetails throws"],"fullName":"fetchFullTextForTopN graceful degradation — fetchDocumentDetails throws records success=false with reason when MCP call rejects","status":"passed","title":"records success=false with reason when MCP call rejects","duration":1.4787189999999555,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","graceful degradation — fetchDocumentDetails throws"],"fullName":"fetchFullTextForTopN graceful degradation — fetchDocumentDetails throws continues to next document after one fails","status":"passed","title":"continues to next document after one fails","duration":1.6353920000000244,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","dokId resolution"],"fullName":"fetchFullTextForTopN dokId resolution skips documents with no resolvable dok_id","status":"passed","title":"skips documents with no resolvable dok_id","duration":1.1813419999999724,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","dokId resolution"],"fullName":"fetchFullTextForTopN dokId resolution resolves dok_id from dokument_id when dok_id is absent","status":"passed","title":"resolves dok_id from dokument_id when dok_id is absent","duration":1.4481109999999262,"failureMessages":[],"location":{"line":340,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content writes markdown file with header and content","status":"passed","title":"writes markdown file with header and content","duration":1.6101850000000013,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content filePath in outcome is relative to outputDir (not CWD)","status":"passed","title":"filePath in outcome is relative to outputDir (not CWD)","duration":1.3851539999999432,"failureMessages":[],"location":{"line":374,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["fetchFullTextForTopN","file content"],"fullName":"fetchFullTextForTopN file content sanitizes MP profile text (isPersonProfileText filter)","status":"passed","title":"sanitizes MP profile text (isPersonProfileText filter)","duration":1.2004779999999755,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["serializeDataManifest (via buildWeeklySummaryMarkdown sanity)"],"fullName":"serializeDataManifest (via buildWeeklySummaryMarkdown sanity) buildWeeklySummaryMarkdown still works after refactor","status":"passed","title":"buildWeeklySummaryMarkdown still works after refactor","duration":1.099066999999991,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract parseArgs exposes autoFullTextTopN=2 when flag is set","status":"passed","title":"parseArgs exposes autoFullTextTopN=2 when flag is set","duration":0.9235390000000052,"failureMessages":[],"location":{"line":431,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract fetchFullTextForTopN returns outcome with filePath for successful fetch","status":"passed","title":"fetchFullTextForTopN returns outcome with filePath for successful fetch","duration":1.60837099999992,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract analysis-gate can determine if top-2 full texts are available from outcomes","status":"passed","title":"analysis-gate can determine if top-2 full texts are available from outcomes","duration":1.5156979999999294,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract serializes coverage-state and deferred queue sections in the manifest","status":"passed","title":"serializes coverage-state and deferred queue sections in the manifest","duration":1.821649999999977,"failureMessages":[],"location":{"line":471,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract escapes pipes and collapses newlines in diagnostic manifest cells","status":"passed","title":"escapes pipes and collapses newlines in diagnostic manifest cells","duration":1.3825590000000147,"failureMessages":[],"location":{"line":537,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["manifest full-text outcomes integration contract"],"fullName":"manifest full-text outcomes integration contract escapes backslashes before pipes so escaped-pipe sentinels are unambiguous","status":"passed","title":"escapes backslashes before pipes so escaped-pipe sentinels are unambiguous","duration":1.1899079999999458,"failureMessages":[],"location":{"line":589,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) treats explicit indexing phrases as not_indexed","status":"passed","title":"treats explicit indexing phrases as not_indexed","duration":1.1658429999999953,"failureMessages":[],"location":{"line":644,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) treats transport-level failures as fetch_error, NOT not_indexed","status":"passed","title":"treats transport-level failures as fetch_error, NOT not_indexed","duration":1.1371489999999085,"failureMessages":[],"location":{"line":650,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDocumentNotIndexedError (transport vs document-level disambiguation)"],"fullName":"isDocumentNotIndexedError (transport vs document-level disambiguation) only treats bare \"not found\" as not_indexed when paired with the dok_id","status":"passed","title":"only treats bare \"not found\" as not_indexed when paired with the dok_id","duration":1.09241499999996,"failureMessages":[],"location":{"line":658,"column":3},"meta":{},"tags":[]}],"startTime":1787953666729,"endTime":1787953666778.0925,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/auto-full-text-top-n.test.ts"},{"assertionResults":[{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should exist in DOM","status":"passed","title":"should exist in DOM","duration":7.35496900000004,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have back-to-top class","status":"passed","title":"should have back-to-top class","duration":1.2588170000000218,"failureMessages":[],"location":{"line":41,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have proper aria-label for accessibility","status":"passed","title":"should have proper aria-label for accessibility","duration":0.7393749999999955,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have arrow content","status":"passed","title":"should have arrow content","duration":0.7227530000000115,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","DOM Structure"],"fullName":"Back to Top Button DOM Structure should have id=\"back-to-top\"","status":"passed","title":"should have id=\"back-to-top\"","duration":0.76636400000001,"failureMessages":[],"location":{"line":53,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should not have visible class initially","status":"passed","title":"should not have visible class initially","duration":0.612446000000034,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should add visible class when pageYOffset > 300","status":"passed","title":"should add visible class when pageYOffset > 300","duration":0.8842250000000149,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should remove visible class when pageYOffset <= 300","status":"passed","title":"should remove visible class when pageYOffset <= 300","duration":0.8134529999999813,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should remove visible class when pageYOffset is 0","status":"passed","title":"should remove visible class when pageYOffset is 0","duration":0.839492000000007,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should toggle correctly at boundary (300 = hidden, 301 = visible)","status":"passed","title":"should toggle correctly at boundary (300 = hidden, 301 = visible)","duration":0.7091279999999642,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Scroll Visibility"],"fullName":"Back to Top Button Scroll Visibility should support scroll event listener registration","status":"passed","title":"should support scroll event listener registration","duration":3.5700140000000147,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should support smooth scrolling API","status":"passed","title":"should support smooth scrolling API","duration":0.7839969999999994,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should call scrollTo with smooth behavior when no motion preference","status":"passed","title":"should call scrollTo with smooth behavior when no motion preference","duration":1.6254330000000436,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should call scrollTo with auto behavior when prefers-reduced-motion","status":"passed","title":"should call scrollTo with auto behavior when prefers-reduced-motion","duration":1.07038399999999,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should always scroll to top: 0","status":"passed","title":"should always scroll to top: 0","duration":1.5563830000000394,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Click Behavior"],"fullName":"Back to Top Button Click Behavior should support click event listener registration","status":"passed","title":"should support click event listener registration","duration":1.0796009999999683,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should check prefers-reduced-motion media query","status":"passed","title":"should check prefers-reduced-motion media query","duration":1.0505269999999882,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should detect when user prefers reduced motion","status":"passed","title":"should detect when user prefers reduced motion","duration":1.04051800000002,"failureMessages":[],"location":{"line":216,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should use auto behavior for reduced-motion users","status":"passed","title":"should use auto behavior for reduced-motion users","duration":0.8193840000000137,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Prefers Reduced Motion"],"fullName":"Back to Top Button Prefers Reduced Motion should use smooth behavior for standard users","status":"passed","title":"should use smooth behavior for standard users","duration":0.752448999999956,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle missing button gracefully","status":"passed","title":"should handle missing button gracefully","duration":0.853868000000034,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle large scroll values","status":"passed","title":"should handle large scroll values","duration":0.8713020000000142,"failureMessages":[],"location":{"line":258,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button","Edge Cases"],"fullName":"Back to Top Button Edge Cases should handle negative scroll values","status":"passed","title":"should handle negative scroll values","duration":0.873395999999957,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button — progressive-enhancement auto-inject"],"fullName":"Back to Top Button — progressive-enhancement auto-inject injects the button when the authored markup is missing","status":"passed","title":"injects the button when the authored markup is missing","duration":2.8070060000000012,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Back to Top Button — progressive-enhancement auto-inject"],"fullName":"Back to Top Button — progressive-enhancement auto-inject reuses the authored button when markup is already present","status":"passed","title":"reuses the authored button when markup is already present","duration":3.9388640000000237,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]}],"startTime":1787953820882,"endTime":1787953820919.939,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/back-to-top.test.js"},{"assertionResults":[{"ancestorTitles":["backfill-news-og-locale-alternate.ts","idempotency"],"fullName":"backfill-news-og-locale-alternate.ts idempotency skips files that already contain og:locale:alternate","status":"passed","title":"skips files that already contain og:locale:alternate","duration":3.8723000000000525,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","safety: no og:locale tag"],"fullName":"backfill-news-og-locale-alternate.ts safety: no og:locale tag does not invent an og:locale block when none exists","status":"passed","title":"does not invent an og:locale block when none exists","duration":0.9966760000000363,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","safety: unknown locale"],"fullName":"backfill-news-og-locale-alternate.ts safety: unknown locale skips files whose og:locale content is not in the lookup table","status":"passed","title":"skips files whose og:locale content is not in the lookup table","duration":0.5508209999999849,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=en (en_US)","status":"passed","title":"injects exactly 13 alternates for lang=en (en_US)","duration":1.2613010000000031,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=sv (sv_SE)","status":"passed","title":"injects exactly 13 alternates for lang=sv (sv_SE)","duration":0.7877050000000168,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=da (da_DK)","status":"passed","title":"injects exactly 13 alternates for lang=da (da_DK)","duration":0.6391160000000013,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=no (nb_NO)","status":"passed","title":"injects exactly 13 alternates for lang=no (nb_NO)","duration":0.7585710000000176,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=fi (fi_FI)","status":"passed","title":"injects exactly 13 alternates for lang=fi (fi_FI)","duration":0.6122059999999578,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=de (de_DE)","status":"passed","title":"injects exactly 13 alternates for lang=de (de_DE)","duration":1.0669980000000123,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=fr (fr_FR)","status":"passed","title":"injects exactly 13 alternates for lang=fr (fr_FR)","duration":0.9943610000000263,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=es (es_ES)","status":"passed","title":"injects exactly 13 alternates for lang=es (es_ES)","duration":0.9327670000000126,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=nl (nl_NL)","status":"passed","title":"injects exactly 13 alternates for lang=nl (nl_NL)","duration":0.8631060000000161,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ar (ar_SA)","status":"passed","title":"injects exactly 13 alternates for lang=ar (ar_SA)","duration":0.9229080000000067,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=he (he_IL)","status":"passed","title":"injects exactly 13 alternates for lang=he (he_IL)","duration":0.809285999999986,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ja (ja_JP)","status":"passed","title":"injects exactly 13 alternates for lang=ja (ja_JP)","duration":1.155033000000003,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=ko (ko_KR)","status":"passed","title":"injects exactly 13 alternates for lang=ko (ko_KR)","duration":0.7805409999999711,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","correctness — all 14 languages"],"fullName":"backfill-news-og-locale-alternate.ts correctness — all 14 languages injects exactly 13 alternates for lang=zh (zh_CN)","status":"passed","title":"injects exactly 13 alternates for lang=zh (zh_CN)","duration":0.7447940000000131,"failureMessages":[],"location":{"line":77,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves 2-space leading indentation","status":"passed","title":"preserves 2-space leading indentation","duration":0.6210530000000176,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves 4-space leading indentation","status":"passed","title":"preserves 4-space leading indentation","duration":0.5065789999999879,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","whitespace preservation"],"fullName":"backfill-news-og-locale-alternate.ts whitespace preservation preserves zero leading indentation","status":"passed","title":"preserves zero leading indentation","duration":0.49300300000004427,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","idempotency on second pass"],"fullName":"backfill-news-og-locale-alternate.ts idempotency on second pass running the backfill twice produces the same result as running it once","status":"passed","title":"running the backfill twice produces the same result as running it once","duration":0.6863049999999475,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness every supported language has a unique og:locale value","status":"passed","title":"every supported language has a unique og:locale value","duration":0.48703199999999924,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Norwegian uses BCP-47 nb_NO (Norwegian Bokmål)","status":"passed","title":"Norwegian uses BCP-47 nb_NO (Norwegian Bokmål)","duration":0.5550289999999904,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Chinese uses zh_CN","status":"passed","title":"Chinese uses zh_CN","duration":0.45207700000003115,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","locale lookup table completeness"],"fullName":"backfill-news-og-locale-alternate.ts locale lookup table completeness Arabic uses ar_SA","status":"passed","title":"Arabic uses ar_SA","duration":0.4601519999999937,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization rewrites no_NO → nb_NO and injects 13 alternates","status":"passed","title":"rewrites no_NO → nb_NO and injects 13 alternates","duration":0.622175000000027,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization rewrites en_GB → en_US and injects 13 alternates","status":"passed","title":"rewrites en_GB → en_US and injects 13 alternates","duration":0.6444869999999696,"failureMessages":[],"location":{"line":171,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization does not flag canonical locales as normalized","status":"passed","title":"does not flag canonical locales as normalized","duration":0.5160060000000044,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["backfill-news-og-locale-alternate.ts","non-canonical locale normalization"],"fullName":"backfill-news-og-locale-alternate.ts non-canonical locale normalization normalization is idempotent on second pass","status":"passed","title":"normalization is idempotent on second pass","duration":0.5569830000000024,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]}],"startTime":1787953841043,"endTime":1787953841068.557,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-news-og-locale-alternate.test.ts"},{"assertionResults":[{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html mirrors the browser stats-loader STAT_MAPPINGS exactly","status":"passed","title":"mirrors the browser stats-loader STAT_MAPPINGS exactly","duration":4.778137000000015,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html builds a lookup from a representative CSV slice","status":"passed","title":"builds a lookup from a representative CSV slice","duration":15.238623000000018,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html rewrites only the text content of matching stat spans","status":"passed","title":"rewrites only the text content of matching stat spans","duration":1.2333399999999983,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html is idempotent — re-baking concrete values is a no-op for those","status":"passed","title":"is idempotent — re-baking concrete values is a no-op for those","duration":0.5662090000000148,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["bake-stats-html"],"fullName":"bake-stats-html does not match across element boundaries","status":"passed","title":"does not match across element boundaries","duration":0.5614209999999957,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]}],"startTime":1787953892752,"endTime":1787953892774.5662,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/bake-stats-html.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines all ten HD-prefixed bill IDs from the brief","status":"passed","title":"mines all ten HD-prefixed bill IDs from the brief","duration":4.36098400000003,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines committee codes only when they appear in parens or with report digits","status":"passed","title":"mines committee codes only when they appear in parens or with report digits","duration":0.6133580000000052,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) mines party codes only from parenthetical lists (gating against bare-word noise)","status":"passed","title":"mines party codes only from parenthetical lists (gating against bare-word noise)","duration":0.4680670000000191,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) does NOT include section-header prose words as named entities","status":"passed","title":"does NOT include section-header prose words as named entities","duration":1.4552140000000122,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — propositions fixture (English)"],"fullName":"extractBriefEntities — propositions fixture (English) does NOT produce multiline-spanning named entities","status":"passed","title":"does NOT produce multiline-spanning named entities","duration":0.3544239999999945,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 60-Second Read"],"fullName":"extractHeadlineSection — 60-Second Read finds the 60-Second Read section and returns its bullet lines","status":"passed","title":"finds the 60-Second Read section and returns its bullet lines","duration":2.0579830000000356,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 60-Second Read"],"fullName":"extractHeadlineSection — 60-Second Read returns heading=null and empty bullets when no headline section is present","status":"passed","title":"returns heading=null and empty bullets when no headline section is present","duration":0.9795239999999694,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["flattenBriefEntities — editorial priority ordering"],"fullName":"flattenBriefEntities — editorial priority ordering puts bill IDs ahead of committee codes ahead of party codes","status":"passed","title":"puts bill IDs ahead of committee codes ahead of party codes","duration":0.9571819999999889,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — empty / null safety"],"fullName":"extractBriefEntities — empty / null safety returns empty arrays for empty input","status":"passed","title":"returns empty arrays for empty input","duration":0.718373999999983,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBriefEntities — empty / null safety"],"fullName":"extractBriefEntities — empty / null safety CJK locales (no Latin capitals) mine universal IDs only, no named entities","status":"passed","title":"CJK locales (no Latin capitals) mine universal IDs only, no named entities","duration":0.7037980000000061,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [sv] matches \"## ⚡ 60 sekunders läsning\"","status":"passed","title":"[sv] matches \"## ⚡ 60 sekunders läsning\"","duration":0.7413579999999911,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [sv] matches \"## ⚡ 60-sekunders underrättelsepunkter\"","status":"passed","title":"[sv] matches \"## ⚡ 60-sekunders underrättelsepunkter\"","duration":0.45688499999999976,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [da] matches \"## ⚡ 60 sekunders læsning\"","status":"passed","title":"[da] matches \"## ⚡ 60 sekunders læsning\"","duration":0.5007080000000315,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [da] matches \"## ⚡ 60 sekunders efterretningspunkter\"","status":"passed","title":"[da] matches \"## ⚡ 60 sekunders efterretningspunkter\"","duration":0.4397040000000061,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [no] matches \"## ⚡ 60 sekunders lesning\"","status":"passed","title":"[no] matches \"## ⚡ 60 sekunders lesning\"","duration":0.5269569999999817,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [no] matches \"## ⚡ 60 sekunders etterretningspunkter\"","status":"passed","title":"[no] matches \"## ⚡ 60 sekunders etterretningspunkter\"","duration":0.48721199999999953,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fi] matches \"## ⚡ 60 sekunnin lukeminen\"","status":"passed","title":"[fi] matches \"## ⚡ 60 sekunnin lukeminen\"","duration":0.5807570000000055,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fi] matches \"## ⚡ 60 sekunnin tiedustelutiivistelmä\"","status":"passed","title":"[fi] matches \"## ⚡ 60 sekunnin tiedustelutiivistelmä\"","duration":0.45064400000001115,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [de] matches \"## ⚡ 60 Sekunden-Lektüre\"","status":"passed","title":"[de] matches \"## ⚡ 60 Sekunden-Lektüre\"","duration":0.5120979999999804,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [de] matches \"## ⚡ 60-Sekunden nachrichtendienstliche Punkte\"","status":"passed","title":"[de] matches \"## ⚡ 60-Sekunden nachrichtendienstliche Punkte\"","duration":0.46501999999998134,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fr] matches \"## ⚡ Lecture en 60 secondes\"","status":"passed","title":"[fr] matches \"## ⚡ Lecture en 60 secondes\"","duration":0.5651979999999526,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [fr] matches \"## ⚡ Points de renseignement en 60 secondes\"","status":"passed","title":"[fr] matches \"## ⚡ Points de renseignement en 60 secondes\"","duration":0.5515419999999835,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] matches \"## ⚡ Lectura de 60 segundos\"","status":"passed","title":"[es] matches \"## ⚡ Lectura de 60 segundos\"","duration":0.5465940000000273,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] matches \"## ⚡ Puntos de inteligencia en 60 segundos\"","status":"passed","title":"[es] matches \"## ⚡ Puntos de inteligencia en 60 segundos\"","duration":0.5289100000000531,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [nl] matches \"## ⚡ 60 seconden lezing\"","status":"passed","title":"[nl] matches \"## ⚡ 60 seconden lezing\"","duration":0.47998799999999164,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [nl] matches \"## ⚡ 60 seconden inlichtingenpunten\"","status":"passed","title":"[nl] matches \"## ⚡ 60 seconden inlichtingenpunten\"","duration":0.5569830000000024,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ar] matches \"## ⚡ قراءة 60 ثانية\"","status":"passed","title":"[ar] matches \"## ⚡ قراءة 60 ثانية\"","duration":0.4718040000000201,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ar] matches \"## ⚡ نقاط الاستخبارات في 60 ثانية\"","status":"passed","title":"[ar] matches \"## ⚡ نقاط الاستخبارات في 60 ثانية\"","duration":0.5688349999999787,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [he] matches \"## ⚡ קריאה של 60 שניות\"","status":"passed","title":"[he] matches \"## ⚡ קריאה של 60 שניות\"","duration":0.5227280000000292,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [he] matches \"## ⚡ נקודות מודיעין ב-60 שניות\"","status":"passed","title":"[he] matches \"## ⚡ נקודות מודיעין ב-60 שניות\"","duration":0.5603790000000117,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ja] matches \"## ⚡ 60秒で読む\"","status":"passed","title":"[ja] matches \"## ⚡ 60秒で読む\"","duration":0.7570069999999873,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ja] matches \"## ⚡ 60秒インテリジェンスポイント\"","status":"passed","title":"[ja] matches \"## ⚡ 60秒インテリジェンスポイント\"","duration":0.7537310000000161,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ko] matches \"## ⚡ 60초 읽기\"","status":"passed","title":"[ko] matches \"## ⚡ 60초 읽기\"","duration":0.5786030000000437,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [ko] matches \"## ⚡ 60초 인텔리전스 포인트\"","status":"passed","title":"[ko] matches \"## ⚡ 60초 인텔리전스 포인트\"","duration":0.7881849999999986,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] matches \"## ⚡ 60秒速读\"","status":"passed","title":"[zh] matches \"## ⚡ 60秒速读\"","duration":0.7499540000000025,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] matches \"## ⚡ 60秒情报要点\"","status":"passed","title":"[zh] matches \"## ⚡ 60秒情报要点\"","duration":0.6311210000000074,"failureMessages":[],"location":{"line":186,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [en] EN dictionary still matches `60-Second Read` (regression guard)","status":"passed","title":"[en] EN dictionary still matches `60-Second Read` (regression guard)","duration":0.6771779999999694,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [es] numbered list bullets (1. 2. …) are collected from Lectura en 60 segundos","status":"passed","title":"[es] numbered list bullets (1. 2. …) are collected from Lectura en 60 segundos","duration":0.7929440000000341,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractHeadlineSection — 14-language headline dictionary (live corpus)"],"fullName":"extractHeadlineSection — 14-language headline dictionary (live corpus) [zh] numbered list bullets (1. 2. …) are collected from 60秒速读","status":"passed","title":"[zh] numbered list bullets (1. 2. …) are collected from 60秒速读","duration":0.6693829999999821,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]}],"startTime":1787953821380,"endTime":1787953821410.6694,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/brief-extractor.test.ts"},{"assertionResults":[{"ancestorTitles":["brief-prefixes — dictionary coverage"],"fullName":"brief-prefixes — dictionary coverage contains entries for every supported language","status":"passed","title":"contains entries for every supported language","duration":4.634225000000015,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — dictionary coverage"],"fullName":"brief-prefixes — dictionary coverage every entry is a non-empty literal string","status":"passed","title":"every entry is a non-empty literal string","duration":9.295453000000009,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching returns the same RegExp instance across calls for the same language","status":"passed","title":"returns the same RegExp instance across calls for the same language","duration":1.1220799999999826,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching returns distinct compiled regexes for distinct languages","status":"passed","title":"returns distinct compiled regexes for distinct languages","duration":1.473228000000006,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching caches the result for every supported language","status":"passed","title":"caches the result for every supported language","duration":1.034877999999992,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — regex caching"],"fullName":"brief-prefixes — regex caching reset cache helper clears prior compilations","status":"passed","title":"reset cache helper clears prior compilations","duration":0.6208520000000135,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'en'","status":"passed","title":"strips the boilerplate prefix for 'en'","duration":0.7623570000000086,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'sv'","status":"passed","title":"strips the boilerplate prefix for 'sv'","duration":0.5962059999999951,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'da'","status":"passed","title":"strips the boilerplate prefix for 'da'","duration":0.7549439999999663,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'no'","status":"passed","title":"strips the boilerplate prefix for 'no'","duration":0.6708659999999895,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'fi'","status":"passed","title":"strips the boilerplate prefix for 'fi'","duration":0.6745329999999967,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'de'","status":"passed","title":"strips the boilerplate prefix for 'de'","duration":0.6369530000000054,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'fr'","status":"passed","title":"strips the boilerplate prefix for 'fr'","duration":0.586387000000002,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'es'","status":"passed","title":"strips the boilerplate prefix for 'es'","duration":0.5869490000000042,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'nl'","status":"passed","title":"strips the boilerplate prefix for 'nl'","duration":0.5882710000000202,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ar'","status":"passed","title":"strips the boilerplate prefix for 'ar'","duration":0.5761090000000308,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'he'","status":"passed","title":"strips the boilerplate prefix for 'he'","duration":0.5792849999999703,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ja'","status":"passed","title":"strips the boilerplate prefix for 'ja'","duration":0.5890029999999911,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'ko'","status":"passed","title":"strips the boilerplate prefix for 'ko'","duration":0.5832920000000286,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix strips the boilerplate prefix for 'zh'","status":"passed","title":"strips the boilerplate prefix for 'zh'","duration":0.5654789999999821,"failureMessages":[],"location":{"line":114,"column":19},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix returns the text unchanged when no prefix matches","status":"passed","title":"returns the text unchanged when no prefix matches","duration":0.8067199999999843,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix matches case-insensitively (UPPERCASE prefix)","status":"passed","title":"matches case-insensitively (UPPERCASE prefix)","duration":0.556933000000015,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — stripBriefPrefix"],"fullName":"brief-prefixes — stripBriefPrefix longer compound prefix wins over its shorter substring","status":"passed","title":"longer compound prefix wins over its shorter substring","duration":0.5618420000000128,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Underrättelsebriefing — Sverige Antar…'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Underrättelsebriefing — Sverige Antar…'","duration":0.4384410000000116,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Verkställande sammanfattning — Riksda…'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Verkställande sammanfattning — Riksda…'","duration":0.4580680000000257,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['sv'] strips corpus-observed prefix: 'Kortanalys — Budgetproposition 2026'","status":"passed","title":"['sv'] strips corpus-observed prefix: 'Kortanalys — Budgetproposition 2026'","duration":0.38522100000000137,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['da'] strips corpus-observed prefix: 'Efterretningsbriefing — Parlamentsval…'","status":"passed","title":"['da'] strips corpus-observed prefix: 'Efterretningsbriefing — Parlamentsval…'","duration":0.5031020000000126,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['da'] strips corpus-observed prefix: 'Eksekutiv resumé — Parlamentet Vedtag…'","status":"passed","title":"['da'] strips corpus-observed prefix: 'Eksekutiv resumé — Parlamentet Vedtag…'","duration":0.43726799999996047,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['no'] strips corpus-observed prefix: 'Etterretningsbriefing — Stortingets V…'","status":"passed","title":"['no'] strips corpus-observed prefix: 'Etterretningsbriefing — Stortingets V…'","duration":0.46711399999998093,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['no'] strips corpus-observed prefix: 'Ledersammendrag — Ny Migrasjonslov Ve…'","status":"passed","title":"['no'] strips corpus-observed prefix: 'Ledersammendrag — Ny Migrasjonslov Ve…'","duration":0.4574060000000486,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fi'] strips corpus-observed prefix: 'Johtoryhmän tiivistelmä — Eduskunta H…'","status":"passed","title":"['fi'] strips corpus-observed prefix: 'Johtoryhmän tiivistelmä — Eduskunta H…'","duration":0.5632039999999847,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fi'] strips corpus-observed prefix: 'Johdon tiivistelmä — Budjettiesitys 2…'","status":"passed","title":"['fi'] strips corpus-observed prefix: 'Johdon tiivistelmä — Budjettiesitys 2…'","duration":0.5395809999999983,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['de'] strips corpus-observed prefix: 'Exekutivzusammenfassung — Bundestag V…'","status":"passed","title":"['de'] strips corpus-observed prefix: 'Exekutivzusammenfassung — Bundestag V…'","duration":0.5616110000000276,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['de'] strips corpus-observed prefix: 'Kurzanalyse — Migrationspolitik 2026'","status":"passed","title":"['de'] strips corpus-observed prefix: 'Kurzanalyse — Migrationspolitik 2026'","duration":0.4837259999999901,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fr'] strips corpus-observed prefix: 'Synthèse — Le Parlement Suédois Vote …'","status":"passed","title":"['fr'] strips corpus-observed prefix: 'Synthèse — Le Parlement Suédois Vote …'","duration":0.5481059999999616,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['fr'] strips corpus-observed prefix: 'Note de synthèse exécutive — Réforme …'","status":"passed","title":"['fr'] strips corpus-observed prefix: 'Note de synthèse exécutive — Réforme …'","duration":2.10706399999998,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['es'] strips corpus-observed prefix: 'Nota ejecutiva — El Parlamento Sueco …'","status":"passed","title":"['es'] strips corpus-observed prefix: 'Nota ejecutiva — El Parlamento Sueco …'","duration":0.4381999999999948,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['nl'] strips corpus-observed prefix: 'Uitvoerende samenvatting — Het Zweeds…'","status":"passed","title":"['nl'] strips corpus-observed prefix: 'Uitvoerende samenvatting — Het Zweeds…'","duration":0.5739049999999679,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['nl'] strips corpus-observed prefix: 'Managementsamenvatting — Migratieherv…'","status":"passed","title":"['nl'] strips corpus-observed prefix: 'Managementsamenvatting — Migratieherv…'","duration":0.37720600000000104,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ar'] strips corpus-observed prefix: 'الملخص التنفيذي — البرلمان السويدي يص…'","status":"passed","title":"['ar'] strips corpus-observed prefix: 'الملخص التنفيذي — البرلمان السويدي يص…'","duration":0.4428490000000238,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ar'] strips corpus-observed prefix: 'إحاطة استخباراتية — تصويت مهم في البر…'","status":"passed","title":"['ar'] strips corpus-observed prefix: 'إحاطة استخباراتية — تصويت مهم في البر…'","duration":0.38567199999999957,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['he'] strips corpus-observed prefix: 'סיכום מנהלים — הפרלמנט השוודי מצביע ע…'","status":"passed","title":"['he'] strips corpus-observed prefix: 'סיכום מנהלים — הפרלמנט השוודי מצביע ע…'","duration":0.6533129999999687,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['he'] strips corpus-observed prefix: 'תדריך מנהלים — חקיקה חדשה בשוודיה'","status":"passed","title":"['he'] strips corpus-observed prefix: 'תדריך מנהלים — חקיקה חדשה בשוודיה'","duration":0.4191240000000107,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ja'] strips corpus-observed prefix: '情報ブリーフィング — スウェーデン議会が移民改革を可決'","status":"passed","title":"['ja'] strips corpus-observed prefix: '情報ブリーフィング — スウェーデン議会が移民改革を可決'","duration":0.5054569999999785,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ja'] strips corpus-observed prefix: 'インテリジェンスブリーフィング — 重要な立法決定'","status":"passed","title":"['ja'] strips corpus-observed prefix: 'インテリジェンスブリーフィング — 重要な立法決定'","duration":0.42273099999999886,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ko'] strips corpus-observed prefix: '집행 브리핑 — 스웨덴 의회가 이민법을 통과'","status":"passed","title":"['ko'] strips corpus-observed prefix: '집행 브리핑 — 스웨덴 의회가 이민법을 통과'","duration":0.5130100000000084,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['ko'] strips corpus-observed prefix: '임원 브리핑 — 중요한 입법 결정'","status":"passed","title":"['ko'] strips corpus-observed prefix: '임원 브리핑 — 중요한 입법 결정'","duration":0.4402340000000322,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['zh'] strips corpus-observed prefix: '执行简报 — 瑞典议会通过移民改革法案'","status":"passed","title":"['zh'] strips corpus-observed prefix: '执行简报 — 瑞典议会通过移民改革法案'","duration":0.55072100000001,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]},{"ancestorTitles":["brief-prefixes — corpus-observed additions (2026-05)"],"fullName":"brief-prefixes — corpus-observed additions (2026-05) ['zh'] strips corpus-observed prefix: '行政简报 — 重要立法决定'","status":"passed","title":"['zh'] strips corpus-observed prefix: '行政简报 — 重要立法决定'","duration":0.6747529999999529,"failureMessages":[],"location":{"line":183,"column":28},"meta":{},"tags":[]}],"startTime":1787953825866,"endTime":1787953825910.6748,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/brief-prefixes.test.ts"},{"assertionResults":[{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should store data via loadText and cache under the module prefix","status":"passed","title":"should store data via loadText and cache under the module prefix","duration":7.059045999999967,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should evict only prefixed entries on QuotaExceededError and retry","status":"passed","title":"should evict only prefixed entries on QuotaExceededError and retry","duration":1.2941730000000007,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader cache eviction (production paths)"],"fullName":"Shared data-loader cache eviction (production paths) should NOT evict on SecurityError (storage disabled)","status":"passed","title":"should NOT evict on SecurityError (storage disabled)","duration":0.8748580000000175,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Election-cycle cache eviction"],"fullName":"Election-cycle cache eviction should evict only election-cycle entries on QuotaExceededError","status":"passed","title":"should evict only election-cycle entries on QuotaExceededError","duration":29.696957999999995,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Election-cycle cache eviction"],"fullName":"Election-cycle cache eviction should NOT evict on SecurityError (storage disabled)","status":"passed","title":"should NOT evict on SecurityError (storage disabled)","duration":0.9248010000000022,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader eviction strategy"],"fullName":"Shared data-loader eviction strategy should evict oldest half of PREFIXED cache entries by timestamp","status":"passed","title":"should evict oldest half of PREFIXED cache entries by timestamp","duration":0.815477000000044,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Shared data-loader eviction strategy"],"fullName":"Shared data-loader eviction strategy should evict at least one entry even when only one exists","status":"passed","title":"should evict at least one entry even when only one exists","duration":0.5361039999999662,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]}],"startTime":1787953821839,"endTime":1787953821881.5361,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cache-eviction.test.ts"},{"assertionResults":[{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch emits normalized calendar status for an org-scoped fetch","status":"passed","title":"emits normalized calendar status for an org-scoped fetch","duration":4.6064250000000015,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch captures fetch errors without throwing","status":"passed","title":"captures fetch errors without throwing","duration":0.8539490000000001,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calendar-fetch"],"fullName":"calendar-fetch filters scoped events in injected MCP client mode","status":"passed","title":"filters scoped events in injected MCP client mode","duration":1.5381800000000112,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]}],"startTime":1787953927437,"endTime":1787953927444.538,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/calendar-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data returns empty catalog for empty data root","status":"passed","title":"returns empty catalog for empty data root","duration":5.826740000000029,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs proposition files","status":"passed","title":"catalogs proposition files","duration":3.0100360000000137,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data detects existing analysis files","status":"passed","title":"detects existing analysis files","duration":1.1235829999999964,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data filters by type","status":"passed","title":"filters by type","duration":0.9581029999999942,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data filters pending-only","status":"passed","title":"filters pending-only","duration":1.58680099999998,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data excludes .meta.json files from entries","status":"passed","title":"excludes .meta.json files from entries","duration":1.230673999999965,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles nested date directories (votes/YYYY-MM-DD/)","status":"passed","title":"handles nested date directories (votes/YYYY-MM-DD/)","duration":1.0750229999999874,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs documents/votes/ for votes without valid datum","status":"passed","title":"catalogs documents/votes/ for votes without valid datum","duration":0.9271160000000123,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data deduplicates votes appearing in both documents/votes and votes/YYYY-MM-DD","status":"passed","title":"deduplicates votes appearing in both documents/votes and votes/YYYY-MM-DD","duration":1.701755999999989,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles malformed meta.json gracefully","status":"passed","title":"handles malformed meta.json gracefully","duration":1.052129999999977,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data records file size","status":"passed","title":"records file size","duration":0.9450300000000311,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data catalogs multiple types at once","status":"passed","title":"catalogs multiple types at once","duration":1.8551740000000336,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data generates analysis paths alongside data files","status":"passed","title":"generates analysis paths alongside data files","duration":0.8624250000000302,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["catalog-downloaded-data"],"fullName":"catalog-downloaded-data handles nested type subdirectories with duplicate basenames","status":"passed","title":"handles nested type subdirectories with duplicate basenames","duration":1.1649610000000052,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]}],"startTime":1787953840090,"endTime":1787953840114.165,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/catalog-downloaded-data.test.ts"},{"assertionResults":[{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth parses a valid JSON config and instantiates Chart.js","status":"passed","title":"parses a valid JSON config and instantiates Chart.js","duration":6.351392000000033,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth rejects configs whose raw attribute contains a function literal","status":"passed","title":"rejects configs whose raw attribute contains a function literal","duration":2.628130999999996,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth rejects configs with function literal and additional whitespace variants","status":"passed","title":"rejects configs with function literal and additional whitespace variants","duration":1.7953520000000367,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — defense-in-depth"],"fullName":"chart-init — defense-in-depth ignores canvases with missing or malformed data-chart-config","status":"passed","title":"ignores canvases with missing or malformed data-chart-config","duration":1.958517000000029,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion disables animation on parsed config when user prefers reduced motion","status":"passed","title":"disables animation on parsed config when user prefers reduced motion","duration":1.1144370000000094,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion preserves original animation settings when user has no reduced-motion preference","status":"passed","title":"preserves original animation settings when user has no reduced-motion preference","duration":1.7825179999999818,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion clears animations/transitions objects when reduced-motion is requested","status":"passed","title":"clears animations/transitions objects when reduced-motion is requested","duration":1.1174330000000054,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chart-init — prefers-reduced-motion"],"fullName":"chart-init — prefers-reduced-motion handles configs without an options field gracefully","status":"passed","title":"handles configs without an options field gracefully","duration":0.9944409999999948,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]}],"startTime":1787953891344,"endTime":1787953891361.9944,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chart-init.test.js"},{"assertionResults":[{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes YAML frontmatter","status":"passed","title":"removes YAML frontmatter","duration":4.196146999999996,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes code fences","status":"passed","title":"removes code fences","duration":0.6243590000000268,"failureMessages":[],"location":{"line":29,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter removes inline code","status":"passed","title":"removes inline code","duration":0.5379970000000185,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","stripMarkdownCodeAndFrontmatter"],"fullName":"check-analysis-language stripMarkdownCodeAndFrontmatter does NOT strip body text between two `---` thematic breaks (regression: regex `/m` flag)","status":"passed","title":"does NOT strip body text between two `---` thematic breaks (regression: regex `/m` flag)","duration":0.4752700000000232,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords extracts lowercase words","status":"passed","title":"extracts lowercase words","duration":1.224232000000029,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords handles Swedish characters","status":"passed","title":"handles Swedish characters","duration":1.2156049999999823,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","tokenizeWords"],"fullName":"check-analysis-language tokenizeWords returns empty array for no words","status":"passed","title":"returns empty array for no words","duration":0.5244519999999966,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity detects 100% English content","status":"passed","title":"detects 100% English content","duration":1.0215929999999958,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity detects heavily Swedish content","status":"passed","title":"detects heavily Swedish content","duration":1.03751299999999,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","calculateSwedishDensity"],"fullName":"check-analysis-language calculateSwedishDensity handles empty file","status":"passed","title":"handles empty file","duration":0.5556199999999762,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles finds regular markdown files","status":"passed","title":"finds regular markdown files","duration":1.6742750000000228,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes executive-brief_<lang>.md files","status":"passed","title":"excludes executive-brief_<lang>.md files","duration":0.8748580000000175,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes pass1/ subdirectories","status":"passed","title":"excludes pass1/ subdirectories","duration":0.7861619999999903,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes data-download-manifest.md","status":"passed","title":"excludes data-download-manifest.md","duration":0.6283060000000091,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","findAnalysisMarkdownFiles"],"fullName":"check-analysis-language findAnalysisMarkdownFiles excludes full-text/ subdirectories (raw downloaded Swedish source material)","status":"passed","title":"excludes full-text/ subdirectories (raw downloaded Swedish source material)","duration":0.8219190000000367,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage passes for all-English artifacts","status":"passed","title":"passes for all-English artifacts","duration":0.9146420000000148,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage detects Swedish violations","status":"passed","title":"detects Swedish violations","duration":0.7239959999999996,"failureMessages":[],"location":{"line":229,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage always exempts executive-brief_sv.md","status":"passed","title":"always exempts executive-brief_sv.md","duration":0.6741719999999987,"failureMessages":[],"location":{"line":247,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage skips short snippets with few Swedish words","status":"passed","title":"skips short snippets with few Swedish words","duration":0.7241960000000063,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage ignores Swedish prose inside blockquote-attributed source quotations","status":"passed","title":"ignores Swedish prose inside blockquote-attributed source quotations","duration":0.8076020000000312,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage ignores verbatim Swedish source-title lines","status":"passed","title":"ignores verbatim Swedish source-title lines","duration":0.9434760000000324,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["check-analysis-language","validateAnalysisLanguage"],"fullName":"check-analysis-language validateAnalysisLanguage does NOT exempt bare `Title:` lines (only explicit source-attribution labels are exempted)","status":"passed","title":"does NOT exempt bare `Title:` lines (only explicit source-attribution labels are exempted)","duration":0.8353239999999573,"failureMessages":[],"location":{"line":318,"column":5},"meta":{},"tags":[]}],"startTime":1787953794789,"endTime":1787953794811.8352,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-analysis-language.test.ts"},{"assertionResults":[{"ancestorTitles":["check-brief-language — ENGLISH_MARKERS"],"fullName":"check-brief-language — ENGLISH_MARKERS contains unambiguous English function words","status":"passed","title":"contains unambiguous English function words","duration":3.8804870000000165,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — ENGLISH_MARKERS"],"fullName":"check-brief-language — ENGLISH_MARKERS excludes short ambiguous tokens that could appear in other languages","status":"passed","title":"excludes short ambiguous tokens that could appear in other languages","duration":0.6575010000000248,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity returns zero density for a Swedish brief","status":"passed","title":"returns zero density for a Swedish brief","duration":1.0335150000000226,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity detects high density when English fallback leaked into _sv.md","status":"passed","title":"detects high density when English fallback leaked into _sv.md","duration":0.724377000000004,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity strips fenced code blocks before measuring","status":"passed","title":"strips fenced code blocks before measuring","duration":0.41940599999998085,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — calculateEnglishDensity"],"fullName":"check-brief-language — calculateEnglishDensity strips Markdown blockquote lines (attributed source quotations)","status":"passed","title":"strips Markdown blockquote lines (attributed source quotations)","duration":0.49623900000000276,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns false when absolute marker count is below the floor","status":"passed","title":"returns false when absolute marker count is below the floor","duration":0.43036599999999225,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns true when density exceeds 5% on Latin targets","status":"passed","title":"returns true when density exceeds 5% on Latin targets","duration":0.5258450000000039,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold uses a tighter 3% threshold for CJK targets","status":"passed","title":"uses a tighter 3% threshold for CJK targets","duration":0.6747540000000072,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold uses a tighter 2% threshold for RTL targets (ar, he)","status":"passed","title":"uses a tighter 2% threshold for RTL targets (ar, he)","duration":0.4585379999999759,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — exceedsEnglishThreshold"],"fullName":"check-brief-language — exceedsEnglishThreshold returns false at exactly the threshold (strict >)","status":"passed","title":"returns false at exactly the threshold (strict >)","duration":0.4763719999999694,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages finds executive-brief_<lang>.md files and skips the English source","status":"passed","title":"finds executive-brief_<lang>.md files and skips the English source","duration":2.175845000000038,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages skips pass1/ and full-text/ subdirectories","status":"passed","title":"skips pass1/ and full-text/ subdirectories","duration":1.772718999999995,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages flags an English-fallback leak in _sv.md","status":"passed","title":"flags an English-fallback leak in _sv.md","duration":1.1059609999999793,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages passes a genuine Swedish translation","status":"passed","title":"passes a genuine Swedish translation","duration":0.7721059999999511,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages formats the violation report with relpath, lang, and density","status":"passed","title":"formats the violation report with relpath, lang, and density","duration":1.0951309999999808,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-brief-language — findTranslatedBriefs + validateBriefLanguages"],"fullName":"check-brief-language — findTranslatedBriefs + validateBriefLanguages returns empty report when no violations","status":"passed","title":"returns empty report when no violations","duration":0.47244499999999334,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]}],"startTime":1787953833458,"endTime":1787953833476.4724,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-brief-language.test.ts"},{"assertionResults":[{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 returns the first H1 after stripping YAML frontmatter","status":"passed","title":"returns the first H1 after stripping YAML frontmatter","duration":3.9386760000000436,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 returns null when there is no H1","status":"passed","title":"returns null when there is no H1","duration":0.6710269999999809,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 does not treat a body `---` thematic break as frontmatter","status":"passed","title":"does not treat a body `---` thematic break as frontmatter","duration":0.42947400000002744,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — extractH1"],"fullName":"check-headline-quality — extractH1 strips trailing whitespace from the H1","status":"passed","title":"strips trailing whitespace from the H1","duration":0.3690000000000282,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags definite-form party names","status":"passed","title":"flags definite-form party names","duration":1.2374070000000188,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags Tidö-coalition Swedish slugs","status":"passed","title":"flags Tidö-coalition Swedish slugs","duration":0.46458999999998696,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) flags untranslated political nouns","status":"passed","title":"flags untranslated political nouns","duration":0.4044579999999769,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag Riksdag / Regeringen — convention loans allowed in EN prose","status":"passed","title":"does NOT flag Riksdag / Regeringen — convention loans allowed in EN prose","duration":0.4804600000000505,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag English party-name forms","status":"passed","title":"does NOT flag English party-name forms","duration":0.4739270000000033,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule A (Swedish-in-EN H1)"],"fullName":"check-headline-quality — Rule A (Swedish-in-EN H1) does NOT flag bill / proposition IDs that contain digits","status":"passed","title":"does NOT flag bill / proposition IDs that contain digits","duration":0.48418600000002243,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) flags full weekday + day + month + year prefix","status":"passed","title":"flags full weekday + day + month + year prefix","duration":1.2063190000000077,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) flags abbreviated weekday + month prefix","status":"passed","title":"flags abbreviated weekday + month prefix","duration":0.5284889999999791,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) does NOT flag headlines that merely start with a weekday word (no date)","status":"passed","title":"does NOT flag headlines that merely start with a weekday word (no date)","duration":0.4755599999999731,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule B (weekday-date prefix)"],"fullName":"check-headline-quality — Rule B (weekday-date prefix) does NOT flag mid-sentence weekday references","status":"passed","title":"does NOT flag mid-sentence weekday references","duration":0.42673899999999776,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) flags ISO date at the start","status":"passed","title":"flags ISO date at the start","duration":0.5747860000000173,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) flags ISO date at the end after a separator","status":"passed","title":"flags ISO date at the end after a separator","duration":0.6929569999999785,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule C (ISO-date affix)"],"fullName":"check-headline-quality — Rule C (ISO-date affix) does NOT flag mid-sentence ISO dates","status":"passed","title":"does NOT flag mid-sentence ISO dates","duration":0.48357600000002776,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Executive Brief — prefix with leading emoji","status":"passed","title":"flags Executive Brief — prefix with leading emoji","duration":1.1108010000000377,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Realtime Monitor — prefix","status":"passed","title":"flags Realtime Monitor — prefix","duration":0.5085219999999708,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) flags Pass 2 and Methodology Reflection scaffolding","status":"passed","title":"flags Pass 2 and Methodology Reflection scaffolding","duration":0.7700219999999831,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule D (boilerplate prefix)"],"fullName":"check-headline-quality — Rule D (boilerplate prefix) does NOT flag headlines that mention \"brief\" mid-sentence","status":"passed","title":"does NOT flag headlines that mention \"brief\" mid-sentence","duration":0.47951799999998457,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) flags bare leaf-label H1 for shallow subfolder","status":"passed","title":"flags bare leaf-label H1 for shallow subfolder","duration":1.3239300000000185,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) flags full-path H1 for nested subfolder","status":"passed","title":"flags full-path H1 for nested subfolder","duration":0.6071769999999788,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) ignores trailing/leading whitespace and punctuation when matching","status":"passed","title":"ignores trailing/leading whitespace and punctuation when matching","duration":1.3073380000000157,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) does NOT flag a real actor+verb headline that mentions the category word","status":"passed","title":"does NOT flag a real actor+verb headline that mentions the category word","duration":0.7765640000000076,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) returns false when subfolder is missing","status":"passed","title":"returns false when subfolder is missing","duration":0.5735029999999597,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) prettifies multi-segment subfolder paths via space-join","status":"passed","title":"prettifies multi-segment subfolder paths via space-join","duration":0.5129200000000083,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) normaliseHeadlineForCompare strips punctuation and lowercases","status":"passed","title":"normaliseHeadlineForCompare strips punctuation and lowercases","duration":0.561540999999977,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) subfolderFromBriefPath extracts subfolder relative to analysis/daily/<date>","status":"passed","title":"subfolderFromBriefPath extracts subfolder relative to analysis/daily/<date>","duration":0.7465880000000311,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) subfolderFromBriefPath returns null for non-canonical paths","status":"passed","title":"subfolderFromBriefPath returns null for non-canonical paths","duration":0.5697759999999903,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) validateH1 wires Rule E with subfolder argument","status":"passed","title":"validateH1 wires Rule E with subfolder argument","duration":1.7460399999999936,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — Rule E (H1 equals prettified subfolder)"],"fullName":"check-headline-quality — Rule E (H1 equals prettified subfolder) validateH1 does not fire Rule E when subfolder is omitted","status":"passed","title":"validateH1 does not fire Rule E when subfolder is omitted","duration":0.5913869999999974,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) returns empty array for a clean editorial headline","status":"passed","title":"returns empty array for a clean editorial headline","duration":0.6557180000000358,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) returns multiple issues when several rules fire","status":"passed","title":"returns multiple issues when several rules fire","duration":0.7528599999999983,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) flags weekday-date-prefix + scaffolding combination","status":"passed","title":"flags weekday-date-prefix + scaffolding combination","duration":0.6986780000000294,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-headline-quality — validateH1 (integration)"],"fullName":"check-headline-quality — validateH1 (integration) passes a real editorial headline from the repository","status":"passed","title":"passes a real editorial headline from the repository","duration":0.5759090000000242,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]}],"startTime":1787953827825,"endTime":1787953827854.576,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-headline-quality.test.ts"},{"assertionResults":[{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs passes on the current committed state (14 sources ↔ 14 triggers ↔ 14 slug branches)","status":"passed","title":"passes on the current committed state (14 sources ↔ 14 triggers ↔ 14 slug branches)","duration":48.06778499999996,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs fails when a workflow name is mistyped in the fallback yml (the Translate Articles regression)","status":"passed","title":"fails when a workflow name is mistyped in the fallback yml (the Translate Articles regression)","duration":41.953484,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["check-pat-fallback-coverage.mjs"],"fullName":"check-pat-fallback-coverage.mjs fails when a news-*.md is added without a matching trigger entry","status":"passed","title":"fails when a news-*.md is added without a matching trigger entry","duration":42.41301400000003,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953904850,"endTime":1787953904982.413,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/check-pat-fallback-coverage.test.ts"},{"assertionResults":[{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation types are importable (TypeScript compile check)","status":"passed","title":"types are importable (TypeScript compile check)","duration":3.7017809999999827,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation helpers.ts exports depth, renderHreflangBlock, fallbackAlternateHref","status":"passed","title":"helpers.ts exports depth, renderHreflangBlock, fallbackAlternateHref","duration":0.619199999999978,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation head.ts exports renderChromeHead","status":"passed","title":"head.ts exports renderChromeHead","duration":0.504052999999999,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation header.ts exports buildHeaderHtml","status":"passed","title":"header.ts exports buildHeaderHtml","duration":0.4038760000000252,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ sub-module isolation"],"fullName":"chrome/ sub-module isolation footer.ts exports buildFooterHtml","status":"passed","title":"footer.ts exports buildFooterHtml","duration":0.44962199999997665,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns empty string for root-level files","status":"passed","title":"returns empty string for root-level files","duration":0.5207839999999919,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns ../ for one level deep","status":"passed","title":"returns ../ for one level deep","duration":0.45639399999998886,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() returns ../../ for two levels deep","status":"passed","title":"returns ../../ for two levels deep","duration":0.3391250000000241,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — depth()"],"fullName":"chrome/helpers — depth() strips leading slashes before computing depth","status":"passed","title":"strips leading slashes before computing depth","duration":0.5461129999999912,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — fallbackAlternateHref()"],"fullName":"chrome/helpers — fallbackAlternateHref() returns base unchanged for English","status":"passed","title":"returns base unchanged for English","duration":0.44986299999999346,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — fallbackAlternateHref()"],"fullName":"chrome/helpers — fallbackAlternateHref() appends _lang suffix for non-English","status":"passed","title":"appends _lang suffix for non-English","duration":0.4741180000000327,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() emits canonical + self alternate when no alternates provided","status":"passed","title":"emits canonical + self alternate when no alternates provided","duration":0.7048699999999712,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() emits all provided alternates + x-default","status":"passed","title":"emits all provided alternates + x-default","duration":0.6207829999999603,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/helpers — renderHreflangBlock()"],"fullName":"chrome/helpers — renderHreflangBlock() uses English alternate as x-default","status":"passed","title":"uses English alternate as x-default","duration":0.4439610000000016,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure starts with <!DOCTYPE html>","status":"passed","title":"starts with <!DOCTYPE html>","duration":1.1833260000000223,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure includes <html lang=\"…\" dir=\"…\">","status":"passed","title":"includes <html lang=\"…\" dir=\"…\">","duration":0.43175899999999956,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure sets dir=\"rtl\" for Arabic","status":"passed","title":"sets dir=\"rtl\" for Arabic","duration":0.3990180000000123,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure sets dir=\"rtl\" for Hebrew","status":"passed","title":"sets dir=\"rtl\" for Hebrew","duration":0.5177290000000312,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure includes charset and viewport meta","status":"passed","title":"includes charset and viewport meta","duration":0.49735099999998056,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — HTML5 structure"],"fullName":"chrome/head — HTML5 structure closes with </head>","status":"passed","title":"closes with </head>","duration":0.5961260000000266,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes branded title with Riksdagsmonitor suffix","status":"passed","title":"includes branded title with Riksdagsmonitor suffix","duration":0.5880810000000452,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags does not double-brand when title contains Riksdagsmonitor","status":"passed","title":"does not double-brand when title contains Riksdagsmonitor","duration":0.6473219999999742,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes OpenGraph meta tags","status":"passed","title":"includes OpenGraph meta tags","duration":0.7359680000000139,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes Twitter Card meta tags","status":"passed","title":"includes Twitter Card meta tags","duration":0.6029780000000073,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags suppresses article meta when ogType is website","status":"passed","title":"suppresses article meta when ogType is website","duration":0.5683539999999994,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — SEO meta tags"],"fullName":"chrome/head — SEO meta tags includes article:published_time for article type","status":"passed","title":"includes article:published_time for article type","duration":0.5686850000000163,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — JSON-LD"],"fullName":"chrome/head — JSON-LD renders JSON-LD blocks in script tags","status":"passed","title":"renders JSON-LD blocks in script tags","duration":0.6444859999999721,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — JSON-LD"],"fullName":"chrome/head — JSON-LD escapes < in JSON-LD to prevent XSS","status":"passed","title":"escapes < in JSON-LD to prevent XSS","duration":0.602346999999952,"failureMessages":[],"location":{"line":262,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility includes skip-link targeting #main","status":"passed","title":"includes skip-link targeting #main","duration":1.5314979999999991,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility header has role=\"banner\"","status":"passed","title":"header has role=\"banner\"","duration":0.6404790000000276,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility main content area has tabindex=\"-1\" for programmatic focus","status":"passed","title":"main content area has tabindex=\"-1\" for programmatic focus","duration":0.6894110000000069,"failureMessages":[],"location":{"line":289,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility breadcrumb nav has aria-label","status":"passed","title":"breadcrumb nav has aria-label","duration":0.8475369999999884,"failureMessages":[],"location":{"line":294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility last breadcrumb item has aria-current=\"page\"","status":"passed","title":"last breadcrumb item has aria-current=\"page\"","duration":0.7060020000000122,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — accessibility"],"fullName":"chrome/header — accessibility language switcher dropdown items have role=\"menuitem\"","status":"passed","title":"language switcher dropdown items have role=\"menuitem\"","duration":0.7596729999999638,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling renders dir=\"rtl\" in <html> for ar","status":"passed","title":"renders dir=\"rtl\" in <html> for ar","duration":0.6045819999999935,"failureMessages":[],"location":{"line":319,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling header renders correctly for ar","status":"passed","title":"header renders correctly for ar","duration":0.7649420000000191,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling footer renders correctly for ar","status":"passed","title":"footer renders correctly for ar","duration":1.2368960000000015,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling renders dir=\"rtl\" in <html> for he","status":"passed","title":"renders dir=\"rtl\" in <html> for he","duration":0.7023659999999836,"failureMessages":[],"location":{"line":319,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling header renders correctly for he","status":"passed","title":"header renders correctly for he","duration":0.7290050000000292,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/ — RTL language handling"],"fullName":"chrome/ — RTL language handling footer renders correctly for he","status":"passed","title":"footer renders correctly for he","duration":0.7268709999999601,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher header dropdown contains 13 language links (all except current)","status":"passed","title":"header dropdown contains 13 language links (all except current)","duration":1.6770500000000084,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher horizontal language bar contains all 14 languages (1 current + 13 links)","status":"passed","title":"horizontal language bar contains all 14 languages (1 current + 13 links)","duration":1.138272000000029,"failureMessages":[],"location":{"line":348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — language switcher"],"fullName":"chrome/header — language switcher uses explicit hreflangAlternates when provided","status":"passed","title":"uses explicit hreflangAlternates when provided","duration":0.8495100000000093,"failureMessages":[],"location":{"line":359,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes role=\"contentinfo\"","status":"passed","title":"includes role=\"contentinfo\"","duration":0.7596320000000105,"failureMessages":[],"location":{"line":377,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes ISMS section with policies","status":"passed","title":"includes ISMS section with policies","duration":0.8070410000000265,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes trust badges with external links","status":"passed","title":"includes trust badges with external links","duration":0.8118100000000368,"failureMessages":[],"location":{"line":388,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes secondary language row","status":"passed","title":"includes secondary language row","duration":0.7627790000000232,"failureMessages":[],"location":{"line":394,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes copyright with current year","status":"passed","title":"includes copyright with current year","duration":0.7937659999998914,"failureMessages":[],"location":{"line":399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure closes with </body></html>","status":"passed","title":"closes with </body></html>","duration":0.9983690000000252,"failureMessages":[],"location":{"line":404,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/footer — structure"],"fullName":"chrome/footer — structure includes Mermaid/theme bootstrap scripts","status":"passed","title":"includes Mermaid/theme bootstrap scripts","duration":3.960739999999987,"failureMessages":[],"location":{"line":410,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts façade — buildChrome"],"fullName":"chrome.ts façade — buildChrome returns head/headerHtml/footerHtml matching sub-module outputs","status":"passed","title":"returns head/headerHtml/footerHtml matching sub-module outputs","duration":1.0739609999999402,"failureMessages":[],"location":{"line":423,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts façade — buildChrome"],"fullName":"chrome.ts façade — buildChrome façade renderChromeHead matches sub-module renderChromeHead","status":"passed","title":"façade renderChromeHead matches sub-module renderChromeHead","duration":0.7141870000000381,"failureMessages":[],"location":{"line":431,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — hreflang for all 14 languages"],"fullName":"chrome/head — hreflang for all 14 languages emits hreflang link for each provided alternate","status":"passed","title":"emits hreflang link for each provided alternate","duration":0.9255529999999226,"failureMessages":[],"location":{"line":442,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner includes hero banner by default","status":"passed","title":"includes hero banner by default","duration":0.7891070000000582,"failureMessages":[],"location":{"line":465,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner excludes hero banner when heroBanner=false","status":"passed","title":"excludes hero banner when heroBanner=false","duration":0.6900920000000497,"failureMessages":[],"location":{"line":474,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/header — hero banner"],"fullName":"chrome/header — hero banner uses custom banner image when provided","status":"passed","title":"uses custom banner image when provided","duration":0.7423800000000256,"failureMessages":[],"location":{"line":480,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next includes rel=prev when relPrev provided","status":"passed","title":"includes rel=prev when relPrev provided","duration":0.7188050000000885,"failureMessages":[],"location":{"line":492,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next includes rel=next when relNext provided","status":"passed","title":"includes rel=next when relNext provided","duration":0.8012600000000702,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome/head — rel prev/next"],"fullName":"chrome/head — rel prev/next omits pagination links when neither relPrev nor relNext provided","status":"passed","title":"omits pagination links when neither relPrev nor relNext provided","duration":0.7451049999999668,"failureMessages":[],"location":{"line":505,"column":3},"meta":{},"tags":[]}],"startTime":1787953683396,"endTime":1787953683445.745,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-decomposition.test.ts"},{"assertionResults":[{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) includes the section header comment that introduces the block","status":"passed","title":"includes the section header comment that introduces the block","duration":3.635226999999986,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) uses :where() to target both header families with controlled specificity","status":"passed","title":"uses :where() to target both header families with controlled specificity","duration":0.76543300000003,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) uses :where() to target both footer families with controlled specificity","status":"passed","title":"uses :where() to target both footer families with controlled specificity","duration":0.646049000000005,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) harmonises both theme-toggle button variants","status":"passed","title":"harmonises both theme-toggle button variants","duration":0.5622030000000109,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) harmonises both language-switcher variants","status":"passed","title":"harmonises both language-switcher variants","duration":0.5748869999999897,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) makes both header families sticky at the top","status":"passed","title":"makes both header families sticky at the top","duration":0.8301040000000057,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) provides explicit light-mode polish for the header (rgba glass + cyan border)","status":"passed","title":"provides explicit light-mode polish for the header (rgba glass + cyan border)","duration":0.7385229999999865,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) enforces WCAG 2.5.5 touch targets (≥ 44×44) on mobile","status":"passed","title":"enforces WCAG 2.5.5 touch targets (≥ 44×44) on mobile","duration":0.6308210000000258,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) declares a visible :focus-visible outline using the cyan token","status":"passed","title":"declares a visible :focus-visible outline using the cyan token","duration":0.7643720000000371,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) wraps hover transforms inside prefers-reduced-motion: no-preference","status":"passed","title":"wraps hover transforms inside prefers-reduced-motion: no-preference","duration":0.40695299999998724,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-family chrome harmonisation block (styles.css)"],"fullName":"Cross-family chrome harmonisation block (styles.css) does not introduce any !important declarations in the harmonisation block","status":"passed","title":"does not introduce any !important declarations in the harmonisation block","duration":0.7016840000000002,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]}],"startTime":1787953907761,"endTime":1787953907770.7017,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-harmonisation.test.js"},{"assertionResults":[{"ancestorTitles":["chrome-i18n — hero & header-tagline keys"],"fullName":"chrome-i18n — hero & header-tagline keys defines every new key for every supported language","status":"passed","title":"defines every new key for every supported language","duration":9.101833,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — hero & header-tagline keys"],"fullName":"chrome-i18n — hero & header-tagline keys translates non-English values (no copy-paste of English strings)","status":"passed","title":"translates non-English values (no copy-paste of English strings)","duration":4.609591000000023,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language renders Swedish tagline for sv chrome","status":"passed","title":"renders Swedish tagline for sv chrome","duration":3.7609319999999684,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language renders Arabic tagline for ar chrome (RTL)","status":"passed","title":"renders Arabic tagline for ar chrome (RTL)","duration":0.8866799999999557,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — header tagline reflects language"],"fullName":"chrome.ts — header tagline reflects language keeps the English tagline for en chrome","status":"passed","title":"keeps the English tagline for en chrome","duration":0.7594019999999659,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys defines every new CTA/ecosystem key for every supported language","status":"passed","title":"defines every new CTA/ecosystem key for every supported language","duration":2.493268999999998,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys translates non-English CTA/ecosystem values (differ from English)","status":"passed","title":"translates non-English CTA/ecosystem values (differ from English)","duration":1.7177659999999833,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders Political Intelligence CTA in header","status":"passed","title":"renders Political Intelligence CTA in header","duration":0.8114590000000135,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders EU Parliament Monitor link in footer","status":"passed","title":"renders EU Parliament Monitor link in footer","duration":0.8792459999999664,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders Hack23 Blog link in footer","status":"passed","title":"renders Hack23 Blog link in footer","duration":0.7514370000000099,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome-i18n — Political Intelligence CTA & ecosystem keys"],"fullName":"chrome-i18n — Political Intelligence CTA & ecosystem keys renders translated Political Intelligence CTA for Swedish","status":"passed","title":"renders translated Political Intelligence CTA for Swedish","duration":0.774610999999993,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]}],"startTime":1787953865399,"endTime":1787953865425.7747,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-i18n-hero.test.ts"},{"assertionResults":[{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission emits FAQPage JSON-LD when ≥2 faqItems are supplied","status":"passed","title":"emits FAQPage JSON-LD when ≥2 faqItems are supplied","duration":8.076101999999992,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission does NOT emit FAQPage JSON-LD when only 1 faqItem is supplied","status":"passed","title":"does NOT emit FAQPage JSON-LD when only 1 faqItem is supplied","duration":1.1106100000000083,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — FAQPage auto-emission"],"fullName":"chrome.ts — FAQPage auto-emission does NOT emit FAQPage JSON-LD when faqItems is empty","status":"passed","title":"does NOT emit FAQPage JSON-LD when faqItems is empty","duration":0.83271000000002,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) falls back to the page title when description is an empty string","status":"passed","title":"falls back to the page title when description is an empty string","duration":0.9691040000000157,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) falls back to the page title when description is whitespace only","status":"passed","title":"falls back to the page title when description is whitespace only","duration":0.8276299999999992,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — meta description never empty (SEO guard)"],"fullName":"chrome.ts — meta description never empty (SEO guard) keeps a supplied non-empty description unchanged","status":"passed","title":"keeps a supplied non-empty description unchanged","duration":0.676085999999998,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge merges speakable into an existing WebPage node without duplication","status":"passed","title":"merges speakable into an existing WebPage node without duplication","duration":1.0194680000000176,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge does NOT mutate the caller-provided jsonLd objects","status":"passed","title":"does NOT mutate the caller-provided jsonLd objects","duration":1.207080000000019,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — WebPage speakable merge"],"fullName":"chrome.ts — WebPage speakable merge emits a standalone WebPage node when no existing one is present","status":"passed","title":"emits a standalone WebPage node when no existing one is present","duration":0.8189629999999966,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links emits <link rel=\"next\"> when relNext is provided","status":"passed","title":"emits <link rel=\"next\"> when relNext is provided","duration":0.7400559999999814,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links emits <link rel=\"prev\"> when relPrev is provided","status":"passed","title":"emits <link rel=\"prev\"> when relPrev is provided","duration":1.007316000000003,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links HTML-escapes relNext/relPrev hrefs","status":"passed","title":"HTML-escapes relNext/relPrev hrefs","duration":0.9190609999999992,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts — rel=prev/next pagination links"],"fullName":"chrome.ts — rel=prev/next pagination links does not emit pagination links when neither relPrev nor relNext is provided","status":"passed","title":"does not emit pagination links when neither relPrev nor relNext is provided","duration":0.6424729999999954,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]}],"startTime":1787953856849,"endTime":1787953856868.6426,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/chrome-seo-features.test.ts"},{"assertionResults":[{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv file exists on disk","status":"passed","title":"file exists on disk","duration":3.9455879999999866,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.4007030000000213,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_performance.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_performance.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7629680000000008,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4299340000000029,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5348710000000096,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_effectiveness_trends.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_effectiveness_trends.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6030189999999607,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.46998000000002094,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5302429999999845,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_party_momentum.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_party_momentum.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6483139999999707,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.43393300000002455,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6806149999999889,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_coalition_alignment.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_coalition_alignment.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.38481000000001586,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.42328199999997196,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.44426100000004,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: parties","/cia-data/party/distribution_annual_party_members.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: parties /cia-data/party/distribution_annual_party_members.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6091600000000312,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6931680000000142,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6431539999999814,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_behavioral_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_behavioral_patterns_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.40351600000002463,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4417879999999741,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.47656200000000126,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/parties/distribution_decision_patterns_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/parties/distribution_decision_patterns_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5715200000000209,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4962489999999775,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5737349999999992,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: coalitions","/cia-data/anomaly/distribution_anomaly_by_party.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: coalitions /cia-data/anomaly/distribution_anomaly_by_party.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5655680000000416,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4654019999999832,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5556399999999826,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_committee_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_committee_productivity_matrix.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5541169999999624,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5072999999999865,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5908060000000432,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: committees","/cia-data/distribution_annual_committee_documents.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: committees /cia-data/distribution_annual_committee_documents.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7168720000000235,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.675926000000004,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5885729999999967,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_comparative_analysis_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5109469999999874,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5303930000000037,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.6214240000000473,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_decision_intelligence_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6395480000000475,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5359340000000543,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5733629999999721,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_predictive_intelligence_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.566159999999968,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5481770000000097,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.8044360000000097,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: election-cycle","/cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: election-cycle /cia-data/election-cycle/view_election_cycle_temporal_trends_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7070940000000405,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5756079999999884,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.694500000000005,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: seasonal-patterns","/cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: seasonal-patterns /cia-data/seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":4.9208830000000034,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5689750000000231,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5029419999999618,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5186710000000403,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.4751499999999851,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5397000000000389,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: pre-election","/cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: pre-election /cia-data/pre-election/view_riksdagen_q4_election_year_comparison_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5001869999999826,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5103050000000167,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5234399999999937,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: anomaly-detection","/cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: anomaly-detection /cia-data/seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.5627439999999524,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.5187109999999961,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.5961970000000179,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_productivity_matrix.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_productivity_matrix.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.593071000000009,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8278700000000185,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.0407490000000053,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_levels.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_levels.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7154899999999884,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6533729999999878,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.73753099999999,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_decision_impact.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_decision_impact.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.6646349999999757,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.6760659999999916,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.718685999999991,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_effectiveness.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_effectiveness.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.7192759999999794,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.7031560000000354,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.7944269999999847,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/distribution_ministry_risk_quarterly.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/distribution_ministry_risk_quarterly.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.8007489999999962,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.779640000000029,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.858887999999979,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/politician/view_riksdagen_politician_influence_metrics_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.8452329999999506,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8642380000000003,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.9099340000000211,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_productivity_matrix_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_productivity_matrix_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.005262000000016,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":0.8908480000000054,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":0.9827610000000391,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: ministers","/cia-data/ministry/view_ministry_risk_evolution_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: ministers /cia-data/ministry/view_ministry_risk_evolution_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":0.9378360000000043,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.0867150000000265,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.1716940000000022,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: risk","/cia-data/politician/view_politician_risk_summary_sample.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: risk /cia-data/politician/view_politician_risk_summary_sample.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.1836669999999572,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.4920740000000023,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.7677099999999655,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/election_forecast.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/election_forecast.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.1488509999999792,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv file exists on disk","status":"passed","title":"file exists on disk","duration":1.0449859999999944,"failureMessages":[],"location":{"line":48,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv header row contains every required column (no legacy column fallbacks)","status":"passed","title":"header row contains every required column (no legacy column fallbacks)","duration":1.0803429999999707,"failureMessages":[],"location":{"line":55,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — every dashboard CSV has its declared canonical schema","dashboard: cia-hub","/cia-data/election/coalition_scenarios.csv"],"fullName":"CSV contracts — every dashboard CSV has its declared canonical schema dashboard: cia-hub /cia-data/election/coalition_scenarios.csv has at least 1 data row(s)","status":"passed","title":"has at least 1 data row(s)","duration":1.151365999999939,"failureMessages":[],"location":{"line":65,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity every contract path is absolute and starts with /cia-data/","status":"passed","title":"every contract path is absolute and starts with /cia-data/","duration":1.8177230000000009,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity no contract has duplicate column entries","status":"passed","title":"no contract has duplicate column entries","duration":1.7745319999999083,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CSV contracts — registry sanity"],"fullName":"CSV contracts — registry sanity no two contracts share the same path","status":"passed","title":"no two contracts share the same path","duration":1.2162069999999403,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]}],"startTime":1787953905875,"endTime":1787953905950.2163,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-csv-contracts.test.ts"},{"assertionResults":[{"ancestorTitles":["csv-validator: CsvContractError"],"fullName":"csv-validator: CsvContractError exposes structured fields on the error instance","status":"passed","title":"exposes structured fields on the error instance","duration":5.315502999999978,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) returns rows unchanged when all required columns and minRows are satisfied","status":"passed","title":"returns rows unchanged when all required columns and minRows are satisfied","duration":0.7767939999999953,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError when a required column is missing from the header","status":"passed","title":"throws CsvContractError when a required column is missing from the header","duration":0.8664120000000253,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError when row count is below minRows","status":"passed","title":"throws CsvContractError when row count is below minRows","duration":0.587771000000032,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) throws CsvContractError on zero rows (header keys unknown)","status":"passed","title":"throws CsvContractError on zero rows (header keys unknown)","duration":0.7961310000000026,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (override contract)"],"fullName":"csv-validator: validateCsvRows (override contract) defaults minRows to 1 when contract omits the field","status":"passed","title":"defaults minRows to 1 when contract omits the field","duration":1.3488849999999957,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (registered contract)"],"fullName":"csv-validator: validateCsvRows (registered contract) uses getCsvContract lookup when no override contract is supplied","status":"passed","title":"uses getCsvContract lookup when no override contract is supplied","duration":0.5498900000000049,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRows (registered contract)"],"fullName":"csv-validator: validateCsvRows (registered contract) returns input unchanged when no contract is registered for the path","status":"passed","title":"returns input unchanged when no contract is registered for the path","duration":0.4008209999999508,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRowsLenient"],"fullName":"csv-validator: validateCsvRowsLenient returns true and does not log when the contract is satisfied","status":"passed","title":"returns true and does not log when the contract is satisfied","duration":0.8163580000000366,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["csv-validator: validateCsvRowsLenient"],"fullName":"csv-validator: validateCsvRowsLenient returns false and logs to console.error on CsvContractError","status":"passed","title":"returns false and logs to console.error on CsvContractError","duration":0.7389429999999493,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]}],"startTime":1787953865892,"endTime":1787953865905.739,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-csv-validator.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract uses explicit imports so production tree shaking keeps the dashboard bootstrap","status":"passed","title":"uses explicit imports so production tree shaking keeps the dashboard bootstrap","duration":3.8500490000000127,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract keeps bootstrap ownership explicit without module import side effects","status":"passed","title":"keeps bootstrap ownership explicit without module import side effects","duration":0.8196849999999927,"failureMessages":[],"location":{"line":14,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract marks only the source entry bootstrap as side-effectful for the app build","status":"passed","title":"marks only the source entry bootstrap as side-effectful for the app build","duration":2.117775999999992,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA dashboard production entry contract"],"fullName":"CIA dashboard production entry contract keeps the bootstrap import on the first line of executable code in cia-entry","status":"passed","title":"keeps the bootstrap import on the first line of executable code in cia-entry","duration":0.6581919999999855,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]}],"startTime":1787953916575,"endTime":1787953916582.6582,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-dashboard-entry-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections uses coalition alignment CSV when available","status":"passed","title":"uses coalition alignment CSV when available","duration":8.161090000000002,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections falls back to win-rate similarity when coalition alignment CSV is unavailable","status":"passed","title":"falls back to win-rate similarity when coalition alignment CSV is unavailable","duration":1.5599109999999996,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses and filters ministry dashboard rows","status":"passed","title":"parses and filters ministry dashboard rows","duration":2.961023999999952,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses demographics and keeps only Riksdag parties","status":"passed","title":"parses demographics and keeps only Riksdag parties","duration":1.5627860000000169,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader dashboard sections"],"fullName":"CIADataLoader dashboard sections parses document activity and risk evolution with zero-row filtering","status":"passed","title":"parses document activity and risk evolution with zero-row filtering","duration":1.7073369999999954,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]}],"startTime":1787953890903,"endTime":1787953890918.7073,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-dashboard-sections.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should build election analysis from CSV sources","status":"passed","title":"should build election analysis from CSV sources","duration":8.63455700000003,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should parse party forecast data correctly","status":"passed","title":"should parse party forecast data correctly","duration":1.8333719999999971,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop confidenceInterval when CSV cells are empty strings","status":"passed","title":"should drop confidenceInterval when CSV cells are empty strings","duration":0.7626580000000445,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop forecast rows with non-numeric required fields","status":"passed","title":"should drop forecast rows with non-numeric required fields","duration":0.8521959999999922,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should parse coalition scenarios correctly","status":"passed","title":"should parse coalition scenarios correctly","duration":1.5094569999999976,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop coalition rows with non-numeric required fields","status":"passed","title":"should drop coalition rows with non-numeric required fields","duration":0.9155739999999923,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should drop coalition rows with invalid majority and empty risk level","status":"passed","title":"should drop coalition rows with invalid majority and empty risk level","duration":1.2068700000000376,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","loadElectionAnalysis (CSV-based)"],"fullName":"CIADataLoader loadElectionAnalysis (CSV-based) should return empty parties when CSV fetch fails","status":"passed","title":"should return empty parties when CSV fetch fails","duration":0.7190760000000296,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","CSV_SOURCES"],"fullName":"CIADataLoader CSV_SOURCES should include election forecast and coalition scenarios","status":"passed","title":"should include election forecast and coalition scenarios","duration":0.511667999999986,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader","election analysis source behavior"],"fullName":"CIADataLoader election analysis source behavior should request election CSV files and never request election-analysis.json","status":"passed","title":"should request election CSV files and never request election-analysis.json","duration":0.9079499999999712,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]}],"startTime":1787953834876,"endTime":1787953834893.908,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-election.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator exposes the same constants and CSV_SOURCES as the extracted modules","status":"passed","title":"exposes the same constants and CSV_SOURCES as the extracted modules","duration":4.645118000000025,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV delegates to the shared helper","status":"passed","title":"parseCSV delegates to the shared helper","duration":3.059248000000025,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV handles quoted commas and multiline fields from larger CIA exports","status":"passed","title":"parseCSV handles quoted commas and multiline fields from larger CIA exports","duration":0.8896460000000275,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator parseCSV normalizes headers and surfaces malformed CSV errors","status":"passed","title":"parseCSV normalizes headers and surfaces malformed CSV errors","duration":1.6349909999999568,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadCSV uses the configured base URL and fallback URL","status":"passed","title":"loadCSV uses the configured base URL and fallback URL","duration":1.2904660000000376,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadCSV recovers from network errors and warns on full failure","status":"passed","title":"loadCSV recovers from network errors and warns on full failure","duration":0.9814269999999965,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadAll wires up every per-domain loader","status":"passed","title":"loadAll wires up every per-domain loader","duration":1.2690259999999967,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIADataLoader orchestrator"],"fullName":"CIADataLoader orchestrator loadPartyPerformance and loadTop10Influential delegate to the loader modules","status":"passed","title":"loadPartyPerformance and loadTop10Influential delegate to the loader modules","duration":2.9491120000000137,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]}],"startTime":1787953867697,"endTime":1787953867713.9492,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-data-loader-orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadOverviewDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadOverviewDashboard aggregates active MP, party and risk totals","status":"passed","title":"aggregates active MP, party and risk totals","duration":7.841072999999994,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadOverviewDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadOverviewDashboard falls back to defaults when CSV sources are empty","status":"passed","title":"falls back to defaults when CSV sources are empty","duration":0.5947039999999788,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadElectionAnalysis"],"fullName":"CIA per-domain loaders (extracted modules) loadElectionAnalysis parses forecast and scenarios from CSV inputs","status":"passed","title":"parses forecast and scenarios from CSV inputs","duration":3.2843599999999924,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadVotingPatterns"],"fullName":"CIA per-domain loaders (extracted modules) loadVotingPatterns uses real coalition alignment data when available","status":"passed","title":"uses real coalition alignment data when available","duration":1.206249000000014,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadMinistryDashboard"],"fullName":"CIA per-domain loaders (extracted modules) loadMinistryDashboard sorts ministries by documents produced and filters zero rows","status":"passed","title":"sorts ministries by documents produced and filters zero rows","duration":1.050247000000013,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadDemographics"],"fullName":"CIA per-domain loaders (extracted modules) loadDemographics keeps only the 8 Riksdag parties","status":"passed","title":"keeps only the 8 Riksdag parties","duration":1.1753709999999842,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadDocumentActivity"],"fullName":"CIA per-domain loaders (extracted modules) loadDocumentActivity drops zero-count rows for both document types and decisions","status":"passed","title":"drops zero-count rows for both document types and decisions","duration":1.154642000000024,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadRiskEvolution"],"fullName":"CIA per-domain loaders (extracted modules) loadRiskEvolution emits temporal risk entries with zero filtering","status":"passed","title":"emits temporal risk entries with zero filtering","duration":0.8705899999999929,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadCommitteeNetwork"],"fullName":"CIA per-domain loaders (extracted modules) loadCommitteeNetwork filters inactive committees with no measured output","status":"passed","title":"filters inactive committees with no measured output","duration":1.6591870000000313,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadPartyPerformance"],"fullName":"CIA per-domain loaders (extracted modules) loadPartyPerformance joins performance, metrics and momentum and sorts by seats","status":"passed","title":"joins performance, metrics and momentum and sorts by seats","duration":1.4610959999999977,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","loadTop10Influential"],"fullName":"CIA per-domain loaders (extracted modules) loadTop10Influential ranks MPs by network connections and joins risk data","status":"passed","title":"ranks MPs by network connections and joins risk data","duration":1.3274260000000027,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","createLoadCSV"],"fullName":"CIA per-domain loaders (extracted modules) createLoadCSV builds a working closure bound to URLs","status":"passed","title":"builds a working closure bound to URLs","duration":0.9237300000000346,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/ + foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/ + foo.csv -> /base/foo.csv","duration":0.4915009999999711,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base + foo.csv -> /base/foo.csv","status":"passed","title":"joins /base + foo.csv -> /base/foo.csv","duration":0.3769060000000195,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/ + /foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/ + /foo.csv -> /base/foo.csv","duration":0.480419999999981,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base + /foo.csv -> /base/foo.csv","status":"passed","title":"joins /base + /foo.csv -> /base/foo.csv","duration":0.41618900000003123,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins /base/// + ///foo.csv -> /base/foo.csv","status":"passed","title":"joins /base/// + ///foo.csv -> /base/foo.csv","duration":0.4747590000000059,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins ../cia-data/ + voting/x.csv -> ../cia-data/voting/x.csv","status":"passed","title":"joins ../cia-data/ + voting/x.csv -> ../cia-data/voting/x.csv","duration":0.397213000000022,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins https://host.example/path/ + x.csv -> https://host.example/path/x.csv","status":"passed","title":"joins https://host.example/path/ + x.csv -> https://host.example/path/x.csv","duration":0.42384299999997666,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL joins https://host.example/path + x.csv -> https://host.example/path/x.csv","status":"passed","title":"joins https://host.example/path + x.csv -> https://host.example/path/x.csv","duration":0.4458750000000009,"failureMessages":[],"location":{"line":317,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL returns the path when base is empty","status":"passed","title":"returns the path when base is empty","duration":0.5210759999999937,"failureMessages":[],"location":{"line":321,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIA per-domain loaders (extracted modules)","joinURL"],"fullName":"CIA per-domain loaders (extracted modules) joinURL returns the base when path is empty","status":"passed","title":"returns the base when path is empty","duration":0.45157599999998865,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]}],"startTime":1787953808885,"endTime":1787953808913.4517,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-loaders.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration exposes a non-empty local path and description for every CSV source","status":"passed","title":"exposes a non-empty local path and description for every CSV source","duration":5.859040999999991,"failureMessages":[],"location":{"line":10,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration uses unique local paths across all sources","status":"passed","title":"uses unique local paths across all sources","duration":0.5655790000000138,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration declares the 8 Swedish Riksdag parties","status":"passed","title":"declares the 8 Swedish Riksdag parties","duration":1.102354000000048,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration maps committee names to short org codes","status":"passed","title":"maps committee names to short org codes","duration":0.4724050000000375,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration exposes a positive committee meetings divisor","status":"passed","title":"exposes a positive committee meetings divisor","duration":0.5141619999999989,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CIA sources configuration"],"fullName":"CIA sources configuration deep-freezes the shared source inventory so consumers cannot mutate it","status":"passed","title":"deep-freezes the shared source inventory so consumers cannot mutate it","duration":0.9006559999999695,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953924296,"endTime":1787953924305.9006,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/cia-sources.test.ts"},{"assertionResults":[{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have coalition dashboard section","status":"passed","title":"should have coalition dashboard section","duration":10.454502999999988,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.4135879999999474,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":1.9787750000000415,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have D3.js visualization containers","status":"passed","title":"should have D3.js visualization containers","duration":1.8419289999999933,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have wide chart cards","status":"passed","title":"should have wide chart cards","duration":4.069899000000021,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","DOM Structure"],"fullName":"Coalition Dashboard DOM Structure should have data attribution","status":"passed","title":"should have data attribution","duration":2.8794809999999984,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have ARIA labels on D3 containers","status":"passed","title":"should have ARIA labels on D3 containers","duration":2.2855090000000473,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have accessible fallback table for network","status":"passed","title":"should have accessible fallback table for network","duration":1.8975730000000226,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have table caption","status":"passed","title":"should have table caption","duration":2.8904210000000035,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Accessibility"],"fullName":"Coalition Dashboard Accessibility should have proper heading hierarchy","status":"passed","title":"should have proper heading hierarchy","duration":1.8196169999999938,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should configure local-first URLs for all CSV files","status":"passed","title":"should configure local-first URLs for all CSV files","duration":2.158811999999955,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should use local paths starting with cia-data/","status":"passed","title":"should use local paths starting with cia-data/","duration":2.4612879999999677,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Data Source Configuration"],"fullName":"Coalition Dashboard Data Source Configuration should have remote fallback URLs for all files","status":"passed","title":"should have remote fallback URLs for all files","duration":2.5325109999999995,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse behavioral patterns CSV with real columns","status":"passed","title":"should parse behavioral patterns CSV with real columns","duration":2.4530429999999797,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse annual party votes CSV with real columns","status":"passed","title":"should parse annual party votes CSV with real columns","duration":4.121165000000019,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse decision trends CSV with real columns","status":"passed","title":"should parse decision trends CSV with real columns","duration":1.1980429999999842,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should parse decision patterns CSV with real columns","status":"passed","title":"should parse decision patterns CSV with real columns","duration":1.1935750000000098,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should calculate alignment scores between parties","status":"passed","title":"should calculate alignment scores between parties","duration":1.6105459999999994,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should identify coalition blocs","status":"passed","title":"should identify coalition blocs","duration":1.5336020000000872,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Coalition Data Processing (Real CSV Schema)"],"fullName":"Coalition Dashboard Coalition Data Processing (Real CSV Schema) should aggregate behavioral data by party","status":"passed","title":"should aggregate behavioral data by party","duration":1.7860729999999876,"failureMessages":[],"location":{"line":232,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should prepare network data nodes for all 8 parties","status":"passed","title":"should prepare network data nodes for all 8 parties","duration":2.258919999999989,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should prepare network data links","status":"passed","title":"should prepare network data links","duration":1.980848999999921,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","D3.js Network"],"fullName":"Coalition Dashboard D3.js Network should generate correct number of links for 8 parties","status":"passed","title":"should generate correct number of links for 8 parties","duration":1.4504450000000588,"failureMessages":[],"location":{"line":271,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should handle empty CSV data gracefully","status":"passed","title":"should handle empty CSV data gracefully","duration":1.3546360000000277,"failureMessages":[],"location":{"line":279,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should provide fallback coalition data when CSV is empty","status":"passed","title":"should provide fallback coalition data when CSV is empty","duration":1.635691999999949,"failureMessages":[],"location":{"line":287,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should handle fetch failures with mock fallback","status":"passed","title":"should handle fetch failures with mock fallback","duration":2.336824999999976,"failureMessages":[],"location":{"line":308,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Error Handling and Fallbacks"],"fullName":"Coalition Dashboard Error Handling and Fallbacks should skip aggregate rows with party \"-\"","status":"passed","title":"should skip aggregate rows with party \"-\"","duration":1.4924139999999397,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Loading State"],"fullName":"Coalition Dashboard Loading State should add loading class to container","status":"passed","title":"should add loading class to container","duration":1.7877069999999549,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Loading State"],"fullName":"Coalition Dashboard Loading State should remove loading class when data loads","status":"passed","title":"should remove loading class when data loads","duration":1.640090999999984,"failureMessages":[],"location":{"line":339,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should use alignment_rate directly as 0-1 scale without dividing by 100","status":"passed","title":"should use alignment_rate directly as 0-1 scale without dividing by 100","duration":1.6358519999999999,"failureMessages":[],"location":{"line":347,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should handle reverse-pair lookups when CSV stores only one direction","status":"passed","title":"should handle reverse-pair lookups when CSV stores only one direction","duration":1.6304829999999129,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should NOT divide alignment_rate by 100 (values are already 0-1)","status":"passed","title":"should NOT divide alignment_rate by 100 (values are already 0-1)","duration":1.7419909999999845,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should calculate node influence correctly with 0-1 alignment rates","status":"passed","title":"should calculate node influence correctly with 0-1 alignment rates","duration":2.0492169999999987,"failureMessages":[],"location":{"line":393,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should treat alignment value of 0 as valid, not fall back to 0.5","status":"passed","title":"should treat alignment value of 0 as valid, not fall back to 0.5","duration":4.7644599999999855,"failureMessages":[],"location":{"line":404,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should fall back to 0.5 only for missing alignment data","status":"passed","title":"should fall back to 0.5 only for missing alignment data","duration":1.1118910000000142,"failureMessages":[],"location":{"line":412,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Alignment Rate Data Processing"],"fullName":"Coalition Dashboard Alignment Rate Data Processing should filter out non-party rows (e.g., party \"-\") when building alignment matrix","status":"passed","title":"should filter out non-party rows (e.g., party \"-\") when building alignment matrix","duration":1.335369999999898,"failureMessages":[],"location":{"line":419,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Mock Data Quality"],"fullName":"Coalition Dashboard Mock Data Quality should generate deterministic non-empty mock anomaly data for all parties","status":"passed","title":"should generate deterministic non-empty mock anomaly data for all parties","duration":2.4925369999999702,"failureMessages":[],"location":{"line":452,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Coalition Dashboard","Mock Data Quality"],"fullName":"Coalition Dashboard Mock Data Quality should generate deterministic non-empty mock annual votes data","status":"passed","title":"should generate deterministic non-empty mock annual votes data","duration":2.8199299999999994,"failureMessages":[],"location":{"line":468,"column":5},"meta":{},"tags":[]}],"startTime":1787953680216,"endTime":1787953680305.8198,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/coalition-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have committee dashboard section","status":"passed","title":"should have committee dashboard section","duration":10.874983999999984,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.4933090000000107,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":2.464104999999961,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have D3 visualization containers","status":"passed","title":"should have D3 visualization containers","duration":2.269820999999979,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have wide chart cards","status":"passed","title":"should have wide chart cards","duration":4.968635000000006,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","DOM Structure"],"fullName":"Committees Dashboard DOM Structure should have last updated timestamp","status":"passed","title":"should have last updated timestamp","duration":2.475174999999979,"failureMessages":[],"location":{"line":91,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have ARIA labels on D3 containers","status":"passed","title":"should have ARIA labels on D3 containers","duration":2.763695000000041,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have accessible fallback tables","status":"passed","title":"should have accessible fallback tables","duration":2.381779999999992,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have table captions","status":"passed","title":"should have table captions","duration":2.749479000000008,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Accessibility"],"fullName":"Committees Dashboard Accessibility should have proper heading hierarchy","status":"passed","title":"should have proper heading hierarchy","duration":3.2991180000000213,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should parse committee productivity matrix CSV with real columns","status":"passed","title":"should parse committee productivity matrix CSV with real columns","duration":3.0706900000000132,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should parse committee ballot decision summary CSV with real columns","status":"passed","title":"should parse committee ballot decision summary CSV with real columns","duration":2.044828999999993,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should rank committees by effectiveness","status":"passed","title":"should rank committees by effectiveness","duration":2.114629999999977,"failureMessages":[],"location":{"line":154,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Committee Data Processing"],"fullName":"Committees Dashboard Committee Data Processing should calculate productivity metrics","status":"passed","title":"should calculate productivity metrics","duration":1.8494329999999763,"failureMessages":[],"location":{"line":165,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Source Configuration"],"fullName":"Committees Dashboard Data Source Configuration should use local-first URLs with cia-data/ prefix","status":"passed","title":"should use local-first URLs with cia-data/ prefix","duration":2.0797750000000406,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Source Configuration"],"fullName":"Committees Dashboard Data Source Configuration should have remote fallback URLs","status":"passed","title":"should have remote fallback URLs","duration":2.0787329999999997,"failureMessages":[],"location":{"line":186,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Error Handling"],"fullName":"Committees Dashboard Error Handling should handle empty CSV data","status":"passed","title":"should handle empty CSV data","duration":1.7472420000000284,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Error Handling"],"fullName":"Committees Dashboard Error Handling should handle fetch failures gracefully","status":"passed","title":"should handle fetch failures gracefully","duration":2.4041220000000294,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Chart Configuration"],"fullName":"Committees Dashboard Chart Configuration should create comparison bar chart","status":"passed","title":"should create comparison bar chart","duration":4.823381999999981,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Attribution"],"fullName":"Committees Dashboard Data Attribution should have data attribution section","status":"passed","title":"should have data attribution section","duration":1.5842670000000112,"failureMessages":[],"location":{"line":228,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Committees Dashboard","Data Attribution"],"fullName":"Committees Dashboard Data Attribution should reference CIA Platform as data source","status":"passed","title":"should reference CIA Platform as data source","duration":1.5518659999999613,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]}],"startTime":1787953832936,"endTime":1787953832998.5518,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/committees-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows maps all 14 contract languages plus the BCP-47 `nb` alias for Norwegian","status":"passed","title":"maps all 14 contract languages plus the BCP-47 `nb` alias for Norwegian","duration":4.200203999999985,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows applies Latin window for unknown language","status":"passed","title":"applies Latin window for unknown language","duration":1.2209060000000136,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows uses tighter CJK windows","status":"passed","title":"uses tighter CJK windows","duration":0.5728630000000408,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: windows"],"fullName":"contract-checker: windows uses tighter RTL windows","status":"passed","title":"uses tighter RTL windows","duration":0.4970209999999611,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length PASS — title exactly at lower bound","status":"passed","title":"PASS — title exactly at lower bound","duration":1.3563699999999699,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — title below lower bound","status":"passed","title":"FAIL — title below lower bound","duration":0.7924339999999575,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — title above upper bound","status":"passed","title":"FAIL — title above upper bound","duration":0.7686089999999695,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title length"],"fullName":"contract-checker: title length FAIL — empty title","status":"passed","title":"FAIL — empty title","duration":0.5629339999999843,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — literal YYYY-MM-DD in title","status":"passed","title":"FAIL — literal YYYY-MM-DD in title","duration":0.6891299999999774,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — trailing brand suffix in title","status":"passed","title":"FAIL — trailing brand suffix in title","duration":1.0378029999999967,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — Executive Brief boilerplate prefix","status":"passed","title":"FAIL — Executive Brief boilerplate prefix","duration":0.6132790000000341,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — AI-generated filler phrase in title","status":"passed","title":"FAIL — AI-generated filler phrase in title","duration":0.47876600000000735,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases FAIL — Brief ID leak in title","status":"passed","title":"FAIL — Brief ID leak in title","duration":0.5191319999999564,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: title banned phrases"],"fullName":"contract-checker: title banned phrases PASS — clean title","status":"passed","title":"PASS — clean title","duration":0.573914000000002,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — description at lower bound, terminated","status":"passed","title":"PASS — description at lower bound, terminated","duration":0.5907659999999737,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description below lower bound","status":"passed","title":"FAIL — description below lower bound","duration":0.5674220000000219,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description above upper bound","status":"passed","title":"FAIL — description above upper bound","duration":0.538739000000021,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description empty","status":"passed","title":"FAIL — description empty","duration":0.5294109999999819,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — description ends mid-word","status":"passed","title":"FAIL — description ends mid-word","duration":1.1411170000000084,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — ellipsis is an accepted terminator","status":"passed","title":"PASS — ellipsis is an accepted terminator","duration":0.9453100000000063,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules PASS — CJK full stop 。 is an accepted terminator","status":"passed","title":"PASS — CJK full stop 。 is an accepted terminator","duration":0.6684420000000273,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (Brief ID)","status":"passed","title":"FAIL — admin leak (Brief ID)","duration":0.5419049999999856,"failureMessages":[],"location":{"line":233,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (Prepared by)","status":"passed","title":"FAIL — admin leak (Prepared by)","duration":0.6143999999999892,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — admin leak (60-second read)","status":"passed","title":"FAIL — admin leak (60-second read)","duration":0.5724309999999946,"failureMessages":[],"location":{"line":251,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: description rules"],"fullName":"contract-checker: description rules FAIL — generic filler","status":"passed","title":"FAIL — generic filler","duration":0.5675529999999753,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — 35-char German description is below floor","status":"passed","title":"FAIL — 35-char German description is below floor","duration":0.5887319999999931,"failureMessages":[],"location":{"line":271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — CJK tighter window catches 80-char Japanese title","status":"passed","title":"FAIL — CJK tighter window catches 80-char Japanese title","duration":0.687546999999995,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows PASS — 40-char Japanese title fits CJK window","status":"passed","title":"PASS — 40-char Japanese title fits CJK window","duration":0.6621499999999969,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: per-language windows"],"fullName":"contract-checker: per-language windows FAIL — RTL tighter window catches 100-char Arabic title","status":"passed","title":"FAIL — RTL tighter window catches 100-char Arabic title","duration":0.6460389999999734,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus BANNED_TITLE_PHRASES covers §2.2 list","status":"passed","title":"BANNED_TITLE_PHRASES covers §2.2 list","duration":0.5937620000000265,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus BANNED_DESCRIPTION_PHRASES covers §3.1 list","status":"passed","title":"BANNED_DESCRIPTION_PHRASES covers §3.1 list","duration":0.7861420000000408,"failureMessages":[],"location":{"line":325,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus ISO_DATE_RE matches canonical forms","status":"passed","title":"ISO_DATE_RE matches canonical forms","duration":0.9189709999999991,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus TRAILING_BRAND_RE matches trailing \" — Riksdagsmonitor\"","status":"passed","title":"TRAILING_BRAND_RE matches trailing \" — Riksdagsmonitor\"","duration":0.6783110000000079,"failureMessages":[],"location":{"line":333,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus GENERIC_FILLER_RE matches contract-listed filler","status":"passed","title":"GENERIC_FILLER_RE matches contract-listed filler","duration":0.5632349999999633,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: regex corpus"],"fullName":"contract-checker: regex corpus SENTENCE_TERMINATOR_RE accepts each multi-script terminator","status":"passed","title":"SENTENCE_TERMINATOR_RE accepts each multi-script terminator","duration":0.7895680000000311,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape ok=true when no violations","status":"passed","title":"ok=true when no violations","duration":0.8247740000000476,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape ok=false iff violations.length > 0","status":"passed","title":"ok=false iff violations.length > 0","duration":0.7458359999999971,"failureMessages":[],"location":{"line":366,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract-checker: result shape"],"fullName":"contract-checker: result shape every violation has {code, field, message, value}","status":"passed","title":"every violation has {code, field, message, value}","duration":1.698178999999982,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]}],"startTime":1787953789986,"endTime":1787953790018.6982,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/contract-checker.test.ts"},{"assertionResults":[{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_politician_risk_levels.csv","status":"passed","title":"should have distribution_politician_risk_levels.csv","duration":3.8710179999999923,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_risk_by_party.csv","status":"passed","title":"should have distribution_risk_by_party.csv","duration":0.5642770000000041,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_risk_evolution_temporal.csv","status":"passed","title":"should have distribution_risk_evolution_temporal.csv","duration":0.42115899999998874,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_crisis_resilience.csv","status":"passed","title":"should have distribution_crisis_resilience.csv","duration":0.46229600000003757,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have percentile_voting_anomaly_detection.csv","status":"passed","title":"should have percentile_voting_anomaly_detection.csv","duration":0.3382230000000277,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_party_effectiveness_trends.csv","status":"passed","title":"should have distribution_party_effectiveness_trends.csv","duration":0.4349040000000173,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_party_momentum.csv","status":"passed","title":"should have distribution_party_momentum.csv","duration":0.35641700000002174,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_annual_committee_documents.csv","status":"passed","title":"should have distribution_annual_committee_documents.csv","duration":0.30551200000002154,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_committee_productivity_matrix.csv","status":"passed","title":"should have distribution_committee_productivity_matrix.csv","duration":0.5624429999999734,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_effectiveness.csv","status":"passed","title":"should have distribution_ministry_effectiveness.csv","duration":0.31880599999999504,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_decision_impact.csv","status":"passed","title":"should have distribution_ministry_decision_impact.csv","duration":0.35458399999998846,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_productivity_matrix.csv","status":"passed","title":"should have distribution_ministry_productivity_matrix.csv","duration":0.3374109999999746,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_risk_levels.csv","status":"passed","title":"should have distribution_ministry_risk_levels.csv","duration":0.27993299999997134,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_ministry_risk_quarterly.csv","status":"passed","title":"should have distribution_ministry_risk_quarterly.csv","duration":0.31534099999998944,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_person_status.csv","status":"passed","title":"should have distribution_person_status.csv","duration":0.47895600000003924,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_experience_levels.csv","status":"passed","title":"should have distribution_experience_levels.csv","duration":0.43832099999997354,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have distribution_experience_by_party.csv","status":"passed","title":"should have distribution_experience_by_party.csv","duration":0.44853999999997995,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Existence"],"fullName":"CIA CSV Data Validation File Existence should have extraction_summary_report.csv","status":"passed","title":"should have extraction_summary_report.csv","duration":0.3714659999999981,"failureMessages":[],"location":{"line":114,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_politician_risk_levels.csv should not be empty or too small","status":"passed","title":"distribution_politician_risk_levels.csv should not be empty or too small","duration":0.6662580000000276,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_risk_by_party.csv should not be empty or too small","status":"passed","title":"distribution_risk_by_party.csv should not be empty or too small","duration":0.5359129999999936,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_risk_evolution_temporal.csv should not be empty or too small","status":"passed","title":"distribution_risk_evolution_temporal.csv should not be empty or too small","duration":0.4872530000000097,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_crisis_resilience.csv should not be empty or too small","status":"passed","title":"distribution_crisis_resilience.csv should not be empty or too small","duration":0.5251930000000016,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation percentile_voting_anomaly_detection.csv should not be empty or too small","status":"passed","title":"percentile_voting_anomaly_detection.csv should not be empty or too small","duration":0.45837899999997944,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_party_effectiveness_trends.csv should not be empty or too small","status":"passed","title":"distribution_party_effectiveness_trends.csv should not be empty or too small","duration":0.4967100000000073,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_party_momentum.csv should not be empty or too small","status":"passed","title":"distribution_party_momentum.csv should not be empty or too small","duration":0.4698900000000208,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_annual_committee_documents.csv should not be empty or too small","status":"passed","title":"distribution_annual_committee_documents.csv should not be empty or too small","duration":0.4833849999999984,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_committee_productivity_matrix.csv should not be empty or too small","status":"passed","title":"distribution_committee_productivity_matrix.csv should not be empty or too small","duration":0.49516700000003766,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_effectiveness.csv should not be empty or too small","status":"passed","title":"distribution_ministry_effectiveness.csv should not be empty or too small","duration":0.46988000000004604,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_decision_impact.csv should not be empty or too small","status":"passed","title":"distribution_ministry_decision_impact.csv should not be empty or too small","duration":0.44942200000002686,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_productivity_matrix.csv should not be empty or too small","status":"passed","title":"distribution_ministry_productivity_matrix.csv should not be empty or too small","duration":0.5209650000000465,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_risk_levels.csv should not be empty or too small","status":"passed","title":"distribution_ministry_risk_levels.csv should not be empty or too small","duration":0.6449980000000437,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_ministry_risk_quarterly.csv should not be empty or too small","status":"passed","title":"distribution_ministry_risk_quarterly.csv should not be empty or too small","duration":0.7723659999999768,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_person_status.csv should not be empty or too small","status":"passed","title":"distribution_person_status.csv should not be empty or too small","duration":0.5570119999999861,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_experience_levels.csv should not be empty or too small","status":"passed","title":"distribution_experience_levels.csv should not be empty or too small","duration":0.5136309999999753,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation distribution_experience_by_party.csv should not be empty or too small","status":"passed","title":"distribution_experience_by_party.csv should not be empty or too small","duration":0.5486779999999953,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","File Size Validation"],"fullName":"CIA CSV Data Validation File Size Validation extraction_summary_report.csv should not be empty or too small","status":"passed","title":"extraction_summary_report.csv should not be empty or too small","duration":0.5166580000000067,"failureMessages":[],"location":{"line":123,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_politician_risk_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_politician_risk_levels.csv should have valid UTF-8 encoding","duration":0.8567639999999983,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_risk_by_party.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_risk_by_party.csv should have valid UTF-8 encoding","duration":0.6430139999999938,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_risk_evolution_temporal.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_risk_evolution_temporal.csv should have valid UTF-8 encoding","duration":0.6454289999999787,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_crisis_resilience.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_crisis_resilience.csv should have valid UTF-8 encoding","duration":0.579435999999987,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation percentile_voting_anomaly_detection.csv should have valid UTF-8 encoding","status":"passed","title":"percentile_voting_anomaly_detection.csv should have valid UTF-8 encoding","duration":0.6480830000000424,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_party_effectiveness_trends.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_party_effectiveness_trends.csv should have valid UTF-8 encoding","duration":0.8558929999999805,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_party_momentum.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_party_momentum.csv should have valid UTF-8 encoding","duration":0.7095590000000129,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_annual_committee_documents.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_annual_committee_documents.csv should have valid UTF-8 encoding","duration":0.7976340000000164,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_committee_productivity_matrix.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_committee_productivity_matrix.csv should have valid UTF-8 encoding","duration":0.8485180000000128,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_effectiveness.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_effectiveness.csv should have valid UTF-8 encoding","duration":0.7251279999999838,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_decision_impact.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_decision_impact.csv should have valid UTF-8 encoding","duration":0.7996070000000373,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_productivity_matrix.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have valid UTF-8 encoding","duration":0.7187660000000164,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_risk_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_risk_levels.csv should have valid UTF-8 encoding","duration":0.8750580000000241,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_ministry_risk_quarterly.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have valid UTF-8 encoding","duration":0.8248539999999593,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_person_status.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_person_status.csv should have valid UTF-8 encoding","duration":0.7819339999999784,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_experience_levels.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_experience_levels.csv should have valid UTF-8 encoding","duration":0.7919630000000097,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation distribution_experience_by_party.csv should have valid UTF-8 encoding","status":"passed","title":"distribution_experience_by_party.csv should have valid UTF-8 encoding","duration":6.173889999999972,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Encoding Validation"],"fullName":"CIA CSV Data Validation Encoding Validation extraction_summary_report.csv should have valid UTF-8 encoding","status":"passed","title":"extraction_summary_report.csv should have valid UTF-8 encoding","duration":0.7315490000000295,"failureMessages":[],"location":{"line":158,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_politician_risk_levels.csv should have proper CSV structure","status":"passed","title":"distribution_politician_risk_levels.csv should have proper CSV structure","duration":0.9320950000000039,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_politician_risk_levels.csv should have data rows","status":"passed","title":"distribution_politician_risk_levels.csv should have data rows","duration":0.7083659999999554,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_by_party.csv should have proper CSV structure","status":"passed","title":"distribution_risk_by_party.csv should have proper CSV structure","duration":0.7103500000000622,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_by_party.csv should have data rows","status":"passed","title":"distribution_risk_by_party.csv should have data rows","duration":0.9374450000000252,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_evolution_temporal.csv should have proper CSV structure","status":"passed","title":"distribution_risk_evolution_temporal.csv should have proper CSV structure","duration":1.0824159999999665,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_risk_evolution_temporal.csv should have data rows","status":"passed","title":"distribution_risk_evolution_temporal.csv should have data rows","duration":0.6940989999999374,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_crisis_resilience.csv should have proper CSV structure","status":"passed","title":"distribution_crisis_resilience.csv should have proper CSV structure","duration":0.6727290000000039,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_crisis_resilience.csv should have data rows","status":"passed","title":"distribution_crisis_resilience.csv should have data rows","duration":0.6914040000000341,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation percentile_voting_anomaly_detection.csv should have proper CSV structure","status":"passed","title":"percentile_voting_anomaly_detection.csv should have proper CSV structure","duration":0.7259999999999991,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation percentile_voting_anomaly_detection.csv should have data rows","status":"passed","title":"percentile_voting_anomaly_detection.csv should have data rows","duration":0.6845610000000306,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_effectiveness_trends.csv should have proper CSV structure","status":"passed","title":"distribution_party_effectiveness_trends.csv should have proper CSV structure","duration":0.7502550000000383,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_effectiveness_trends.csv should have data rows","status":"passed","title":"distribution_party_effectiveness_trends.csv should have data rows","duration":0.7409770000000435,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_momentum.csv should have proper CSV structure","status":"passed","title":"distribution_party_momentum.csv should have proper CSV structure","duration":0.821749000000068,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_party_momentum.csv should have data rows","status":"passed","title":"distribution_party_momentum.csv should have data rows","duration":0.9089409999999134,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_annual_committee_documents.csv should have proper CSV structure","status":"passed","title":"distribution_annual_committee_documents.csv should have proper CSV structure","duration":1.0364210000000185,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_annual_committee_documents.csv should have data rows","status":"passed","title":"distribution_annual_committee_documents.csv should have data rows","duration":0.8401229999999487,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_committee_productivity_matrix.csv should have proper CSV structure","status":"passed","title":"distribution_committee_productivity_matrix.csv should have proper CSV structure","duration":0.8510629999999537,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_committee_productivity_matrix.csv should have data rows","status":"passed","title":"distribution_committee_productivity_matrix.csv should have data rows","duration":0.8053979999999683,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_effectiveness.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_effectiveness.csv should have proper CSV structure","duration":0.9363440000000764,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_effectiveness.csv should have data rows","status":"passed","title":"distribution_ministry_effectiveness.csv should have data rows","duration":0.8712909999999283,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_decision_impact.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_decision_impact.csv should have proper CSV structure","duration":0.9153840000000173,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_decision_impact.csv should have data rows","status":"passed","title":"distribution_ministry_decision_impact.csv should have data rows","duration":0.9091919999999618,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_productivity_matrix.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have proper CSV structure","duration":0.9805660000000671,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_productivity_matrix.csv should have data rows","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have data rows","duration":0.9442780000000539,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_levels.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_risk_levels.csv should have proper CSV structure","duration":1.1352759999999762,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_levels.csv should have data rows","status":"passed","title":"distribution_ministry_risk_levels.csv should have data rows","duration":1.1937560000000076,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_quarterly.csv should have proper CSV structure","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have proper CSV structure","duration":1.0724880000000212,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_ministry_risk_quarterly.csv should have data rows","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have data rows","duration":1.6020800000000008,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_person_status.csv should have proper CSV structure","status":"passed","title":"distribution_person_status.csv should have proper CSV structure","duration":2.024000000000001,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_person_status.csv should have data rows","status":"passed","title":"distribution_person_status.csv should have data rows","duration":1.4485019999999622,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_levels.csv should have proper CSV structure","status":"passed","title":"distribution_experience_levels.csv should have proper CSV structure","duration":1.1116610000000264,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_levels.csv should have data rows","status":"passed","title":"distribution_experience_levels.csv should have data rows","duration":1.059172999999987,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_by_party.csv should have proper CSV structure","status":"passed","title":"distribution_experience_by_party.csv should have proper CSV structure","duration":1.097395000000006,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation distribution_experience_by_party.csv should have data rows","status":"passed","title":"distribution_experience_by_party.csv should have data rows","duration":1.057570999999939,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation extraction_summary_report.csv should have proper CSV structure","status":"passed","title":"extraction_summary_report.csv should have proper CSV structure","duration":1.1122219999999743,"failureMessages":[],"location":{"line":177,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","CSV Structure Validation"],"fullName":"CIA CSV Data Validation CSV Structure Validation extraction_summary_report.csv should have data rows","status":"passed","title":"extraction_summary_report.csv should have data rows","duration":1.1047379999999976,"failureMessages":[],"location":{"line":196,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.3934390000000576,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should have required columns","status":"passed","title":"should have required columns","duration":2.021223999999961,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_politician_risk_levels.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_politician_risk_levels.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":1.4512680000000273,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.2187020000000075,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should have required columns","status":"passed","title":"should have required columns","duration":1.4052410000000464,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_risk_by_party.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_risk_by_party.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":2.274519000000055,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":1.684423000000038,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should have required columns","status":"passed","title":"should have required columns","duration":1.9128420000000688,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_party_effectiveness_trends.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_party_effectiveness_trends.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":5.685165000000097,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":2.208344000000011,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should have required columns","status":"passed","title":"should have required columns","duration":3.0398119999999835,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_ministry_effectiveness.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_ministry_effectiveness.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":3.668309000000022,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should exist and be parseable","status":"passed","title":"should exist and be parseable","duration":2.541488999999956,"failureMessages":[],"location":{"line":214,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should have required columns","status":"passed","title":"should have required columns","duration":2.2808009999999967,"failureMessages":[],"location":{"line":226,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Schema Validation","distribution_committee_productivity_matrix.csv"],"fullName":"CIA CSV Data Validation Schema Validation distribution_committee_productivity_matrix.csv should have valid numeric data types","status":"passed","title":"should have valid numeric data types","duration":12.54633100000001,"failureMessages":[],"location":{"line":242,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_politician_risk_levels.csv should have consistent column counts","status":"passed","title":"distribution_politician_risk_levels.csv should have consistent column counts","duration":2.6686369999999897,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_risk_by_party.csv should have consistent column counts","status":"passed","title":"distribution_risk_by_party.csv should have consistent column counts","duration":2.2425589999999147,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_risk_evolution_temporal.csv should have consistent column counts","status":"passed","title":"distribution_risk_evolution_temporal.csv should have consistent column counts","duration":3.0915590000000748,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_crisis_resilience.csv should have consistent column counts","status":"passed","title":"distribution_crisis_resilience.csv should have consistent column counts","duration":2.265310999999997,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency percentile_voting_anomaly_detection.csv should have consistent column counts","status":"passed","title":"percentile_voting_anomaly_detection.csv should have consistent column counts","duration":1.9890850000000455,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_party_effectiveness_trends.csv should have consistent column counts","status":"passed","title":"distribution_party_effectiveness_trends.csv should have consistent column counts","duration":3.459206999999992,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_party_momentum.csv should have consistent column counts","status":"passed","title":"distribution_party_momentum.csv should have consistent column counts","duration":7.801216999999951,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_annual_committee_documents.csv should have consistent column counts","status":"passed","title":"distribution_annual_committee_documents.csv should have consistent column counts","duration":11.184652000000028,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_committee_productivity_matrix.csv should have consistent column counts","status":"passed","title":"distribution_committee_productivity_matrix.csv should have consistent column counts","duration":6.330152999999996,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_effectiveness.csv should have consistent column counts","status":"passed","title":"distribution_ministry_effectiveness.csv should have consistent column counts","duration":2.674147000000062,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_decision_impact.csv should have consistent column counts","status":"passed","title":"distribution_ministry_decision_impact.csv should have consistent column counts","duration":2.2525779999999713,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_productivity_matrix.csv should have consistent column counts","status":"passed","title":"distribution_ministry_productivity_matrix.csv should have consistent column counts","duration":1.9710810000000265,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_risk_levels.csv should have consistent column counts","status":"passed","title":"distribution_ministry_risk_levels.csv should have consistent column counts","duration":1.6111069999999472,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_ministry_risk_quarterly.csv should have consistent column counts","status":"passed","title":"distribution_ministry_risk_quarterly.csv should have consistent column counts","duration":1.761908999999946,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_person_status.csv should have consistent column counts","status":"passed","title":"distribution_person_status.csv should have consistent column counts","duration":3.872090999999955,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_experience_levels.csv should have consistent column counts","status":"passed","title":"distribution_experience_levels.csv should have consistent column counts","duration":1.6840430000000879,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency distribution_experience_by_party.csv should have consistent column counts","status":"passed","title":"distribution_experience_by_party.csv should have consistent column counts","duration":2.059476000000018,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Column Consistency"],"fullName":"CIA CSV Data Validation Column Consistency extraction_summary_report.csv should have consistent column counts","status":"passed","title":"extraction_summary_report.csv should have consistent column counts","duration":3.421196000000009,"failureMessages":[],"location":{"line":268,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["CIA CSV Data Validation","Data Freshness"],"fullName":"CIA CSV Data Validation Data Freshness CSV files should not be older than 90 days (warns at 30 days)","status":"passed","title":"CSV files should not be older than 90 days (warns at 30 days)","duration":2.2340330000000677,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]}],"startTime":1787953813933,"endTime":1787953814120.2341,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/csv-validation.test.js"},{"assertionResults":[{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) dist/dashboards/ directory exists","status":"skipped","title":"dist/dashboards/ directory exists","failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) dist/cia-data/ directory exists","status":"skipped","title":"dist/cia-data/ directory exists","failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","parties.html"],"fullName":"Dashboard bundle integrity (post-build) parties.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","pre-election.html"],"fullName":"Dashboard bundle integrity (post-build) pre-election.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","coalitions.html"],"fullName":"Dashboard bundle integrity (post-build) coalitions.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","committees.html"],"fullName":"Dashboard bundle integrity (post-build) committees.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","seasonal-patterns.html"],"fullName":"Dashboard bundle integrity (post-build) seasonal-patterns.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","anomaly-detection.html"],"fullName":"Dashboard bundle integrity (post-build) anomaly-detection.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","risk.html"],"fullName":"Dashboard bundle integrity (post-build) risk.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","ministers.html"],"fullName":"Dashboard bundle integrity (post-build) ministers.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html exists in dist/dashboards/","status":"skipped","title":"exists in dist/dashboards/","failureMessages":[],"location":{"line":68,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html contains hashed main-*.js bundle (not dev /src/browser/main.ts)","status":"skipped","title":"contains hashed main-*.js bundle (not dev /src/browser/main.ts)","failureMessages":[],"location":{"line":72,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","election-cycle.html"],"fullName":"Dashboard bundle integrity (post-build) election-cycle.html has correctly rewritten stylesheet href (stable assets/styles.css path)","status":"skipped","title":"has correctly rewritten stylesheet href (stable assets/styles.css path)","failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)"],"fullName":"Dashboard bundle integrity (post-build) all localized dashboard pages also have hashed bundles","status":"skipped","title":"all localized dashboard pages also have hashed bundles","failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) dashboard/index.html exists and ships a hashed cia-entry bundle","status":"skipped","title":"dashboard/index.html exists and ships a hashed cia-entry bundle","failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) cia-entry-*.js statically bundles Chart.js (registerables + auto)","status":"skipped","title":"cia-entry-*.js statically bundles Chart.js (registerables + auto)","failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard bundle integrity (post-build)","CIA dashboard hub bundle (dashboard/index.html)"],"fullName":"Dashboard bundle integrity (post-build) CIA dashboard hub bundle (dashboard/index.html) cia-entry-*.js bundle graph statically references the d3 chunk","status":"skipped","title":"cia-entry-*.js bundle graph statically references the d3 chunk","failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]}],"startTime":1787953656920,"endTime":1787953656920,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-bundle-integrity.test.ts"},{"assertionResults":[{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/stats-loader.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/stats-loader.ts should not contain relative cia-data/ string literals","duration":4.167622999999992,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/party-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/party-dashboard.ts should not contain relative cia-data/ string literals","duration":0.7229440000000409,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/election-cycle.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/election-cycle.ts should not contain relative cia-data/ string literals","duration":0.5661499999999933,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/committees-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/committees-dashboard.ts should not contain relative cia-data/ string literals","duration":0.492621999999983,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/coalition-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/coalition-dashboard.ts should not contain relative cia-data/ string literals","duration":0.6088599999999929,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/seasonal-patterns.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/seasonal-patterns.ts should not contain relative cia-data/ string literals","duration":0.5966669999999681,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/pre-election.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/pre-election.ts should not contain relative cia-data/ string literals","duration":0.5828309999999988,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/anomaly-detection.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/anomaly-detection.ts should not contain relative cia-data/ string literals","duration":0.44594500000005155,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/ministry-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/ministry-dashboard.ts should not contain relative cia-data/ string literals","duration":0.7131750000000352,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/risk-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/risk-dashboard.ts should not contain relative cia-data/ string literals","duration":0.5447200000000407,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/dashboards/politician-dashboard.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/dashboards/politician-dashboard.ts should not contain relative cia-data/ string literals","duration":0.48422600000003513,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard modules use absolute /cia-data/ URLs"],"fullName":"Dashboard modules use absolute /cia-data/ URLs src/browser/cia/data-loader.ts should not contain relative cia-data/ string literals","status":"passed","title":"src/browser/cia/data-loader.ts should not contain relative cia-data/ string literals","duration":0.3367709999999988,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]}],"startTime":1787953920266,"endTime":1787953920276.3367,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-cia-data-absolute-paths.test.ts"},{"assertionResults":[{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","stats-loader"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist stats-loader should have extraction_summary_report.csv","status":"passed","title":"should have extraction_summary_report.csv","duration":5.599212999999963,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_performance.csv","status":"passed","title":"should have party/distribution_party_performance.csv","duration":0.6956920000000082,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_effectiveness_trends.csv","status":"passed","title":"should have party/distribution_party_effectiveness_trends.csv","duration":0.5473949999999377,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_party_momentum.csv","status":"passed","title":"should have party/distribution_party_momentum.csv","duration":0.5372660000000451,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.4923720000000458,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_annual_party_members.csv","status":"passed","title":"should have party/distribution_annual_party_members.csv","duration":0.630410999999981,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist party-dashboard should have party/distribution_annual_party_votes.csv","status":"passed","title":"should have party/distribution_annual_party_votes.csv","duration":0.47763399999996636,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_comparative_analysis_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_comparative_analysis_sample.csv","duration":0.5038030000000617,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_decision_intelligence_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_decision_intelligence_sample.csv","duration":0.6714769999999817,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_predictive_intelligence_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_predictive_intelligence_sample.csv","duration":0.45960999999999785,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist election-cycle should have election-cycle/view_election_cycle_temporal_trends_sample.csv","status":"passed","title":"should have election-cycle/view_election_cycle_temporal_trends_sample.csv","duration":0.579072999999994,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have distribution_committee_productivity_matrix.csv","status":"passed","title":"should have distribution_committee_productivity_matrix.csv","duration":0.4751499999999851,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have view_riksdagen_committee_decisions.csv","status":"passed","title":"should have view_riksdagen_committee_decisions.csv","duration":0.5318260000000237,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have distribution_annual_committee_documents.csv","status":"passed","title":"should have distribution_annual_committee_documents.csv","duration":0.5498000000000047,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have view_riksdagen_committee_ballot_decision_party_summary.csv","status":"passed","title":"should have view_riksdagen_committee_ballot_decision_party_summary.csv","duration":0.6029690000000301,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist committees-dashboard should have percentile_seasonal_activity_patterns.csv","status":"passed","title":"should have percentile_seasonal_activity_patterns.csv","duration":0.6201710000000276,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.4959689999999455,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have parties/distribution_behavioral_patterns_by_party.csv","status":"passed","title":"should have parties/distribution_behavioral_patterns_by_party.csv","duration":0.5214160000000447,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have parties/distribution_decision_patterns_by_party.csv","status":"passed","title":"should have parties/distribution_decision_patterns_by_party.csv","duration":0.5136919999999918,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have anomaly/distribution_anomaly_by_party.csv","status":"passed","title":"should have anomaly/distribution_anomaly_by_party.csv","duration":0.5611809999999195,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have voting/distribution_annual_party_votes.csv","status":"passed","title":"should have voting/distribution_annual_party_votes.csv","duration":0.6086090000000013,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have voting/distribution_decision_trends.csv","status":"passed","title":"should have voting/distribution_decision_trends.csv","duration":0.6502369999999473,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist coalition-dashboard should have distribution_party_momentum.csv","status":"passed","title":"should have distribution_party_momentum.csv","duration":0.7288549999999532,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist seasonal-patterns should have seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv","status":"passed","title":"should have seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv","duration":0.6068559999999934,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist pre-election should have pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv","status":"passed","title":"should have pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv","duration":0.6383150000000342,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist pre-election should have pre-election/view_riksdagen_q4_election_year_comparison_sample.csv","status":"passed","title":"should have pre-election/view_riksdagen_q4_election_year_comparison_sample.csv","duration":0.680072999999993,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist anomaly-detection should have seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv","status":"passed","title":"should have seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv","duration":0.6683819999999514,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_risk_levels.csv","status":"passed","title":"should have ministry/distribution_ministry_risk_levels.csv","duration":0.7412980000000289,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_productivity_matrix.csv","status":"passed","title":"should have ministry/distribution_ministry_productivity_matrix.csv","duration":0.6567389999999023,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_decision_impact.csv","status":"passed","title":"should have ministry/distribution_ministry_decision_impact.csv","duration":0.7150990000000093,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_effectiveness.csv","status":"passed","title":"should have ministry/distribution_ministry_effectiveness.csv","duration":1.0243679999999813,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist ministry-dashboard should have ministry/distribution_ministry_risk_quarterly.csv","status":"passed","title":"should have ministry/distribution_ministry_risk_quarterly.csv","duration":1.049955999999952,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist risk-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":0.7811030000000301,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":0.8979810000000725,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_riksdagen_politician_influence_metrics_sample.csv","status":"passed","title":"should have politician/view_riksdagen_politician_influence_metrics_sample.csv","duration":0.9584439999999859,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/view_politician_behavioral_trends_sample.csv","status":"passed","title":"should have politician/view_politician_behavioral_trends_sample.csv","duration":0.8222799999999779,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_experience_levels.csv","status":"passed","title":"should have politician/distribution_experience_levels.csv","duration":0.7723059999999577,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_influence_buckets.csv","status":"passed","title":"should have politician/distribution_influence_buckets.csv","duration":0.8230109999999513,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist politician-dashboard should have politician/distribution_assignment_roles.csv","status":"passed","title":"should have politician/distribution_assignment_roles.csv","duration":0.8747270000000071,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_person_status.csv","status":"passed","title":"should have distribution_person_status.csv","duration":0.9377259999999978,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_risk_by_party.csv","status":"passed","title":"should have distribution_risk_by_party.csv","duration":1.0357989999999972,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_politician_risk_levels.csv","status":"passed","title":"should have distribution_politician_risk_levels.csv","duration":1.0904620000000023,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_annual_ballots.csv","status":"passed","title":"should have voting/distribution_annual_ballots.csv","duration":0.9551079999999956,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have risk/distribution_crisis_resilience.csv","status":"passed","title":"should have risk/distribution_crisis_resilience.csv","duration":0.9137200000000121,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_performance.csv","status":"passed","title":"should have party/distribution_party_performance.csv","duration":0.9813669999999775,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/view_party_performance_metrics_sample.csv","status":"passed","title":"should have party/view_party_performance_metrics_sample.csv","duration":0.9355219999999917,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_momentum.csv","status":"passed","title":"should have party/distribution_party_momentum.csv","duration":1.0406279999999697,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_annual_party_members.csv","status":"passed","title":"should have party/distribution_annual_party_members.csv","duration":0.9494979999999487,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have politician/view_riksdagen_politician_influence_metrics_sample.csv","status":"passed","title":"should have politician/view_riksdagen_politician_influence_metrics_sample.csv","duration":1.0923050000000103,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have politician/view_politician_risk_summary_sample.csv","status":"passed","title":"should have politician/view_politician_risk_summary_sample.csv","duration":1.0139580000000024,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have committee/distribution_committee_productivity.csv","status":"passed","title":"should have committee/distribution_committee_productivity.csv","duration":1.060895999999957,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have committee/distribution_committee_activity.csv","status":"passed","title":"should have committee/distribution_committee_activity.csv","duration":1.0131069999999909,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_party_effectiveness_trends.csv","status":"passed","title":"should have party/distribution_party_effectiveness_trends.csv","duration":1.052930999999944,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/election_forecast.csv","status":"passed","title":"should have election/election_forecast.csv","duration":10.53108599999996,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/coalition_scenarios.csv","status":"passed","title":"should have election/coalition_scenarios.csv","duration":1.6754869999999755,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_coalition_alignment.csv","status":"passed","title":"should have party/distribution_coalition_alignment.csv","duration":0.869638000000009,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_gender_by_party.csv","status":"passed","title":"should have party/distribution_gender_by_party.csv","duration":0.6466709999999694,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_experience_by_party.csv","status":"passed","title":"should have party/distribution_experience_by_party.csv","duration":0.7506050000000641,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have ministry/distribution_ministry_effectiveness.csv","status":"passed","title":"should have ministry/distribution_ministry_effectiveness.csv","duration":0.7803409999999076,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_annual_document_types.csv","status":"passed","title":"should have voting/distribution_annual_document_types.csv","duration":0.7458370000000514,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have voting/distribution_decision_trends.csv","status":"passed","title":"should have voting/distribution_decision_trends.csv","duration":0.6907429999999977,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have election/distribution_election_regions.csv","status":"passed","title":"should have election/distribution_election_regions.csv","duration":0.8227299999999786,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have view_riksdagen_goverment_role_member_sample.csv","status":"passed","title":"should have view_riksdagen_goverment_role_member_sample.csv","duration":0.7394350000000713,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have distribution_risk_evolution_temporal.csv","status":"passed","title":"should have distribution_risk_evolution_temporal.csv","duration":0.958295000000021,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files exist","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files exist cia-dashboard should have party/distribution_behavioral_patterns_by_party.csv","status":"passed","title":"should have party/distribution_behavioral_patterns_by_party.csv","duration":0.8838749999999891,"failureMessages":[],"location":{"line":191,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","stats-loader"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) stats-loader extraction_summary_report.csv should have at least 1 data row","status":"passed","title":"extraction_summary_report.csv should have at least 1 data row","duration":1.1547109999999066,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_performance.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_performance.csv should have at least 1 data row","duration":0.8419360000000324,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_effectiveness_trends.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_effectiveness_trends.csv should have at least 1 data row","duration":0.8966589999999997,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_momentum.csv should have at least 1 data row","duration":1.1760810000000674,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":0.914421999999945,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_annual_party_members.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_members.csv should have at least 1 data row","duration":0.912488000000053,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) party-dashboard party/distribution_annual_party_votes.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_votes.csv should have at least 1 data row","duration":0.9587849999999207,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_comparative_analysis_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_comparative_analysis_sample.csv should have at least 1 data row","duration":0.9780809999999747,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_decision_intelligence_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_decision_intelligence_sample.csv should have at least 1 data row","duration":0.992678000000069,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_predictive_intelligence_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_predictive_intelligence_sample.csv should have at least 1 data row","duration":0.9686440000000403,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","election-cycle"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) election-cycle election-cycle/view_election_cycle_temporal_trends_sample.csv should have at least 1 data row","status":"passed","title":"election-cycle/view_election_cycle_temporal_trends_sample.csv should have at least 1 data row","duration":0.9995710000000599,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard distribution_committee_productivity_matrix.csv should have at least 1 data row","status":"passed","title":"distribution_committee_productivity_matrix.csv should have at least 1 data row","duration":1.0329739999999674,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard view_riksdagen_committee_decisions.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_committee_decisions.csv should have at least 1 data row","duration":37.17560900000001,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard distribution_annual_committee_documents.csv should have at least 1 data row","status":"passed","title":"distribution_annual_committee_documents.csv should have at least 1 data row","duration":1.9775220000000218,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard view_riksdagen_committee_ballot_decision_party_summary.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_committee_ballot_decision_party_summary.csv should have at least 1 data row","duration":41.16138000000001,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) committees-dashboard percentile_seasonal_activity_patterns.csv should have at least 1 data row","status":"passed","title":"percentile_seasonal_activity_patterns.csv should have at least 1 data row","duration":1.7485940000000255,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":1.2380970000000389,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard parties/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"parties/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","duration":1.7507880000000569,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard parties/distribution_decision_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"parties/distribution_decision_patterns_by_party.csv should have at least 1 data row","duration":1.5090250000000651,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard anomaly/distribution_anomaly_by_party.csv should have at least 1 data row","status":"passed","title":"anomaly/distribution_anomaly_by_party.csv should have at least 1 data row","duration":1.2337390000000141,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard voting/distribution_annual_party_votes.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_party_votes.csv should have at least 1 data row","duration":1.2382989999999836,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard voting/distribution_decision_trends.csv should have at least 1 data row","status":"passed","title":"voting/distribution_decision_trends.csv should have at least 1 data row","duration":1.2425369999999702,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) coalition-dashboard distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"distribution_party_momentum.csv should have at least 1 data row","duration":1.2430970000000343,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) seasonal-patterns seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv should have at least 1 data row","status":"passed","title":"seasonal/view_riksdagen_seasonal_activity_patterns_sample.csv should have at least 1 data row","duration":1.2833119999999099,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) pre-election pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv should have at least 1 data row","status":"passed","title":"pre-election/view_riksdagen_pre_election_quarterly_activity_sample.csv should have at least 1 data row","duration":1.3224860000000263,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","pre-election"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) pre-election pre-election/view_riksdagen_q4_election_year_comparison_sample.csv should have at least 1 data row","status":"passed","title":"pre-election/view_riksdagen_q4_election_year_comparison_sample.csv should have at least 1 data row","duration":1.268624999999929,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) anomaly-detection seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv should have at least 1 data row","status":"passed","title":"seasonal/view_riksdagen_seasonal_anomaly_detection_sample.csv should have at least 1 data row","duration":1.3180869999999913,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_risk_levels.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_risk_levels.csv should have at least 1 data row","duration":1.3708870000000388,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_productivity_matrix.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_productivity_matrix.csv should have at least 1 data row","duration":1.4474700000000666,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_decision_impact.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_decision_impact.csv should have at least 1 data row","duration":1.3610479999999825,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","duration":1.3402399999999943,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) ministry-dashboard ministry/distribution_ministry_risk_quarterly.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_risk_quarterly.csv should have at least 1 data row","duration":1.4210610000000088,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) risk-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.5765010000000075,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.5276799999999184,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","duration":1.4836480000000165,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/view_politician_behavioral_trends_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_behavioral_trends_sample.csv should have at least 1 data row","duration":1.5893049999999675,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_experience_levels.csv should have at least 1 data row","status":"passed","title":"politician/distribution_experience_levels.csv should have at least 1 data row","duration":1.6629330000000664,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_influence_buckets.csv should have at least 1 data row","status":"passed","title":"politician/distribution_influence_buckets.csv should have at least 1 data row","duration":1.625583000000006,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) politician-dashboard politician/distribution_assignment_roles.csv should have at least 1 data row","status":"passed","title":"politician/distribution_assignment_roles.csv should have at least 1 data row","duration":1.8617859999999382,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_person_status.csv should have at least 1 data row","status":"passed","title":"distribution_person_status.csv should have at least 1 data row","duration":1.5738470000000007,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_risk_by_party.csv should have at least 1 data row","status":"passed","title":"distribution_risk_by_party.csv should have at least 1 data row","duration":1.5334020000000237,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_politician_risk_levels.csv should have at least 1 data row","status":"passed","title":"distribution_politician_risk_levels.csv should have at least 1 data row","duration":1.5451219999999921,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_annual_ballots.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_ballots.csv should have at least 1 data row","duration":1.5782749999999623,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard risk/distribution_crisis_resilience.csv should have at least 1 data row","status":"passed","title":"risk/distribution_crisis_resilience.csv should have at least 1 data row","duration":1.5978020000000015,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_performance.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_performance.csv should have at least 1 data row","duration":1.649989000000005,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/view_party_performance_metrics_sample.csv should have at least 1 data row","status":"passed","title":"party/view_party_performance_metrics_sample.csv should have at least 1 data row","duration":1.6236289999999372,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_momentum.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_momentum.csv should have at least 1 data row","duration":1.6651669999999967,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_annual_party_members.csv should have at least 1 data row","status":"passed","title":"party/distribution_annual_party_members.csv should have at least 1 data row","duration":1.7462889999999334,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_riksdagen_politician_influence_metrics_sample.csv should have at least 1 data row","duration":1.7240980000000263,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard politician/view_politician_risk_summary_sample.csv should have at least 1 data row","status":"passed","title":"politician/view_politician_risk_summary_sample.csv should have at least 1 data row","duration":1.7549850000000333,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard committee/distribution_committee_productivity.csv should have at least 1 data row","status":"passed","title":"committee/distribution_committee_productivity.csv should have at least 1 data row","duration":1.754905000000008,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard committee/distribution_committee_activity.csv should have at least 1 data row","status":"passed","title":"committee/distribution_committee_activity.csv should have at least 1 data row","duration":2.016905999999949,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_party_effectiveness_trends.csv should have at least 1 data row","status":"passed","title":"party/distribution_party_effectiveness_trends.csv should have at least 1 data row","duration":2.2165699999999333,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/election_forecast.csv should have at least 1 data row","status":"passed","title":"election/election_forecast.csv should have at least 1 data row","duration":3.034730999999965,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/coalition_scenarios.csv should have at least 1 data row","status":"passed","title":"election/coalition_scenarios.csv should have at least 1 data row","duration":2.931838999999968,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_coalition_alignment.csv should have at least 1 data row","status":"passed","title":"party/distribution_coalition_alignment.csv should have at least 1 data row","duration":2.992082000000096,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_gender_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_gender_by_party.csv should have at least 1 data row","duration":3.0278279999999995,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_experience_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_experience_by_party.csv should have at least 1 data row","duration":3.0259750000000167,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","status":"passed","title":"ministry/distribution_ministry_effectiveness.csv should have at least 1 data row","duration":2.579168999999979,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_annual_document_types.csv should have at least 1 data row","status":"passed","title":"voting/distribution_annual_document_types.csv should have at least 1 data row","duration":1.951133000000027,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard voting/distribution_decision_trends.csv should have at least 1 data row","status":"passed","title":"voting/distribution_decision_trends.csv should have at least 1 data row","duration":1.9735449999999446,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard election/distribution_election_regions.csv should have at least 1 data row","status":"passed","title":"election/distribution_election_regions.csv should have at least 1 data row","duration":2.231518000000051,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard view_riksdagen_goverment_role_member_sample.csv should have at least 1 data row","status":"passed","title":"view_riksdagen_goverment_role_member_sample.csv should have at least 1 data row","duration":2.0242600000000266,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard distribution_risk_evolution_temporal.csv should have at least 1 data row","status":"passed","title":"distribution_risk_evolution_temporal.csv should have at least 1 data row","duration":1.9768109999999979,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","All dashboard CSV files have data rows (not just headers)","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity All dashboard CSV files have data rows (not just headers) cia-dashboard party/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","status":"passed","title":"party/distribution_behavioral_patterns_by_party.csv should have at least 1 data row","duration":1.953467000000046,"failureMessages":[],"location":{"line":204,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist stats-loader module should exist at src/browser/dashboards/stats-loader.ts","status":"passed","title":"stats-loader module should exist at src/browser/dashboards/stats-loader.ts","duration":2.0947720000000345,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist party-dashboard module should exist at src/browser/dashboards/party-dashboard.ts","status":"passed","title":"party-dashboard module should exist at src/browser/dashboards/party-dashboard.ts","duration":2.8252599999999575,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist election-cycle module should exist at src/browser/dashboards/election-cycle.ts","status":"passed","title":"election-cycle module should exist at src/browser/dashboards/election-cycle.ts","duration":1.9618030000000317,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist committees-dashboard module should exist at src/browser/dashboards/committees-dashboard.ts","status":"passed","title":"committees-dashboard module should exist at src/browser/dashboards/committees-dashboard.ts","duration":2.045178999999962,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist coalition-dashboard module should exist at src/browser/dashboards/coalition-dashboard.ts","status":"passed","title":"coalition-dashboard module should exist at src/browser/dashboards/coalition-dashboard.ts","duration":1.9862880000000587,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist seasonal-patterns module should exist at src/browser/dashboards/seasonal-patterns.ts","status":"passed","title":"seasonal-patterns module should exist at src/browser/dashboards/seasonal-patterns.ts","duration":2.10187499999995,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist pre-election module should exist at src/browser/dashboards/pre-election.ts","status":"passed","title":"pre-election module should exist at src/browser/dashboards/pre-election.ts","duration":2.786016000000018,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist anomaly-detection module should exist at src/browser/dashboards/anomaly-detection.ts","status":"passed","title":"anomaly-detection module should exist at src/browser/dashboards/anomaly-detection.ts","duration":2.321446000000037,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist ministry-dashboard module should exist at src/browser/dashboards/ministry-dashboard.ts","status":"passed","title":"ministry-dashboard module should exist at src/browser/dashboards/ministry-dashboard.ts","duration":2.0904339999999593,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist risk-dashboard module should exist at src/browser/dashboards/risk-dashboard.ts","status":"passed","title":"risk-dashboard module should exist at src/browser/dashboards/risk-dashboard.ts","duration":2.0866060000000743,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist politician-dashboard module should exist at src/browser/dashboards/politician-dashboard.ts","status":"passed","title":"politician-dashboard module should exist at src/browser/dashboards/politician-dashboard.ts","duration":2.144935999999916,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard module files exist"],"fullName":"Dashboard-CSV Data Integrity Dashboard module files exist cia-dashboard module should exist at src/browser/cia/data-loader.ts","status":"passed","title":"cia-dashboard module should exist at src/browser/cia/data-loader.ts","duration":2.0981879999999364,"failureMessages":[],"location":{"line":218,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/parties.html should have container #party-dashboard","status":"passed","title":"dashboards/parties.html should have container #party-dashboard","duration":2.4655050000000074,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/election-cycle.html should have container #election-cycle-dashboard","status":"passed","title":"dashboards/election-cycle.html should have container #election-cycle-dashboard","duration":2.206099999999992,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/committees.html should have container #committee-dashboard","status":"passed","title":"dashboards/committees.html should have container #committee-dashboard","duration":2.232138999999961,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/coalitions.html should have container #coalition-dashboard","status":"passed","title":"dashboards/coalitions.html should have container #coalition-dashboard","duration":2.224815000000035,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/seasonal-patterns.html should have container #seasonal-patterns-dashboard","status":"passed","title":"dashboards/seasonal-patterns.html should have container #seasonal-patterns-dashboard","duration":2.2563149999999723,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/pre-election.html should have container #pre-election-dashboard","status":"passed","title":"dashboards/pre-election.html should have container #pre-election-dashboard","duration":2.268387000000075,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/anomaly-detection.html should have container #anomaly-detection-dashboard","status":"passed","title":"dashboards/anomaly-detection.html should have container #anomaly-detection-dashboard","duration":2.3275580000000673,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/ministers.html should have container #ministry-dashboard","status":"passed","title":"dashboards/ministers.html should have container #ministry-dashboard","duration":2.3131309999999985,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) dashboards/risk.html should have container #risk-dashboard","status":"passed","title":"dashboards/risk.html should have container #risk-dashboard","duration":2.3287599999999884,"failureMessages":[],"location":{"line":242,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","No orphaned dashboard HTML containers (specialised dashboard pages)"],"fullName":"Dashboard-CSV Data Integrity No orphaned dashboard HTML containers (specialised dashboard pages) index.html should expose a hub linking to every specialised dashboard","status":"passed","title":"index.html should expose a hub linking to every specialised dashboard","duration":2.8866140000000087,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties.html","status":"passed","title":"should have dashboards/parties.html","duration":2.542780999999991,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ar.html","status":"passed","title":"should have dashboards/parties_ar.html","duration":2.3798550000000205,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_da.html","status":"passed","title":"should have dashboards/parties_da.html","duration":2.6971999999999525,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_de.html","status":"passed","title":"should have dashboards/parties_de.html","duration":2.8006829999999354,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_es.html","status":"passed","title":"should have dashboards/parties_es.html","duration":2.7939409999999043,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_fi.html","status":"passed","title":"should have dashboards/parties_fi.html","duration":2.757863999999927,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_fr.html","status":"passed","title":"should have dashboards/parties_fr.html","duration":3.218766999999957,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_he.html","status":"passed","title":"should have dashboards/parties_he.html","duration":3.6370090000000346,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ja.html","status":"passed","title":"should have dashboards/parties_ja.html","duration":2.895972000000029,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_ko.html","status":"passed","title":"should have dashboards/parties_ko.html","duration":2.81570099999999,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_nl.html","status":"passed","title":"should have dashboards/parties_nl.html","duration":2.8666170000000193,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_no.html","status":"passed","title":"should have dashboards/parties_no.html","duration":3.3694080000000213,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_sv.html","status":"passed","title":"should have dashboards/parties_sv.html","duration":2.9132339999999886,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/parties_zh.html","status":"passed","title":"should have dashboards/parties_zh.html","duration":2.981612000000041,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle.html","status":"passed","title":"should have dashboards/election-cycle.html","duration":2.921880999999985,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ar.html","status":"passed","title":"should have dashboards/election-cycle_ar.html","duration":2.9582580000000007,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_da.html","status":"passed","title":"should have dashboards/election-cycle_da.html","duration":2.986340999999925,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_de.html","status":"passed","title":"should have dashboards/election-cycle_de.html","duration":3.0245929999999817,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_es.html","status":"passed","title":"should have dashboards/election-cycle_es.html","duration":3.0031529999999975,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_fi.html","status":"passed","title":"should have dashboards/election-cycle_fi.html","duration":3.113609999999994,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_fr.html","status":"passed","title":"should have dashboards/election-cycle_fr.html","duration":3.1253510000000233,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_he.html","status":"passed","title":"should have dashboards/election-cycle_he.html","duration":3.0500599999999167,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ja.html","status":"passed","title":"should have dashboards/election-cycle_ja.html","duration":3.1601669999998876,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_ko.html","status":"passed","title":"should have dashboards/election-cycle_ko.html","duration":3.185504000000037,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_nl.html","status":"passed","title":"should have dashboards/election-cycle_nl.html","duration":3.2113319999998566,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_no.html","status":"passed","title":"should have dashboards/election-cycle_no.html","duration":3.188218000000006,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_sv.html","status":"passed","title":"should have dashboards/election-cycle_sv.html","duration":3.233793999999989,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/election-cycle_zh.html","status":"passed","title":"should have dashboards/election-cycle_zh.html","duration":3.245335999999952,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees.html","status":"passed","title":"should have dashboards/committees.html","duration":3.192145999999866,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ar.html","status":"passed","title":"should have dashboards/committees_ar.html","duration":4.407651999999871,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_da.html","status":"passed","title":"should have dashboards/committees_da.html","duration":3.7056569999999738,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_de.html","status":"passed","title":"should have dashboards/committees_de.html","duration":3.5906320000001415,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_es.html","status":"passed","title":"should have dashboards/committees_es.html","duration":3.356924999999819,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_fi.html","status":"passed","title":"should have dashboards/committees_fi.html","duration":3.4020889999999326,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_fr.html","status":"passed","title":"should have dashboards/committees_fr.html","duration":4.975676000000021,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_he.html","status":"passed","title":"should have dashboards/committees_he.html","duration":3.1892599999998765,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ja.html","status":"passed","title":"should have dashboards/committees_ja.html","duration":3.1212530000000243,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_ko.html","status":"passed","title":"should have dashboards/committees_ko.html","duration":4.060301999999865,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_nl.html","status":"passed","title":"should have dashboards/committees_nl.html","duration":3.3645289999999477,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_no.html","status":"passed","title":"should have dashboards/committees_no.html","duration":3.126022000000148,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_sv.html","status":"passed","title":"should have dashboards/committees_sv.html","duration":3.0949439999999413,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/committees_zh.html","status":"passed","title":"should have dashboards/committees_zh.html","duration":3.1771179999998367,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions.html","status":"passed","title":"should have dashboards/coalitions.html","duration":3.147502999999915,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ar.html","status":"passed","title":"should have dashboards/coalitions_ar.html","duration":3.188840999999911,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_da.html","status":"passed","title":"should have dashboards/coalitions_da.html","duration":3.2002919999999904,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_de.html","status":"passed","title":"should have dashboards/coalitions_de.html","duration":3.419502000000193,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_es.html","status":"passed","title":"should have dashboards/coalitions_es.html","duration":3.2685599999999795,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_fi.html","status":"passed","title":"should have dashboards/coalitions_fi.html","duration":3.4704269999999724,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_fr.html","status":"passed","title":"should have dashboards/coalitions_fr.html","duration":3.3555730000000494,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_he.html","status":"passed","title":"should have dashboards/coalitions_he.html","duration":3.3230610000000524,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ja.html","status":"passed","title":"should have dashboards/coalitions_ja.html","duration":3.262678000000051,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_ko.html","status":"passed","title":"should have dashboards/coalitions_ko.html","duration":3.264652000000069,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_nl.html","status":"passed","title":"should have dashboards/coalitions_nl.html","duration":3.2768650000000434,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_no.html","status":"passed","title":"should have dashboards/coalitions_no.html","duration":3.7022309999999834,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_sv.html","status":"passed","title":"should have dashboards/coalitions_sv.html","duration":3.3327690000000985,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/coalitions_zh.html","status":"passed","title":"should have dashboards/coalitions_zh.html","duration":3.3813199999999597,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns.html","status":"passed","title":"should have dashboards/seasonal-patterns.html","duration":3.4339380000001256,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ar.html","status":"passed","title":"should have dashboards/seasonal-patterns_ar.html","duration":3.3861490000001595,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_da.html","status":"passed","title":"should have dashboards/seasonal-patterns_da.html","duration":3.4364129999999022,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_de.html","status":"passed","title":"should have dashboards/seasonal-patterns_de.html","duration":3.4388080000001082,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_es.html","status":"passed","title":"should have dashboards/seasonal-patterns_es.html","duration":3.464465999999902,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_fi.html","status":"passed","title":"should have dashboards/seasonal-patterns_fi.html","duration":3.6116309999999885,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_fr.html","status":"passed","title":"should have dashboards/seasonal-patterns_fr.html","duration":3.8404900000000453,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_he.html","status":"passed","title":"should have dashboards/seasonal-patterns_he.html","duration":3.6819440000001578,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ja.html","status":"passed","title":"should have dashboards/seasonal-patterns_ja.html","duration":3.6913899999999558,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_ko.html","status":"passed","title":"should have dashboards/seasonal-patterns_ko.html","duration":3.8546269999999367,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_nl.html","status":"passed","title":"should have dashboards/seasonal-patterns_nl.html","duration":3.958421000000044,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_no.html","status":"passed","title":"should have dashboards/seasonal-patterns_no.html","duration":6.928883000000042,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_sv.html","status":"passed","title":"should have dashboards/seasonal-patterns_sv.html","duration":5.642364000000043,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/seasonal-patterns_zh.html","status":"passed","title":"should have dashboards/seasonal-patterns_zh.html","duration":3.811805999999933,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election.html","status":"passed","title":"should have dashboards/pre-election.html","duration":3.7086629999998877,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ar.html","status":"passed","title":"should have dashboards/pre-election_ar.html","duration":3.9932960000001003,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_da.html","status":"passed","title":"should have dashboards/pre-election_da.html","duration":3.7344009999999344,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_de.html","status":"passed","title":"should have dashboards/pre-election_de.html","duration":3.736855999999989,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_es.html","status":"passed","title":"should have dashboards/pre-election_es.html","duration":3.713412000000062,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_fi.html","status":"passed","title":"should have dashboards/pre-election_fi.html","duration":3.7209069999998974,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_fr.html","status":"passed","title":"should have dashboards/pre-election_fr.html","duration":3.7625040000000354,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_he.html","status":"passed","title":"should have dashboards/pre-election_he.html","duration":3.843847000000096,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ja.html","status":"passed","title":"should have dashboards/pre-election_ja.html","duration":3.938323000000082,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_ko.html","status":"passed","title":"should have dashboards/pre-election_ko.html","duration":4.94437599999992,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_nl.html","status":"passed","title":"should have dashboards/pre-election_nl.html","duration":3.9819350000000213,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_no.html","status":"passed","title":"should have dashboards/pre-election_no.html","duration":3.8789520000000266,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_sv.html","status":"passed","title":"should have dashboards/pre-election_sv.html","duration":3.8948120000000017,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/pre-election_zh.html","status":"passed","title":"should have dashboards/pre-election_zh.html","duration":3.8387259999999515,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection.html","status":"passed","title":"should have dashboards/anomaly-detection.html","duration":3.8756459999999606,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ar.html","status":"passed","title":"should have dashboards/anomaly-detection_ar.html","duration":3.9745909999999185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_da.html","status":"passed","title":"should have dashboards/anomaly-detection_da.html","duration":3.9285440000001017,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_de.html","status":"passed","title":"should have dashboards/anomaly-detection_de.html","duration":3.999427000000196,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_es.html","status":"passed","title":"should have dashboards/anomaly-detection_es.html","duration":3.9365190000000894,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_fi.html","status":"passed","title":"should have dashboards/anomaly-detection_fi.html","duration":3.991703000000143,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_fr.html","status":"passed","title":"should have dashboards/anomaly-detection_fr.html","duration":4.039143000000195,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_he.html","status":"passed","title":"should have dashboards/anomaly-detection_he.html","duration":4.695570999999973,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ja.html","status":"passed","title":"should have dashboards/anomaly-detection_ja.html","duration":7.2826440000001185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_ko.html","status":"passed","title":"should have dashboards/anomaly-detection_ko.html","duration":5.03227099999981,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_nl.html","status":"passed","title":"should have dashboards/anomaly-detection_nl.html","duration":4.163994999999886,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_no.html","status":"passed","title":"should have dashboards/anomaly-detection_no.html","duration":4.195795000000089,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_sv.html","status":"passed","title":"should have dashboards/anomaly-detection_sv.html","duration":4.129411000000118,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/anomaly-detection_zh.html","status":"passed","title":"should have dashboards/anomaly-detection_zh.html","duration":4.183881999999812,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers.html","status":"passed","title":"should have dashboards/ministers.html","duration":4.204661999999871,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ar.html","status":"passed","title":"should have dashboards/ministers_ar.html","duration":4.292445999999927,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_da.html","status":"passed","title":"should have dashboards/ministers_da.html","duration":4.641950000000179,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_de.html","status":"passed","title":"should have dashboards/ministers_de.html","duration":4.3154490000001715,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_es.html","status":"passed","title":"should have dashboards/ministers_es.html","duration":4.337660999999798,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_fi.html","status":"passed","title":"should have dashboards/ministers_fi.html","duration":4.249745999999959,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_fr.html","status":"passed","title":"should have dashboards/ministers_fr.html","duration":4.406048999999939,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_he.html","status":"passed","title":"should have dashboards/ministers_he.html","duration":4.357868000000053,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ja.html","status":"passed","title":"should have dashboards/ministers_ja.html","duration":4.312364000000116,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_ko.html","status":"passed","title":"should have dashboards/ministers_ko.html","duration":4.332540999999992,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_nl.html","status":"passed","title":"should have dashboards/ministers_nl.html","duration":4.356326000000081,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_no.html","status":"passed","title":"should have dashboards/ministers_no.html","duration":5.867966000000024,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_sv.html","status":"passed","title":"should have dashboards/ministers_sv.html","duration":4.362437,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/ministers_zh.html","status":"passed","title":"should have dashboards/ministers_zh.html","duration":4.349993999999924,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk.html","status":"passed","title":"should have dashboards/risk.html","duration":4.367095999999947,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ar.html","status":"passed","title":"should have dashboards/risk_ar.html","duration":5.496751000000131,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_da.html","status":"passed","title":"should have dashboards/risk_da.html","duration":7.40843000000018,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_de.html","status":"passed","title":"should have dashboards/risk_de.html","duration":4.321300000000065,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_es.html","status":"passed","title":"should have dashboards/risk_es.html","duration":4.387152999999898,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_fi.html","status":"passed","title":"should have dashboards/risk_fi.html","duration":4.537374999999884,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_fr.html","status":"passed","title":"should have dashboards/risk_fr.html","duration":5.620722999999998,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_he.html","status":"passed","title":"should have dashboards/risk_he.html","duration":4.461121999999932,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ja.html","status":"passed","title":"should have dashboards/risk_ja.html","duration":4.569584999999961,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_ko.html","status":"passed","title":"should have dashboards/risk_ko.html","duration":4.605983000000151,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_nl.html","status":"passed","title":"should have dashboards/risk_nl.html","duration":4.6277339999999185,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_no.html","status":"passed","title":"should have dashboards/risk_no.html","duration":4.680482999999867,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_sv.html","status":"passed","title":"should have dashboards/risk_sv.html","duration":4.704177000000072,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Specialised dashboard pages exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Specialised dashboard pages exist for all 14 languages should have dashboards/risk_zh.html","status":"passed","title":"should have dashboards/risk_zh.html","duration":4.841773999999987,"failureMessages":[],"location":{"line":269,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index.html","status":"passed","title":"should have dashboard/index.html","duration":5.2398809999999685,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ar.html","status":"passed","title":"should have dashboard/index_ar.html","duration":4.876369000000068,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_da.html","status":"passed","title":"should have dashboard/index_da.html","duration":4.757697000000007,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_de.html","status":"passed","title":"should have dashboard/index_de.html","duration":4.752216999999973,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_es.html","status":"passed","title":"should have dashboard/index_es.html","duration":4.8059079999998175,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_fi.html","status":"passed","title":"should have dashboard/index_fi.html","duration":5.067397000000028,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_fr.html","status":"passed","title":"should have dashboard/index_fr.html","duration":4.869497000000138,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_he.html","status":"passed","title":"should have dashboard/index_he.html","duration":4.786761999999953,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ja.html","status":"passed","title":"should have dashboard/index_ja.html","duration":6.147860000000037,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_ko.html","status":"passed","title":"should have dashboard/index_ko.html","duration":7.8623099999999795,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_nl.html","status":"passed","title":"should have dashboard/index_nl.html","duration":7.992463000000043,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_no.html","status":"passed","title":"should have dashboard/index_no.html","duration":6.113565999999992,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_sv.html","status":"passed","title":"should have dashboard/index_sv.html","duration":4.783124999999927,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CIA dashboard HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity CIA dashboard HTML files exist for all 14 languages should have dashboard/index_zh.html","status":"passed","title":"should have dashboard/index_zh.html","duration":4.85718299999985,"failureMessages":[],"location":{"line":280,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index.html","status":"passed","title":"should have index.html","duration":4.951189999999997,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ar.html","status":"passed","title":"should have index_ar.html","duration":4.872270999999955,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_da.html","status":"passed","title":"should have index_da.html","duration":4.890415999999959,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_de.html","status":"passed","title":"should have index_de.html","duration":4.914620999999897,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_es.html","status":"passed","title":"should have index_es.html","duration":4.975083999999924,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_fi.html","status":"passed","title":"should have index_fi.html","duration":5.9094239999999445,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_fr.html","status":"passed","title":"should have index_fr.html","duration":5.428592999999864,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_he.html","status":"passed","title":"should have index_he.html","duration":5.049984999999879,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ja.html","status":"passed","title":"should have index_ja.html","duration":5.384671000000026,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_ko.html","status":"passed","title":"should have index_ko.html","duration":5.134763000000021,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_nl.html","status":"passed","title":"should have index_nl.html","duration":5.0388940000000275,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_no.html","status":"passed","title":"should have index_no.html","duration":5.03053900000009,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_sv.html","status":"passed","title":"should have index_sv.html","duration":6.335581000000047,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Main page HTML files exist for all 14 languages"],"fullName":"Dashboard-CSV Data Integrity Main page HTML files exist for all 14 languages should have index_zh.html","status":"passed","title":"should have index_zh.html","duration":5.565860000000157,"failureMessages":[],"location":{"line":290,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for en (default)","status":"passed","title":"should have politician dashboard for en (default)","duration":5.224250999999867,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ar","status":"passed","title":"should have politician dashboard for ar","duration":5.201207999999951,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for da","status":"passed","title":"should have politician dashboard for da","duration":5.139942999999903,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for de","status":"passed","title":"should have politician dashboard for de","duration":5.458919999999807,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for es","status":"passed","title":"should have politician dashboard for es","duration":5.127550000000156,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for fi","status":"passed","title":"should have politician dashboard for fi","duration":5.149812000000111,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for fr","status":"passed","title":"should have politician dashboard for fr","duration":5.179576999999881,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for he","status":"passed","title":"should have politician dashboard for he","duration":5.190237000000025,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ja","status":"passed","title":"should have politician dashboard for ja","duration":5.179787999999917,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for ko","status":"passed","title":"should have politician dashboard for ko","duration":5.349294999999984,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for nl","status":"passed","title":"should have politician dashboard for nl","duration":5.411611999999877,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for no","status":"passed","title":"should have politician dashboard for no","duration":5.3193389999999,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for sv","status":"passed","title":"should have politician dashboard for sv","duration":5.830726000000141,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have politician dashboard for zh","status":"passed","title":"should have politician dashboard for zh","duration":5.344625999999835,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for en (default)","status":"passed","title":"should have political intelligence for en (default)","duration":5.377036000000089,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ar","status":"passed","title":"should have political intelligence for ar","duration":5.529381000000058,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for da","status":"passed","title":"should have political intelligence for da","duration":5.361327000000074,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for de","status":"passed","title":"should have political intelligence for de","duration":5.5581459999998515,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for es","status":"passed","title":"should have political intelligence for es","duration":8.511514999999918,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for fi","status":"passed","title":"should have political intelligence for fi","duration":5.6767979999999625,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for fr","status":"passed","title":"should have political intelligence for fr","duration":5.516658000000007,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for he","status":"passed","title":"should have political intelligence for he","duration":5.3816249999999854,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ja","status":"passed","title":"should have political intelligence for ja","duration":5.549710000000005,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for ko","status":"passed","title":"should have political intelligence for ko","duration":5.412943999999925,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for nl","status":"passed","title":"should have political intelligence for nl","duration":5.462737999999945,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for no","status":"passed","title":"should have political intelligence for no","duration":5.489045999999917,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for sv","status":"passed","title":"should have political intelligence for sv","duration":5.604763000000048,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should have political intelligence for zh","status":"passed","title":"should have political intelligence for zh","duration":5.615072000000055,"failureMessages":[],"location":{"line":304,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index.html","status":"passed","title":"should promote Political Intelligence on index.html","duration":7.106044000000111,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index.html","duration":6.595276999999896,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ar.html","status":"passed","title":"should promote Political Intelligence on index_ar.html","duration":5.876492000000098,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ar.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ar.html","duration":5.8984629999999925,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_da.html","status":"passed","title":"should promote Political Intelligence on index_da.html","duration":5.946803999999929,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_da.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_da.html","duration":6.277471999999989,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_de.html","status":"passed","title":"should promote Political Intelligence on index_de.html","duration":6.579126999999971,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_de.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_de.html","duration":7.164663000000019,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_es.html","status":"passed","title":"should promote Political Intelligence on index_es.html","duration":5.963223999999855,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_es.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_es.html","duration":5.772607999999991,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_fi.html","status":"passed","title":"should promote Political Intelligence on index_fi.html","duration":5.589024000000109,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_fi.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_fi.html","duration":5.902659999999969,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_fr.html","status":"passed","title":"should promote Political Intelligence on index_fr.html","duration":6.1807410000001255,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_fr.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_fr.html","duration":6.01575200000002,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_he.html","status":"passed","title":"should promote Political Intelligence on index_he.html","duration":5.897420999999895,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_he.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_he.html","duration":5.748241999999891,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ja.html","status":"passed","title":"should promote Political Intelligence on index_ja.html","duration":5.824804999999969,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ja.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ja.html","duration":6.546196000000009,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_ko.html","status":"passed","title":"should promote Political Intelligence on index_ko.html","duration":7.142381999999998,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_ko.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_ko.html","duration":7.100973999999951,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_nl.html","status":"passed","title":"should promote Political Intelligence on index_nl.html","duration":6.2275690000001305,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_nl.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_nl.html","duration":6.089079000000083,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_no.html","status":"passed","title":"should promote Political Intelligence on index_no.html","duration":6.0302399999998215,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_no.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_no.html","duration":6.769583999999895,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_sv.html","status":"passed","title":"should promote Political Intelligence on index_sv.html","duration":6.037814000000026,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_sv.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_sv.html","duration":7.133726000000024,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should promote Political Intelligence on index_zh.html","status":"passed","title":"should promote Political Intelligence on index_zh.html","duration":6.9788059999998495,"failureMessages":[],"location":{"line":315,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Political Intelligence localized page coverage"],"fullName":"Dashboard-CSV Data Integrity Political Intelligence localized page coverage should hide decorative Political Intelligence CTA feature emojis on index_zh.html","status":"passed","title":"should hide decorative Political Intelligence CTA feature emojis on index_zh.html","duration":6.369434999999839,"failureMessages":[],"location":{"line":322,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"object_name\" in at least one CSV","status":"passed","title":"should have column \"object_name\" in at least one CSV","duration":6.324971999999889,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"row_count\" in at least one CSV","status":"passed","title":"should have column \"row_count\" in at least one CSV","duration":6.066266999999925,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","stats-loader"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation stats-loader should have column \"status\" in at least one CSV","status":"passed","title":"should have column \"status\" in at least one CSV","duration":6.101924000000054,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.653054999999995,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.917079999999942,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"momentum\" in at least one CSV","status":"passed","title":"should have column \"momentum\" in at least one CSV","duration":6.867897999999968,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.645060000000058,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party1\" in at least one CSV","status":"passed","title":"should have column \"party1\" in at least one CSV","duration":6.319651000000022,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","party-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation party-dashboard should have column \"party2\" in at least one CSV","status":"passed","title":"should have column \"party2\" in at least one CSV","duration":6.076215999999931,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"election_cycle_id\" in at least one CSV","status":"passed","title":"should have column \"election_cycle_id\" in at least one CSV","duration":5.9924899999998615,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.455355999999938,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"cycle_year\" in at least one CSV","status":"passed","title":"should have column \"cycle_year\" in at least one CSV","duration":6.669415999999956,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"overall_performance_score\" in at least one CSV","status":"passed","title":"should have column \"overall_performance_score\" in at least one CSV","duration":6.026382000000012,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"avg_approval_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_approval_rate\" in at least one CSV","duration":6.179578999999876,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"forecast_confidence\" in at least one CSV","status":"passed","title":"should have column \"forecast_confidence\" in at least one CSV","duration":6.123884999999973,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"semester\" in at least one CSV","status":"passed","title":"should have column \"semester\" in at least one CSV","duration":6.174479999999903,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.505288999999948,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","election-cycle"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation election-cycle should have column \"is_pre_election_semester\" in at least one CSV","status":"passed","title":"should have column \"is_pre_election_semester\" in at least one CSV","duration":6.586680999999999,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.650151000000051,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"committee\" in at least one CSV","status":"passed","title":"should have column \"committee\" in at least one CSV","duration":6.970389999999725,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"committee_code\" in at least one CSV","status":"passed","title":"should have column \"committee_code\" in at least one CSV","duration":6.703499999999622,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"productivity_level\" in at least one CSV","status":"passed","title":"should have column \"productivity_level\" in at least one CSV","duration":6.492816000000403,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","committees-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation committees-dashboard should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":6.704643000000033,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.758522999999968,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party1\" in at least one CSV","status":"passed","title":"should have column \"party1\" in at least one CSV","duration":7.589477999999872,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"party2\" in at least one CSV","status":"passed","title":"should have column \"party2\" in at least one CSV","duration":6.422533999999814,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.458662000000004,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"behavioral_assessment\" in at least one CSV","status":"passed","title":"should have column \"behavioral_assessment\" in at least one CSV","duration":9.357338000000254,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"anomaly_classification\" in at least one CSV","status":"passed","title":"should have column \"anomaly_classification\" in at least one CSV","duration":6.416983000000073,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"avg_rebellions\" in at least one CSV","status":"passed","title":"should have column \"avg_rebellions\" in at least one CSV","duration":6.329269999999724,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":6.238329000000249,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"vote_count\" in at least one CSV","status":"passed","title":"should have column \"vote_count\" in at least one CSV","duration":6.236986999999772,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","coalition-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation coalition-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.477606999999807,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":6.530967000000146,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.318087999999989,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"attendance_rate\" in at least one CSV","status":"passed","title":"should have column \"attendance_rate\" in at least one CSV","duration":6.457629999999881,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"documents_produced\" in at least one CSV","status":"passed","title":"should have column \"documents_produced\" in at least one CSV","duration":6.385203999999703,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"ballot_z_score\" in at least one CSV","status":"passed","title":"should have column \"ballot_z_score\" in at least one CSV","duration":6.316165000000183,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"doc_z_score\" in at least one CSV","status":"passed","title":"should have column \"doc_z_score\" in at least one CSV","duration":6.4097099999999045,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.392957999999908,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"is_election_year\" in at least one CSV","status":"passed","title":"should have column \"is_election_year\" in at least one CSV","duration":6.402927999999974,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","seasonal-patterns"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation seasonal-patterns should have column \"seasonal_pattern_classification\" in at least one CSV","status":"passed","title":"should have column \"seasonal_pattern_classification\" in at least one CSV","duration":6.994716000000153,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":8.026988000000074,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"total_ballots\" in at least one CSV","status":"passed","title":"should have column \"total_ballots\" in at least one CSV","duration":6.9632769999998345,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"total_documents\" in at least one CSV","status":"passed","title":"should have column \"total_documents\" in at least one CSV","duration":6.693741999999929,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"is_election_year\" in at least one CSV","status":"passed","title":"should have column \"is_election_year\" in at least one CSV","duration":6.657605000000331,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"avg_party_win_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_party_win_rate\" in at least one CSV","duration":6.48194599999988,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","pre-election"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation pre-election should have column \"avg_party_absence_rate\" in at least one CSV","status":"passed","title":"should have column \"avg_party_absence_rate\" in at least one CSV","duration":6.471495999999661,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"quarter\" in at least one CSV","status":"passed","title":"should have column \"quarter\" in at least one CSV","duration":7.975612000000183,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":8.396318999999949,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"anomaly_severity\" in at least one CSV","status":"passed","title":"should have column \"anomaly_severity\" in at least one CSV","duration":6.980407999999898,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"anomaly_type\" in at least one CSV","status":"passed","title":"should have column \"anomaly_type\" in at least one CSV","duration":7.601652000000286,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","anomaly-detection"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation anomaly-detection should have column \"max_z_score\" in at least one CSV","status":"passed","title":"should have column \"max_z_score\" in at least one CSV","duration":6.7860340000002,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"ministry_name\" in at least one CSV","status":"passed","title":"should have column \"ministry_name\" in at least one CSV","duration":6.611748999999691,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"documents_produced\" in at least one CSV","status":"passed","title":"should have column \"documents_produced\" in at least one CSV","duration":6.775744999999915,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.620473999999831,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":6.928522000000157,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"ministry_code\" in at least one CSV","status":"passed","title":"should have column \"ministry_code\" in at least one CSV","duration":7.340773000000354,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"committee\" in at least one CSV","status":"passed","title":"should have column \"committee\" in at least one CSV","duration":6.805209999999988,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"approval_rate\" in at least one CSV","status":"passed","title":"should have column \"approval_rate\" in at least one CSV","duration":7.643630999999914,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","ministry-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation ministry-dashboard should have column \"total_proposals\" in at least one CSV","status":"passed","title":"should have column \"total_proposals\" in at least one CSV","duration":6.891933000000336,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","risk-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation risk-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.791274000000158,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"person_id\" in at least one CSV","status":"passed","title":"should have column \"person_id\" in at least one CSV","duration":6.753603999999996,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"first_name\" in at least one CSV","status":"passed","title":"should have column \"first_name\" in at least one CSV","duration":6.860855000000356,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"last_name\" in at least one CSV","status":"passed","title":"should have column \"last_name\" in at least one CSV","duration":7.0119380000001,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.741913000000295,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"risk_score\" in at least one CSV","status":"passed","title":"should have column \"risk_score\" in at least one CSV","duration":6.891442000000097,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"experience_level\" in at least one CSV","status":"passed","title":"should have column \"experience_level\" in at least one CSV","duration":7.157199999999648,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":6.962225000000217,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","politician-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation politician-dashboard should have column \"influence_classification\" in at least one CSV","status":"passed","title":"should have column \"influence_classification\" in at least one CSV","duration":6.854021999999986,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"party\" in at least one CSV","status":"passed","title":"should have column \"party\" in at least one CSV","duration":6.893285999999989,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"year\" in at least one CSV","status":"passed","title":"should have column \"year\" in at least one CSV","duration":7.570553000000018,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"risk_level\" in at least one CSV","status":"passed","title":"should have column \"risk_level\" in at least one CSV","duration":6.978935999999976,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"politician_count\" in at least one CSV","status":"passed","title":"should have column \"politician_count\" in at least one CSV","duration":7.973789000000124,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"status\" in at least one CSV","status":"passed","title":"should have column \"status\" in at least one CSV","duration":6.966973000000053,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"alignment_rate\" in at least one CSV","status":"passed","title":"should have column \"alignment_rate\" in at least one CSV","duration":6.9802480000003015,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"ministry_name\" in at least one CSV","status":"passed","title":"should have column \"ministry_name\" in at least one CSV","duration":7.024621000000025,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Dashboard CSV column validation","cia-dashboard"],"fullName":"Dashboard-CSV Data Integrity Dashboard CSV column validation cia-dashboard should have column \"effectiveness_assessment\" in at least one CSV","status":"passed","title":"should have column \"effectiveness_assessment\" in at least one CSV","duration":7.045300000000225,"failureMessages":[],"location":{"line":412,"column":11},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation extraction_summary_report.csv should have at least 100 rows","status":"passed","title":"extraction_summary_report.csv should have at least 100 rows","duration":7.230005999999776,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation should contain view entries matching dashboard source views","status":"passed","title":"should contain view entries matching dashboard source views","duration":7.585802000000058,"failureMessages":[],"location":{"line":433,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","Extraction summary row count validation"],"fullName":"Dashboard-CSV Data Integrity Extraction summary row count validation all source views should have success status","status":"passed","title":"all source views should have success status","duration":7.767111000000114,"failureMessages":[],"location":{"line":458,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Dashboard-CSV Data Integrity","CSV data quality summary"],"fullName":"Dashboard-CSV Data Integrity CSV data quality summary should report all empty/header-only CSV files in cia-data","status":"passed","title":"should report all empty/header-only CSV files in cia-data","duration":159.87970300000006,"failureMessages":[],"location":{"line":488,"column":5},"meta":{},"tags":[]}],"startTime":1787953676247,"endTime":1787953678224.8796,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-csv-integrity.test.js"},{"assertionResults":[{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant file exists","status":"passed","title":"file exists","duration":5.584515999999894,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.9091519999999491,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":0.7889569999999821,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.6176759999998467,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.7056410000000142,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.4060320000000956,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.9796739999999318,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.079042999999956,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.6419619999999213,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.7015939999998864,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.1348449999998138,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.6837800000000698,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.1827740000001086,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant file exists","status":"passed","title":"file exists","duration":0.7175640000000385,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5526449999999841,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":0.5456309999999576,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5343809999999394,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.4841670000000704,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.9062870000000203,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6310419999999795,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.860251000000062,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.48505699999986973,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.4790469999998095,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.0148099999998976,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.5541279999999915,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.7488319999999931,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant file exists","status":"passed","title":"file exists","duration":0.687246999999843,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5627130000000307,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":0.6950810000000729,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5455919999999423,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.4652009999999791,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.6646040000000539,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6292080000000624,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.6525019999999131,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.4649410000001808,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.39566100000001825,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.8879930000000513,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.4352850000000217,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.6662069999999858,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant file exists","status":"passed","title":"file exists","duration":0.6233670000001439,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.6256809999999859,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":0.6081380000000536,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.46696399999996174,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.44561399999997775,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.7585400000000391,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.9077990000000682,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.6585930000001099,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.55217400000015,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.6992099999999937,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.7199980000000323,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.5457709999998315,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.7029569999999694,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant file exists","status":"passed","title":"file exists","duration":0.6372730000000502,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.5901449999998931,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":0.6571199999998498,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.5612409999998818,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.6168949999998858,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":0.8702800000000934,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.6667180000001736,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":0.8095550000000458,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":0.6625500000000102,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":0.6478730000001178,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":0.9098730000000614,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":0.733743000000004,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":0.8449120000000221,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant file exists","status":"passed","title":"file exists","duration":0.8757689999999911,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":0.8308959999999388,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":0.907369000000017,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":0.9241709999998875,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":0.7831869999999981,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.0355289999999968,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":0.958515000000034,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.3211929999999938,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":5.197721999999885,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.2743169999998827,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.2525559999999132,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.0166739999999663,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.5608620000000428,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant file exists","status":"passed","title":"file exists","duration":1.6466319999999541,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.4956199999999171,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":1.577203000000054,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.4079659999999876,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.5975510000000668,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.5343330000000606,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.6445690000000468,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.9007790000000568,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.6141419999999016,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.5167089999999916,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.0299609999999575,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.6659590000001572,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.8588709999999082,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant file exists","status":"passed","title":"file exists","duration":1.863788999999997,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.709831000000122,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":1.7675460000000385,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.9644069999999374,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.0703370000001087,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.2393070000000534,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.5188730000002124,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.7247889999998733,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.3906939999999395,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.4630389999999807,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.2190550000000258,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.965951000000132,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.4072570000000724,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant file exists","status":"passed","title":"file exists","duration":1.6230490000000373,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":1.411051999999927,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":1.5268490000000838,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":1.48824599999989,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.5532080000000406,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.7222649999998794,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.5111090000000331,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":1.9246239999999943,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.6657290000000557,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.5424579999998969,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":1.8620060000000649,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.60564700000009,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":1.8438120000000708,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant file exists","status":"passed","title":"file exists","duration":1.9791760000000522,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.0815979999999854,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":2.0231280000000424,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":1.8660239999999249,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":1.6718610000000353,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":1.987280999999939,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":1.8535099999999147,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.0066770000000815,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":1.892042000000174,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":1.9059790000001158,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.250874000000067,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":1.8891370000001189,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.0288980000000265,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant file exists","status":"passed","title":"file exists","duration":2.1370210000000043,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.587795000000142,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":2.219184000000041,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":3.711319000000003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.1509970000001886,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.3849250000000666,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.9832949999999983,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.3095240000000103,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.0584250000001703,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.065746999999874,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.2354659999998603,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.0185089999999946,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.237468999999919,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant file exists","status":"passed","title":"file exists","duration":4.1929499999998825,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.198059999999941,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":3.9671270000001186,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.7713750000000346,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.467139999999972,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.5235650000001897,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.1899000000000797,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.63394100000005,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.2285430000001725,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.1739500000001044,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.383192000000008,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.223273000000063,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.330112000000099,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant file exists","status":"passed","title":"file exists","duration":2.3968979999999647,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.293354000000136,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":2.3720210000001316,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.2835359999999127,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.305717000000186,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.481375000000071,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.42470000000003,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.5469080000000304,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.4545960000000377,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.4119160000000193,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.64716599999997,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.518555000000106,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":2.619004000000132,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant file exists","status":"passed","title":"file exists","duration":2.5988559999998415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.5828859999999167,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":2.6590989999999692,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.646695000000136,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.555114000000003,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.7440469999999095,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.5567369999998846,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.7050140000001193,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant exposes container #party-dashboard","status":"passed","title":"exposes container #party-dashboard","duration":2.6971300000000156,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.627420000000029,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":2.811914999999999,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.688574000000017,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'parties'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'parties' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.0383690000001025,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant file exists","status":"passed","title":"file exists","duration":6.1697619999999915,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.856062000000065,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":3.6150780000000395,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":2.735612000000174,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.748886999999968,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":2.9856700000000274,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":2.831863000000112,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":2.9384419999998954,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":2.820271000000048,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":2.8572589999998854,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.1161349999999857,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":2.9369890000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.309989999999971,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant file exists","status":"passed","title":"file exists","duration":3.1643349999999373,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":2.988534999999956,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":2.9808909999999287,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.0126910000001317,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":2.9784060000001773,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":3.1913549999999304,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.172840999999835,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.188178999999991,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.104863999999907,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.1057250000001204,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.7255250000000615,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.519068999999945,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.2502759999999853,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant file exists","status":"passed","title":"file exists","duration":3.3371279999998933,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.1732419999998456,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":3.1599160000000666,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.1750540000000456,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.067395000000033,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.231818000000203,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.189476999999897,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.3880730000000767,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.9997880000000805,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.100807000000032,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.5343869999999242,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.3607220000001234,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.494331999999986,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant file exists","status":"passed","title":"file exists","duration":3.495445000000018,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.422888000000057,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":3.4940220000000863,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.43507099999988,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.405715999999984,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":3.689728000000059,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.5069260000000213,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.639944999999898,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.4942819999998846,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.509409999999889,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":3.802169000000049,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.544685999999956,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.661254999999983,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant file exists","status":"passed","title":"file exists","duration":3.693504999999959,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.598207000000002,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":4.7521979999999076,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":3.8033009999999194,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.9236960000000636,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.8920640000001185,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.961188999999877,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":3.8758960000000116,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":3.808631000000105,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.7929810000000543,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.004989000000023,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.7857380000000376,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":3.9308599999999387,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant file exists","status":"passed","title":"file exists","duration":3.9425920000001042,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":3.8409010000000308,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":3.875827000000072,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.01876500000003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":3.8963350000001356,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.057117000000062,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":3.86855300000002,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.056415000000015,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.04624600000011,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":3.925028999999995,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.200033000000076,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":3.9785890000000563,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.1703379999999015,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant file exists","status":"passed","title":"file exists","duration":4.179826000000048,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.06552099999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":4.031789000000117,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.117451000000074,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.298344999999927,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.310009000000036,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.186909000000014,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.283400000000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.242512999999917,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.379991000000018,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.361054999999851,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.179084999999986,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.331549999999879,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant file exists","status":"passed","title":"file exists","duration":5.54738599999996,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.296573999999964,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":4.28372000000013,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.2866760000001705,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.339384999999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.5735930000000735,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.382344999999987,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.575818000000027,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.416268999999829,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.400059000000056,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.632652999999891,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.500144999999975,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.813043999999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant file exists","status":"passed","title":"file exists","duration":7.376330000000053,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.560087999999951,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":4.665906000000177,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":4.531684000000041,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.566641000000118,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":4.773867999999993,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":4.583251000000018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":4.723543999999947,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.761403999999857,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.9264630000000125,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":4.92081300000018,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.731839000000036,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.821537000000035,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant file exists","status":"passed","title":"file exists","duration":4.843478000000005,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.891939000000093,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":5.147407999999814,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":4.968372000000045,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":4.907306999999946,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.018526000000065,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.116172000000006,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.321099999999888,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":4.867684000000054,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":4.7816519999998945,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.00396899999987,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":4.837327000000187,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":4.985443999999916,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant file exists","status":"passed","title":"file exists","duration":5.2359939999998915,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":4.945770000000039,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":4.93500999999992,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":5.010060999999951,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.036128999999846,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.2056760000000395,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.014828999999963,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.120216999999911,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.017112999999881,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.041789999999992,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.2047039999999924,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.061476999999968,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.215515000000096,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant file exists","status":"passed","title":"file exists","duration":5.853388999999879,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.1246849999999995,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":5.384180999999899,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.404479999999921,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.172614999999951,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.3258710000000065,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.17506000000003,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.281388000000106,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.188503999999966,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.175761000000193,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.362843000000112,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.316193999999996,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.376856000000089,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant file exists","status":"passed","title":"file exists","duration":5.400400999999874,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.345829000000094,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":5.308369000000312,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.395572999999786,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.343283999999585,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.628038000000288,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.940813000000162,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.598461999999927,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.42890400000033,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.455815000000257,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.611816999999974,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":5.435055999999804,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":5.6029209999996965,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant file exists","status":"passed","title":"file exists","duration":5.601848999999675,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.5297129999999015,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":5.551343999999972,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.494436999999834,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.545774000000165,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":5.811600999999882,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.59413399999994,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.762399000000187,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant exposes container #election-cycle-dashboard","status":"passed","title":"exposes container #election-cycle-dashboard","duration":5.70493099999976,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.622036000000207,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":5.950130999999601,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.703671000000213,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'election-cycle'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'election-cycle' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.782208000000082,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant file exists","status":"passed","title":"file exists","duration":6.069183000000066,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":5.753322000000026,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":5.766135999999733,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":5.756929000000127,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":5.801832999999988,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.007317999999941,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":5.831869000000097,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":5.9373860000000604,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.1128749999998035,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":5.818903999999748,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.6895470000004025,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.475178000000142,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.015968000000157,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant file exists","status":"passed","title":"file exists","duration":8.014966999999615,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.315517,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":6.617189000000053,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.482057000000168,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.088940000000093,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.188216000000011,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.122323000000051,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":6.219554000000244,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.068751999999677,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.117804999999862,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.506300999999894,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.234643000000233,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.292723999999907,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant file exists","status":"passed","title":"file exists","duration":6.420832000000246,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.218263000000206,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":6.512232999999924,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.454056000000037,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.929583999999977,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.694282999999814,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.334299999999985,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":6.489149999999881,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.395935000000009,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.557436999999936,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.081970000000183,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.924854999999752,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.645172000000002,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant file exists","status":"passed","title":"file exists","duration":6.954040000000077,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.468951999999717,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":6.574528999999984,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.995701000000281,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.322961000000305,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.737246000000141,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.9294959999997445,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.5501359999998385,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.810060000000249,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.878810000000158,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.441835999999967,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.296360999999706,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":6.814728999999716,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant file exists","status":"passed","title":"file exists","duration":6.751119999999901,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.612169999999878,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":6.566824999999881,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.561114000000089,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.795473000000129,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":6.714310999999725,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.82598999999982,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":9.266830000000027,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":6.661321999999927,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":6.620796000000155,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":6.808358000000226,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":6.7354999999997744,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.10097500000029,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant file exists","status":"passed","title":"file exists","duration":7.2188960000003135,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":6.933620999999675,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":6.8925649999996494,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.840748000000076,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":6.842711000000236,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.017607999999655,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":6.9079139999998915,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.03727600000002,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.75532499999963,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.3144470000002,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":7.337568000000374,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.110803999999916,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.17682700000023,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant file exists","status":"passed","title":"file exists","duration":7.18872999999985,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.0747660000001815,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":7.069275999999718,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":6.969309000000067,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.0407319999999345,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.2100089999999,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.130350000000362,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.482809999999972,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":7.1417710000000625,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.585727000000134,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.630299000000377,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.28823599999987,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.31832200000008,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant file exists","status":"passed","title":"file exists","duration":7.449497000000065,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.7948340000002645,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":7.250845000000027,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":8.503551000000243,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.993026999999984,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.609336999999869,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.295950000000175,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.521671999999853,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":7.35062199999993,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.289262000000235,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":9.811940999999933,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":7.597013999999945,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":7.61452700000018,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant file exists","status":"passed","title":"file exists","duration":7.563602000000174,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":7.739510000000337,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":7.806826999999885,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":7.636897999999746,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.577898000000005,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":7.91789400000016,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":7.57314899999983,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":7.75420800000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.52710500000012,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.761406000000079,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":9.224872000000232,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.132416999999805,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":9.08001000000013,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant file exists","status":"passed","title":"file exists","duration":8.186227000000144,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.196695999999974,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":7.979580000000169,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":7.777141000000029,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":7.9477609999999,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.30284599999959,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":8.629566999999952,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.595233000000007,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.636920999999802,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.220330000000104,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.491157000000385,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.192348000000038,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.267648999999892,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant file exists","status":"passed","title":"file exists","duration":8.872410999999829,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.67631399999982,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":8.70577000000003,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":9.106009000000086,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.848035999999865,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.963541999999961,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.980275999999776,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.126980999999887,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.45061399999986,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.017382999999882,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.71481700000004,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.079748000000109,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.152283000000352,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant file exists","status":"passed","title":"file exists","duration":8.153706000000057,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":8.009846999999809,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":8.085528000000068,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":8.143716999999924,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":8.704538000000412,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":8.50760900000023,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.709711999999854,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":8.48483699999997,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":8.310910000000149,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.517125999999735,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.506937000000107,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.615741000000071,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":8.456023000000187,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant file exists","status":"passed","title":"file exists","duration":9.655097000000296,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.116979999999785,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":9.945020000000113,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":9.270878000000266,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.421530000000075,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.73567200000025,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.279195999999956,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.047982999999931,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":9.182532000000265,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":8.912676999999803,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":8.974742999999762,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":8.649073999999928,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":9.640359999999873,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant file exists","status":"passed","title":"file exists","duration":10.07575399999996,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.112313000000086,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":10.899286999999731,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.153961999999865,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.657862000000023,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.735406999999668,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.323941999999988,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.919423999999708,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant exposes container #committee-dashboard","status":"passed","title":"exposes container #committee-dashboard","duration":11.380667999999787,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.833494999999857,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.89388800000006,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.335683999999674,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'committees'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'committees' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.514713999999913,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant file exists","status":"passed","title":"file exists","duration":11.682032000000163,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.34841200000028,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":12.61193299999968,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.338290000000143,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.490268000000015,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.066815000000133,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.645178000000215,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.710493999999926,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.395900999999867,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.3042989999999,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.808103000000301,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.02184299999999,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.599981000000298,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant file exists","status":"passed","title":"file exists","duration":13.874397000000044,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.191873000000214,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":13.425686999999925,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":14.075313000000278,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.16235400000005,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.681641000000127,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.041519999999764,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":9.934389999999894,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":9.8189339999999,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":9.393327000000227,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.132254999999986,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.547218999999586,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.427994000000126,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant file exists","status":"passed","title":"file exists","duration":9.745134999999664,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.36461300000019,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":9.787505000000237,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.385377000000062,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.599211999999625,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.685743999999886,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":10.154982000000018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.446986999999808,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.956941999999799,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.257564000000002,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.21516500000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.869458000000122,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.229580000000169,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant file exists","status":"passed","title":"file exists","duration":12.700448999999935,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.703392000000349,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":12.926271999999699,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.718848999999864,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.789588000000549,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.96118000000024,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.778832999999395,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.434000000000196,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.340583000000152,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.78341999999975,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.080485000000408,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.400870000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.243209999999635,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant file exists","status":"passed","title":"file exists","duration":10.196030000000064,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":9.95848500000011,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":10.095711999999367,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.187083000000712,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":9.908722999999554,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":9.821136999999908,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.714759000000413,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.413027000000511,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.99810400000024,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.062299000000166,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":10.614392999999836,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.708340999999564,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.543711000000258,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant file exists","status":"passed","title":"file exists","duration":10.27955699999984,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.195408000000498,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":11.15870300000006,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.233764999999948,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.851740000000063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.90712799999983,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.157635999999911,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.678162000000157,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":12.704506999999467,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.746032000000014,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.183288999999604,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":10.627747999999883,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":10.10738399999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant file exists","status":"passed","title":"file exists","duration":11.969350000000304,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.552539000000252,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":10.191541000000143,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":10.245662000000266,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":10.313610000000153,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":10.271882000000005,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":9.98178900000039,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":10.116862000000765,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":10.06840100000045,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":10.301548000000366,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.438458000000537,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.005678000000444,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.176249999999527,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant file exists","status":"passed","title":"file exists","duration":14.133712999999261,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.59212000000025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":14.234581000000617,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":14.662030999999843,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":16.16233100000045,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.70425300000079,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.73728200000005,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.793157000000065,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":14.733675999999832,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.7003509999995,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.171969999999419,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.542271000000255,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.977466999999706,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant file exists","status":"passed","title":"file exists","duration":11.372472999999445,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":10.723006000000169,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":11.457070999999814,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.14218399999936,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.000696000000062,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":12.434911999999713,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.342059000000518,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":11.003061000000343,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":13.098904999999831,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.933013999999275,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.5802020000001,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":11.167569000000185,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.18873799999983,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant file exists","status":"passed","title":"file exists","duration":11.212251999999353,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":11.304234000000179,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":12.396338999999898,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":11.773823999999877,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.85393600000043,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.715564999999515,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.87887099999989,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.209350000000086,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":12.462743000000046,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.72315400000025,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.840634999999565,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.433431000000382,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.508826000000226,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant file exists","status":"passed","title":"file exists","duration":16.85868400000072,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.016042000000198,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":12.76089199999933,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":14.070784000000458,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.888224999999693,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":12.387773999999808,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":11.547249000000193,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.642039000000295,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.048625999999786,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.224906000000374,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":11.536420000000362,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.516665000000103,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":11.695356999999603,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant file exists","status":"passed","title":"file exists","duration":11.426413999999568,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.061091999999917,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":14.529082000000017,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.920427999999447,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":11.19948899999963,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":11.578968999999233,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.454838999999993,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.773568000000523,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":16.707781000000068,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.69528799999989,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.050365000000056,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.38029000000006,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":16.248281000000134,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant file exists","status":"passed","title":"file exists","duration":14.140636000000086,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.812442999999803,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":16.101427000000513,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.418100999999297,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":18.431219000000056,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.524145999999746,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":12.474395999999615,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":12.14625100000012,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.788601999999628,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":11.818657999999232,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.379417999999532,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.648791999999958,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.27749700000004,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant file exists","status":"passed","title":"file exists","duration":13.262171000000308,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.872701000000234,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":12.361304000000018,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":11.537390999999843,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.660805000000437,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.391773000000285,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.24231299999974,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.156882999999652,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant exposes container #coalition-dashboard","status":"passed","title":"exposes container #coalition-dashboard","duration":11.94116699999995,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.874284000000443,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":12.811627000000044,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":12.126152999999249,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'coalitions'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'coalitions' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.018541999999798,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant file exists","status":"passed","title":"file exists","duration":12.607445000000553,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.774501999999302,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":13.484857999999804,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":12.693445999999312,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":12.656928000000335,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":13.89611799999966,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.509756999999809,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.341765000000123,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.61265899999944,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.654386999999588,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":16.26451199999974,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":16.426744999999755,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":14.548408999999992,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant file exists","status":"passed","title":"file exists","duration":13.668580999999904,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.9113440000001,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":14.09519999999975,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.454642000000604,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.67912999999953,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.24789299999975,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.910737000000154,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.887521000000561,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":12.735133999999562,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.770950000000084,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.946367000000464,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.186902000000373,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":12.664040999999997,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant file exists","status":"passed","title":"file exists","duration":12.55505599999924,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":12.24750099999983,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":12.121463999999833,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":13.380872999999156,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.18670099999963,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.444424999999683,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.801339999999982,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.164840999999797,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.307705000000169,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.66010599999936,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.718680000000859,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.347671000000446,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.06613500000003,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant file exists","status":"passed","title":"file exists","duration":16.58659499999976,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":14.424696999999469,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":15.103106999999909,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.760737999999947,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.048123999999916,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.4811380000001,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.98764300000039,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.007215000000542,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.22141399999964,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":12.817508000000089,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.39966800000002,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.719716999999946,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.594548000000032,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant file exists","status":"passed","title":"file exists","duration":15.36001800000031,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":17.55666100000053,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":17.043009999999413,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.380263000000014,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.314447000000655,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.499544000000242,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.286826000000474,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":16.552942000000257,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":16.5274330000002,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.54388999999992,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.899706000000151,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.32449699999961,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.412443000000167,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant file exists","status":"passed","title":"file exists","duration":14.577061999999387,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.440844999999172,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":13.442508000000089,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.047787999999855,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.82860299999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.05269799999951,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.400614000000132,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":13.899633999999423,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.02502800000002,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":13.152554999999666,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":13.94931700000052,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.67161699999997,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":14.105219000000034,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant file exists","status":"passed","title":"file exists","duration":17.323975999999675,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.40972099999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":14.341310999999223,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.956605000000309,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.718998000000283,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.75144900000032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":15.60725100000036,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.312799999999697,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":16.69140100000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":14.976229000000785,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":15.858420999999908,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.548045000000457,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":17.179565999999795,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant file exists","status":"passed","title":"file exists","duration":22.77232600000025,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.684590000000753,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":22.196859000000586,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.58010700000068,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":16.32166799999959,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.71050699999978,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.348305999999866,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":17.165608999999677,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":21.453377000000728,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.33126799999991,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.897957000000133,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.023019000000204,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":15.270641000000069,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant file exists","status":"passed","title":"file exists","duration":18.129633999999896,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.701399000000492,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":20.32504499999959,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":21.264814000000115,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":19.128454000000602,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.452164999999695,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.958706999999777,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.980016999999862,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":19.483518000000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.76143200000024,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.76734900000065,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":16.825260999999955,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.464390999999523,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant file exists","status":"passed","title":"file exists","duration":14.808125000000473,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.466447999999218,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":14.208211999999548,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":13.889114000000518,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":13.629979000000276,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.267243999999664,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.32978699999967,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":15.336323999999877,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.778900000000249,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.404763999999886,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.21525500000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":13.751698000000033,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.647461999999905,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant file exists","status":"passed","title":"file exists","duration":16.58210599999984,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.98401399999966,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":20.291040999999495,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":15.985139000000345,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":14.543679999999767,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.141647000000376,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":13.749371999999312,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.201830000000882,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":13.788935999999921,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":15.505850999999893,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":14.122512000000825,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":14.692027000000053,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":13.97417299999961,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant file exists","status":"passed","title":"file exists","duration":14.053191999999399,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":13.935410999999476,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":13.649506000000656,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":13.871851999999308,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.103729000000385,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":14.735219000000143,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":14.113524999998845,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":14.61449200000061,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":14.439865999998801,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":17.84141500000078,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.761916999999812,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.478046000000177,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":20.09809899999891,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant file exists","status":"passed","title":"file exists","duration":18.572532999998657,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.355219999999463,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":15.115780999998606,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.904372000000876,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.168440999999802,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":22.29414100000031,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.94550799999888,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":22.200474999999642,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":22.115676999999778,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.836090999999215,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.839152000000468,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":21.783955999999307,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.59777000000031,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant file exists","status":"passed","title":"file exists","duration":23.77030399999967,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.434729000000516,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":18.10149099999944,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":17.158035000000382,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.729570000001331,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":15.273616000000402,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":18.927057000000787,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.57621400000062,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant exposes container #seasonal-patterns-dashboard","status":"passed","title":"exposes container #seasonal-patterns-dashboard","duration":23.02700299999924,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.071586000000025,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.22853600000053,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.447925000000396,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'seasonal-patterns'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'seasonal-patterns' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.924122000000352,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant file exists","status":"passed","title":"file exists","duration":17.00834500000019,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":15.950002999999924,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":15.834146000001056,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":15.217842000000019,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":15.379585000000588,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":18.3765970000004,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.080109000000448,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.224435999998605,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.444064000001163,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":22.00010999999904,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":23.914795999999114,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.83068699999967,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":19.65678300000036,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant file exists","status":"passed","title":"file exists","duration":18.235421999999744,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":17.832236999998713,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":21.01561700000093,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.55096500000036,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.017594999999346,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.668163000000277,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.885991999999533,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.020680999999968,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":21.249635000000126,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.96613399999842,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.355406000000585,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.011011999999027,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.22243900000103,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant file exists","status":"passed","title":"file exists","duration":21.14426800000001,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":20.37198200000057,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":23.85446299999967,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":21.163753999999244,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.256097999999838,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.241769000000204,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":16.769937999999456,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":17.42348200000015,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":16.48862100000042,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":18.864921000000322,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.644044999999096,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.725619000000734,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.206826999999976,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant file exists","status":"passed","title":"file exists","duration":24.407076999999845,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":24.667765000000145,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":25.15258300000096,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.687527999998565,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":19.057259999999587,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":16.532664000000295,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":17.348641999999018,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.07331299999896,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":16.955464999999094,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":16.230427999998938,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.05750799999987,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.699268000000302,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":21.84271600000102,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant file exists","status":"passed","title":"file exists","duration":19.29412400000001,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.972858999999517,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":26.63589900000079,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":31.066375000000335,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.645770000000994,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.1991450000005,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.64671499999895,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":25.68474900000001,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":26.44200699999965,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.601634999999078,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.24454499999956,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.428466999999728,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.742737999999008,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant file exists","status":"passed","title":"file exists","duration":23.819375999999465,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.624377999998615,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":21.323131999999532,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.235381000000416,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.8972700000013,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":24.63527400000021,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.07497400000102,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.768659999999727,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":23.828961999999592,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.334987999998702,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.96236499999941,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":17.757102999999915,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.778073999999833,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant file exists","status":"passed","title":"file exists","duration":23.88058899999851,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":24.37721000000056,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":24.711155000000872,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.702022999999826,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.66153900000063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.1053780000002,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.89282699999967,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.049589000000196,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":20.087657000000036,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.024319999998625,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.750631000000794,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.150299999999334,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":21.974600000001374,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant file exists","status":"passed","title":"file exists","duration":21.481837999999698,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":19.13102500000059,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":18.475377000000663,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.727429999999003,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.504076999999597,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.789520999998786,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.794754000000466,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.275981999999203,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.792113999999856,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.16852800000015,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":19.983060999998997,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":20.774242000001323,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.527946000000156,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant file exists","status":"passed","title":"file exists","duration":21.968278000000282,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.373193999999785,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":21.112366000001202,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":20.834585000000516,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":18.866700000000492,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":17.73212599999897,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":18.62636999999995,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":18.609087999999247,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":19.136375000000044,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.710119999999733,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":20.367640999998912,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.37229500000103,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.111125999999786,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant file exists","status":"passed","title":"file exists","duration":23.115146000000095,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.841001000000688,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":25.618693999998868,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":26.44474099999934,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.388074999998935,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.318978000001152,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":22.925771000000168,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":22.55961599999864,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":21.921400999999605,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.88905700000032,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.19219499999963,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.037437999999383,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.76250599999912,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant file exists","status":"passed","title":"file exists","duration":23.785079999999653,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.860097999999198,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":24.520237000000634,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":22.794025000001056,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.567094999998517,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.087714999999662,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":20.634030000001076,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.04418799999985,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":22.131024000000252,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.612286999999924,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.46215900000061,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.417123999999603,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.045170999999755,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant file exists","status":"passed","title":"file exists","duration":21.66256599999906,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":21.657326999998986,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":22.32643900000039,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":19.510755999999674,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.0992040000001,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.390581000001475,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.439727000000858,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.797223999999915,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":25.521342000000004,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":20.699812999999267,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.616151000000173,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.97858400000041,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":22.709476999998515,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant file exists","status":"passed","title":"file exists","duration":20.320002000000386,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.81548500000099,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":25.312651000000187,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.71130500000072,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":20.87140400000135,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.53309900000022,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.749714999999924,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":20.11882499999956,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":18.485286000000997,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":19.020699000000604,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.70262300000104,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":19.3493440000002,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":19.09718200000134,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant file exists","status":"passed","title":"file exists","duration":19.590745999999854,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":19.25097999999889,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":22.32946499999889,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.281166999999186,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":21.682973999999376,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.792797000000064,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.648333999999522,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":21.653057999999874,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant exposes container #pre-election-dashboard","status":"passed","title":"exposes container #pre-election-dashboard","duration":24.17417899999964,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":25.37051900000006,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":23.036228999999366,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":18.728551999998672,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'pre-election'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'pre-election' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":18.394836999999825,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant file exists","status":"passed","title":"file exists","duration":21.653630000000703,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":18.856481000000713,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":18.782812999999805,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":18.125201999999263,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":17.64955100000043,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":19.142006000000038,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":19.96201099999962,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":18.086018999998487,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":17.782439999999042,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":18.012179999999717,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":18.337799999999334,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":21.4316230000004,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.48256399999991,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant file exists","status":"passed","title":"file exists","duration":24.226587000001018,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.21958199999972,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":24.468980999999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.58727799999906,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":23.22615399999995,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":22.682404999999562,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":25.59581100000105,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.533503000000564,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":24.136868999999933,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.984459000001152,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":21.221089000000575,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.100289000001794,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.163375000000087,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant file exists","status":"passed","title":"file exists","duration":30.677958000000217,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.489653000000544,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":29.860758000000715,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.298375000000306,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.784082000000126,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.832965999999942,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.29860000000008,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.651098000000275,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.312431999998807,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":28.977615000001606,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":30.652351000000635,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.637402999998812,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.259626999999455,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant file exists","status":"passed","title":"file exists","duration":30.77987899999971,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.8082200000008,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":29.15642900000057,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":30.910804999999527,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.14925100000073,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.69467600000098,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.563195000000633,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.266148000000612,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":19.82245999999941,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":21.22679000000062,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":22.370412000000215,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":25.829728999999134,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.601543000000675,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant file exists","status":"passed","title":"file exists","duration":29.670452000000296,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":30.15764399999898,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":29.973479000000225,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":31.489767999999458,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.194644000001063,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":30.70970800000032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.788040999999794,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.337725999999748,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.85200199999963,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.126612999998542,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.6950680000009,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.097405999998955,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":28.277352999999493,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant file exists","status":"passed","title":"file exists","duration":28.08184699999947,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":30.50080700000035,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":27.407795000000988,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.621236999999383,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.86908399999993,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.0245730000006,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.85715899999923,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.204302000000098,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.804261999999653,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.94497600000068,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.001498000001448,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.65607000000091,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":26.87439599999925,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant file exists","status":"passed","title":"file exists","duration":31.152917999999772,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":31.05563600000096,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":28.438485000000583,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.174714999999196,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.71763699999974,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":20.64926899999955,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":21.927772999999434,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.983275000000503,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":28.66393699999935,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.85468899999978,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":27.81557900000007,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.778419000000213,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.832099000001108,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant file exists","status":"passed","title":"file exists","duration":25.30192100000022,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.22793300000012,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":25.520220000000336,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":27.53215700000146,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.39429199999904,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.513788000000204,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":28.54967300000135,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.004057000000103,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":28.2606420000011,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.32517999999982,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.66475100000025,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.312332999999853,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.867960999999923,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant file exists","status":"passed","title":"file exists","duration":24.744737999999415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.22333400000025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":28.362081999999646,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.0795049999997,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.07835999999952,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.07912100000067,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":30.48454700000002,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.898702000000412,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":31.5785649999998,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.835440999999264,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":31.83575700000074,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.699162999999317,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":28.38486499999999,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant file exists","status":"passed","title":"file exists","duration":31.091832999998587,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":31.491141000000425,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":31.014259000001402,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":32.80594300000121,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.740475999999035,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.95526500000051,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.773794999999154,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.31388700000025,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.0002970000005,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":26.932584999998653,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":26.982357999999294,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.90686199999982,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.969531999999163,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant file exists","status":"passed","title":"file exists","duration":28.655329999999594,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":28.01361999999972,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":29.609268000001975,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":27.969005000002653,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.352671000000555,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.974269999998796,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.447007999999187,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":33.6128839999983,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":32.33504100000209,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.50252499999988,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":33.882730000001175,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":31.51414400000067,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":30.211834999998246,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant file exists","status":"passed","title":"file exists","duration":30.155320000001666,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.60289499999999,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":30.13869799999884,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.206460999997944,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.27385900000081,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.391155999997864,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.20708800000284,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.495359000000462,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.15384400000039,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":30.974614000002475,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":28.575982000002114,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.087664999999106,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":24.598674000000756,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant file exists","status":"passed","title":"file exists","duration":23.015118999999686,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":22.286974999999074,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":24.13921400000254,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.34796500000084,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.93742199999906,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.384674000000814,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":33.125952000002144,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":34.980673999998544,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":32.83335299999817,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.26253500000166,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":32.23569399999906,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":32.401255000000674,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.186413000003085,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant file exists","status":"passed","title":"file exists","duration":32.251554000002216,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.897367999998096,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":32.311516999998275,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":29.914569000000483,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.79128600000331,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":32.59716199999821,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":30.857474000000366,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.373632999999245,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant exposes container #anomaly-detection-dashboard","status":"passed","title":"exposes container #anomaly-detection-dashboard","duration":29.20178400000077,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":31.283151999999973,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.301139999999577,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":28.585109999999986,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'anomaly-detection'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'anomaly-detection' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.06315899999754,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant file exists","status":"passed","title":"file exists","duration":31.667310999997426,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.232631999999285,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":26.402704000000085,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.30297999999675,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.63484299999982,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.042051000000356,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.138043000002654,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.451780999999755,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":28.902874999999767,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.07271799999944,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.831762000001618,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":22.06103400000211,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":23.85377100000187,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant file exists","status":"passed","title":"file exists","duration":21.69913699999961,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.59844299999895,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":23.533971999997448,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.599247000001924,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":24.10442999999941,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.87302699999782,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":23.201379999998608,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.358790999998746,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":24.805905000001076,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":24.927008000002388,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.800493999999162,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.162029999999504,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.59521400000085,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant file exists","status":"passed","title":"file exists","duration":28.20506600000226,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.145760000003065,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":26.163002999997843,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.029962000000523,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":21.36652000000322,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.159772999999404,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":29.120771000001696,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":28.961522999998124,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.38409699999829,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":27.274833999999828,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":26.58530299999984,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.320788000000903,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.833385000001726,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant file exists","status":"passed","title":"file exists","duration":26.347297999996954,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":25.733908000001975,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":23.19250000000102,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.27670500000022,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.558666000000812,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":28.995555999998032,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.969074000000546,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.674580000002607,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.005026000002545,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":25.725163000002794,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.46939100000236,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":23.82893100000001,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.442802999998094,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant file exists","status":"passed","title":"file exists","duration":23.0576570000012,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":28.178735999998025,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":26.17557499999748,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.431350000002567,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.063367999999173,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.54788600000029,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":22.33647700000074,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.52921299999798,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":22.73737699999765,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":23.15361699999994,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":24.471976000000723,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":24.488655999997718,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":27.09998600000108,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant file exists","status":"passed","title":"file exists","duration":27.114754999998695,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.600761000001512,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":23.881399999998393,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":22.916753000001336,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.800835999998526,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":23.821246999999858,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.04804199999853,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":23.57019699999728,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":22.648049999999785,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":30.19599400000152,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.184990999998263,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":29.551547000002756,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.693653999998787,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant file exists","status":"passed","title":"file exists","duration":29.35260500000004,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.593727999999828,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":23.215913,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":23.610522000002675,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":22.94511599999896,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":30.47291299999779,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":32.125426999999036,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":32.214083000002574,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":32.998603,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":33.64284899999984,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.65947999999844,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.84191600000122,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.37186799999836,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant file exists","status":"passed","title":"file exists","duration":32.85521299999891,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.56488499999978,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":34.511836000001495,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.623530000000756,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":31.139060000001336,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":31.946302000000287,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":34.69952700000067,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":35.308367999998154,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.14112699999896,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":35.725798999999824,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":35.74772999999914,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":34.67760599999747,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.36355800000092,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant file exists","status":"passed","title":"file exists","duration":35.28646600000138,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.463746000001265,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":34.4239910000033,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":36.48958899999707,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":36.290766000001895,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.181204000000434,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":36.15238799999861,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":38.56948399999965,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.07371100000091,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":36.19586899999922,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":35.34209999999803,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":33.9769750000014,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":36.67793200000233,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant file exists","status":"passed","title":"file exists","duration":35.26839199999813,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":33.91229299999759,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":28.551755000000412,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":26.951669000001857,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":27.217327000002115,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":26.978598999998212,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.036027000001923,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":25.88308799999868,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":28.401213000001007,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":32.08277699999962,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.628561999998055,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.467211999999563,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":32.55474099999992,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant file exists","status":"passed","title":"file exists","duration":33.98629200000141,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":34.655305000000226,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":32.23258799999894,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":29.701138000000356,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":29.035169999999198,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":29.714092000001983,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":26.250636000000668,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":24.21694800000114,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":25.286871000000247,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":31.833961000000272,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.63795700000264,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":32.066256000001886,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.343086000000767,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant file exists","status":"passed","title":"file exists","duration":23.78537000000142,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":23.226834000000963,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":22.896244999999908,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":24.360305999998673,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.12557199999719,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":25.879360999999335,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":24.25701300000219,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.932535999996617,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.272256000000198,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":24.452128000000812,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":25.513364999998885,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":27.873004000000947,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.052443000000494,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant file exists","status":"passed","title":"file exists","duration":26.617813999997452,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":26.553594000000885,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":25.33089299999847,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.243803000001208,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":25.30808099999922,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":31.871431999999913,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.405769999997574,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":36.7627109999994,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":36.35850399999981,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.65881900000022,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.92244900000151,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.1373620000013,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.85601999999926,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant file exists","status":"passed","title":"file exists","duration":34.007471000000805,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.21923500000048,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":28.233157999999094,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":26.45866499999829,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.74276800000007,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.54189000000042,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.51332199999888,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":30.803341999999247,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant exposes container #ministry-dashboard","status":"passed","title":"exposes container #ministry-dashboard","duration":26.586675000002288,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.461417999998957,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":30.437826000001223,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":30.558452999997826,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'ministers'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'ministers' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":31.926705000001675,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant file exists","status":"passed","title":"file exists","duration":31.050735000000714,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":36.21411300000182,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant <html lang> attribute matches BCP-47 en","status":"passed","title":"<html lang> attribute matches BCP-47 en","duration":34.73187799999869,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.71556199999759,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.258370999999897,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.94478700000036,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.26231099999859,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":35.83696699999928,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":32.394311000000016,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.59494900000209,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":27.111558000000514,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.16909399999713,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'en' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'en' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":29.885401999999885,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant file exists","status":"passed","title":"file exists","duration":32.57216300000073,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":35.22531199999867,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant <html lang> attribute matches BCP-47 sv","status":"passed","title":"<html lang> attribute matches BCP-47 sv","duration":33.84766200000013,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":34.176588000002084,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":33.76680099999794,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":34.24343299999964,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":34.1948029999985,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":34.338732000000164,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":35.64254299999811,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":35.73995500000092,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.70947100000194,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":35.68456200000219,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'sv' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'sv' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":33.192825999998604,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant file exists","status":"passed","title":"file exists","duration":28.807784000000538,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":27.049191999998584,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant <html lang> attribute matches BCP-47 da","status":"passed","title":"<html lang> attribute matches BCP-47 da","duration":37.19658299999719,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":32.66302399999768,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":30.15855400000146,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.67258799999763,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":27.636662000000797,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":26.28735500000039,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":24.94520199999897,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":29.706186999999773,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":29.5746309999995,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":26.19416099999944,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'da' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'da' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":25.782028999998147,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant file exists","status":"passed","title":"file exists","duration":35.07065199999852,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":29.718550000001414,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant <html lang> attribute matches BCP-47 nb","status":"passed","title":"<html lang> attribute matches BCP-47 nb","duration":28.510677999998734,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":28.62546300000031,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":28.350969000002806,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":27.491629999996803,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":26.679329000002326,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":27.20333000000028,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":34.08043800000087,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.16809999999896,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.528229999999894,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.8813659999978,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nb' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nb' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":37.15841100000034,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant file exists","status":"passed","title":"file exists","duration":35.59036500000002,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":35.15731500000038,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant <html lang> attribute matches BCP-47 fi","status":"passed","title":"<html lang> attribute matches BCP-47 fi","duration":35.86492999999973,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":38.90957100000014,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":36.909035000000586,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":34.61151199999949,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":35.96874400000161,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":37.73060400000031,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":38.88115800000014,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":34.620028000001184,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":34.80999399999928,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":33.837422000000515,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fi' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fi' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":34.83907900000122,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant file exists","status":"passed","title":"file exists","duration":36.30697700000019,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.22632899999735,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant <html lang> attribute matches BCP-47 de","status":"passed","title":"<html lang> attribute matches BCP-47 de","duration":39.46110399999816,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.19932600000175,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":40.21902300000147,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":40.287200999999186,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.291958999998315,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.42826200000127,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":40.407146000001376,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":39.257313000001886,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.3487030000033,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":36.92474500000026,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'de' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'de' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.3611639999981,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant file exists","status":"passed","title":"file exists","duration":38.931752000000415,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.863993999999366,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant <html lang> attribute matches BCP-47 fr","status":"passed","title":"<html lang> attribute matches BCP-47 fr","duration":39.17858400000114,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":39.309940999999526,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":39.513842000000295,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":37.19108299999789,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":38.2490439999965,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.442581999999675,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":40.91854299999977,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":39.21450200000254,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":39.00071200000093,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":42.09865300000092,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'fr' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'fr' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":39.582390999999916,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant file exists","status":"passed","title":"file exists","duration":37.903667000002315,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":38.14215500000137,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant <html lang> attribute matches BCP-47 es","status":"passed","title":"<html lang> attribute matches BCP-47 es","duration":37.50786599999992,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":39.176329999998416,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.50460999999996,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.70333599999867,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":38.396701000001485,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":38.376774000000296,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.97441500000059,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":40.598793999997724,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":41.69933499999752,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.03827799999999,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'es' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'es' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.44641400000182,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant file exists","status":"passed","title":"file exists","duration":37.34993100000065,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":37.55328200000076,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant <html lang> attribute matches BCP-47 nl","status":"passed","title":"<html lang> attribute matches BCP-47 nl","duration":38.35385099999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.192424000000756,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":39.88823400000183,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.62198300000091,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.726911999998265,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.837007999998605,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.3794510000007,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":40.34332599999834,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":40.70317000000068,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.607593000000634,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'nl' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'nl' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":39.94722399999955,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant file exists","status":"passed","title":"file exists","duration":39.62284699999873,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":40.261553000000276,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant <html lang> attribute matches BCP-47 ar","status":"passed","title":"<html lang> attribute matches BCP-47 ar","duration":39.58227099999931,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":38.17081800000233,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":38.8506610000004,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":38.8236109999998,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.79409900000246,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.93487399999867,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.68178199999966,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.31533599999966,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":40.92005599999902,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":45.430091000001994,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ar' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ar' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":41.67759400000068,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant file exists","status":"passed","title":"file exists","duration":40.81945800000176,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":41.907444000000396,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant <html lang> attribute matches BCP-47 he","status":"passed","title":"<html lang> attribute matches BCP-47 he","duration":41.12942699999985,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant dir attribute is rtl","status":"passed","title":"dir attribute is rtl","duration":41.61155000000144,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":42.46117099999901,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":39.48436799999763,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.356267000002845,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":41.20413800000097,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.855256999999256,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.028408000001946,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.06724399999803,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":37.27869799999826,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'he' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'he' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.85705299999972,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant file exists","status":"passed","title":"file exists","duration":39.12415299999702,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":38.90594500000225,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant <html lang> attribute matches BCP-47 ja","status":"passed","title":"<html lang> attribute matches BCP-47 ja","duration":39.027783000001364,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.28879400000005,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.593988000000536,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":39.48972800000047,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":42.02592600000207,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":41.47525499999756,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":39.93439999999828,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.072251000001415,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.50045500000124,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":41.58405900000071,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ja' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ja' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":42.6921540000003,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant file exists","status":"passed","title":"file exists","duration":42.344772999997076,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":41.078512000000046,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant <html lang> attribute matches BCP-47 ko","status":"passed","title":"<html lang> attribute matches BCP-47 ko","duration":40.01478099999804,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":40.57884700000068,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":40.88863700000002,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":40.65399800000159,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":40.349277000001166,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":39.69592399999965,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":38.43048400000043,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":37.84983700000157,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":36.57550199999969,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":35.90609899999981,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'ko' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'ko' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":37.16865200000029,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant file exists","status":"passed","title":"file exists","duration":38.72958500000095,"failureMessages":[],"location":{"line":75,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant plausible size (8 KB – 80 KB)","status":"passed","title":"plausible size (8 KB – 80 KB)","duration":40.22601600000053,"failureMessages":[],"location":{"line":80,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant <html lang> attribute matches BCP-47 zh","status":"passed","title":"<html lang> attribute matches BCP-47 zh","duration":40.1451049999996,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant dir attribute is ltr","status":"passed","title":"dir attribute is ltr","duration":43.64632100000017,"failureMessages":[],"location":{"line":92,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant canonical link points at the correct slug + language","status":"passed","title":"canonical link points at the correct slug + language","duration":41.10976099999971,"failureMessages":[],"location":{"line":101,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","status":"passed","title":"hreflang chain has all 14 langs + x-default with \"nb\" for Norwegian","duration":41.39958300000217,"failureMessages":[],"location":{"line":108,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant Open Graph + Twitter Card meta present","status":"passed","title":"Open Graph + Twitter Card meta present","duration":39.825355999997555,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant JSON-LD @graph parses and contains a BreadcrumbList","status":"passed","title":"JSON-LD @graph parses and contains a BreadcrumbList","duration":40.01024200000029,"failureMessages":[],"location":{"line":132,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant exposes container #risk-dashboard","status":"passed","title":"exposes container #risk-dashboard","duration":41.168321000001015,"failureMessages":[],"location":{"line":145,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant has back-to-home navigation","status":"passed","title":"has back-to-home navigation","duration":41.68172200000117,"failureMessages":[],"location":{"line":150,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant related-dashboards <aside> links to the other 8 dashboards (and not itself)","status":"passed","title":"related-dashboards <aside> links to the other 8 dashboards (and not itself)","duration":42.96580600000016,"failureMessages":[],"location":{"line":155,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant no double-escaped HTML entities (&amp; / &lt; …)","status":"passed","title":"no double-escaped HTML entities (&amp; / &lt; …)","duration":39.73527699999977,"failureMessages":[],"location":{"line":174,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Specialised dashboard pages — structural contract","'risk'","'zh' variant"],"fullName":"Specialised dashboard pages — structural contract 'risk' 'zh' variant ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","status":"passed","title":"ships /js/theme-toggle.js + /js/back-to-top.js + /js/lib/mermaid-init.mjs bootstrap","duration":38.672867999997834,"failureMessages":[],"location":{"line":187,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant loads","status":"passed","title":"loads","duration":38.005999000000884,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.15248500000234,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.20295199999964,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant loads","status":"passed","title":"loads","duration":29.469085999997333,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":28.141599999999016,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":28.89123400000244,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant loads","status":"passed","title":"loads","duration":28.738648000002286,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.176220000001194,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.81213399999979,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant loads","status":"passed","title":"loads","duration":35.52868099999978,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":37.96477199999936,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.01607100000183,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant loads","status":"passed","title":"loads","duration":37.31377400000201,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.69793799999752,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.1797719999995,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant loads","status":"passed","title":"loads","duration":42.75095399999918,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.643191999999544,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.50441199999841,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant loads","status":"passed","title":"loads","duration":41.58757600000172,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.76038100000005,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.34803599999941,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant loads","status":"passed","title":"loads","duration":41.91163199999937,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.25704200000109,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.20564200000081,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant loads","status":"passed","title":"loads","duration":43.146074000000226,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.10628899999938,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.585901999998896,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant loads","status":"passed","title":"loads","duration":41.515870999999606,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.346043999998074,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.135965000001306,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant loads","status":"passed","title":"loads","duration":42.637040999998135,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.107395999999426,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.585095999998885,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant loads","status":"passed","title":"loads","duration":36.91607899999872,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.752830000001268,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.19742199999746,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant loads","status":"passed","title":"loads","duration":31.82496700000047,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.111299000000145,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'parties'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'parties' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":30.94172299999991,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant loads","status":"passed","title":"loads","duration":33.058937000001606,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.132840999998734,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.9839979999997,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant loads","status":"passed","title":"loads","duration":42.592407000000094,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.64181000000099,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.98556000000099,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant loads","status":"passed","title":"loads","duration":44.805630999999266,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.52076600000146,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.58288199999879,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant loads","status":"passed","title":"loads","duration":43.16681299999982,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.143990000000485,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.42227499999717,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant loads","status":"passed","title":"loads","duration":43.34896300000037,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.90108700000201,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.480077000000165,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant loads","status":"passed","title":"loads","duration":42.669943000000785,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.6553700000004,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.58797599999889,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant loads","status":"passed","title":"loads","duration":43.018144000001485,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.69075899999734,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.356988999999885,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant loads","status":"passed","title":"loads","duration":42.499352999999246,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.890770999998495,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.98894400000063,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant loads","status":"passed","title":"loads","duration":43.87873600000239,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.09128300000157,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.95533699999942,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant loads","status":"passed","title":"loads","duration":42.90805800000089,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.83946699999797,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.38180400000056,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant loads","status":"passed","title":"loads","duration":45.41719599999851,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.98527500000273,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.373820000000705,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant loads","status":"passed","title":"loads","duration":42.370310999998765,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.90196699999797,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.137008999998216,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant loads","status":"passed","title":"loads","duration":43.04434300000139,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.832698999998684,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'election-cycle'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'election-cycle' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.798790000000736,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant loads","status":"passed","title":"loads","duration":32.10131399999955,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":33.24271099999896,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":34.5193419999996,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant loads","status":"passed","title":"loads","duration":34.67014400000335,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":32.76556900000287,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":31.92626599999494,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant loads","status":"passed","title":"loads","duration":32.37823300000309,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":30.04791000000114,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.29993499999546,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant loads","status":"passed","title":"loads","duration":34.61795600000187,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":31.74275299999863,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":29.295270000002347,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant loads","status":"passed","title":"loads","duration":30.35714900000312,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":38.42891199999576,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.74049699999887,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant loads","status":"passed","title":"loads","duration":43.754924000000756,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.56905299999926,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.71420500000386,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant loads","status":"passed","title":"loads","duration":43.46703399999387,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.934792000000016,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.711130999996385,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant loads","status":"passed","title":"loads","duration":44.46408099999826,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.301494999999704,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.81057999999757,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant loads","status":"passed","title":"loads","duration":39.02729199999885,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.329438000000664,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.32841200000257,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant loads","status":"passed","title":"loads","duration":42.63895400000183,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.144735000001674,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.021498000001884,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant loads","status":"passed","title":"loads","duration":40.638668999999936,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.64620999999897,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.14182900000014,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant loads","status":"passed","title":"loads","duration":39.43774000000121,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":38.6019759999981,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.71010499999829,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant loads","status":"passed","title":"loads","duration":41.931619999995746,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.86777399999846,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'committees'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'committees' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.88915800000541,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant loads","status":"passed","title":"loads","duration":46.76908700000058,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.997129999996105,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.81896699999925,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant loads","status":"passed","title":"loads","duration":45.923063000002,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.85077500000625,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.24295700000221,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant loads","status":"passed","title":"loads","duration":44.6615610000008,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.74590199999511,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.5094190000018,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant loads","status":"passed","title":"loads","duration":46.358307999995304,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.65401700000075,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.686915999998746,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant loads","status":"passed","title":"loads","duration":44.60156899999856,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.47553499999776,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.081788000003144,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant loads","status":"passed","title":"loads","duration":46.2101610000027,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.78632500000094,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.11910799999896,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant loads","status":"passed","title":"loads","duration":45.39097799999581,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.62150799999654,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.58176100000128,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant loads","status":"passed","title":"loads","duration":44.99130899999727,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.1037490000017,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.838550000000396,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant loads","status":"passed","title":"loads","duration":44.911159000002954,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.00509199999942,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.29789200000232,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant loads","status":"passed","title":"loads","duration":44.07254799999646,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.150393999996595,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.76995200000238,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant loads","status":"passed","title":"loads","duration":41.26635499999975,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.495145000000775,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.53457899999921,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant loads","status":"passed","title":"loads","duration":44.20716000000539,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.51973600000201,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.329651999993075,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant loads","status":"passed","title":"loads","duration":45.35093199999392,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.6599600000045,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'coalitions'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'coalitions' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.8408519999939,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant loads","status":"passed","title":"loads","duration":43.102161000002525,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.851817999995546,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.84976599999936,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant loads","status":"passed","title":"loads","duration":47.18422400000418,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.665373000003456,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.33433700000023,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant loads","status":"passed","title":"loads","duration":44.867677000002004,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.335643999998865,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.38435500000196,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant loads","status":"passed","title":"loads","duration":47.57500599999912,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.89207799999713,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.795170999997936,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant loads","status":"passed","title":"loads","duration":44.792265999996744,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.54219999999623,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.88528799999767,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant loads","status":"passed","title":"loads","duration":45.109511000002385,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.14565500000026,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.17255000000296,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant loads","status":"passed","title":"loads","duration":46.81671600000118,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.940386000002036,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.29363900000317,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant loads","status":"passed","title":"loads","duration":44.28928399999859,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.04195299999992,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.306767000001855,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant loads","status":"passed","title":"loads","duration":44.01749500000005,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.68749199999729,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.877250000005006,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant loads","status":"passed","title":"loads","duration":44.11463700000604,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.104050000001735,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.97967699999572,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant loads","status":"passed","title":"loads","duration":45.31915300000401,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.42751799999678,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.850443000003,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant loads","status":"passed","title":"loads","duration":45.506253000006836,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.78300399999716,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.18485299999884,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant loads","status":"passed","title":"loads","duration":45.572156000001996,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.87702900000295,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'seasonal-patterns'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'seasonal-patterns' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.24040499999683,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant loads","status":"passed","title":"loads","duration":44.57620099999622,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.101056999999855,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.816595999996935,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant loads","status":"passed","title":"loads","duration":48.559369000002334,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.684346000001824,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.74453899999935,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant loads","status":"passed","title":"loads","duration":45.9989659999992,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.069980000000214,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.17891899999813,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant loads","status":"passed","title":"loads","duration":50.37550999999803,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":52.35714000000007,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":56.6306609999956,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant loads","status":"passed","title":"loads","duration":48.469169999996666,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.33660200000304,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.19181099999696,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant loads","status":"passed","title":"loads","duration":45.374496000004,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.32003399999667,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.21643800000311,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant loads","status":"passed","title":"loads","duration":38.71545699999842,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.53062300000602,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.954501000000164,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant loads","status":"passed","title":"loads","duration":34.948465000001306,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.533809000000474,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":32.144313999997394,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant loads","status":"passed","title":"loads","duration":32.50147299999662,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.75605899999937,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.457493000001705,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant loads","status":"passed","title":"loads","duration":39.74701900000218,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":40.88614300000336,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.5635470000052,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant loads","status":"passed","title":"loads","duration":40.18777499999851,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.578773999994155,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.43218000000343,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant loads","status":"passed","title":"loads","duration":41.96701600000233,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.11547699999937,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.71625700000004,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant loads","status":"passed","title":"loads","duration":43.063178999997035,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.425113000004785,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'pre-election'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'pre-election' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.780557999998564,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant loads","status":"passed","title":"loads","duration":46.26079500000196,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.59165799999755,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.51948699999775,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant loads","status":"passed","title":"loads","duration":47.22439899999881,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":45.81283699999767,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.425889000005554,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant loads","status":"passed","title":"loads","duration":46.9381429999994,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.594262999999046,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.543100000002596,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant loads","status":"passed","title":"loads","duration":41.763636000003316,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.65639699999883,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.88128699999652,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant loads","status":"passed","title":"loads","duration":45.87095599999884,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.481800000001385,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.468926000001375,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant loads","status":"passed","title":"loads","duration":33.68408799999452,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":33.72558500000014,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":35.369613999995636,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant loads","status":"passed","title":"loads","duration":35.2068089999957,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.889916000000085,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":34.9872880000039,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant loads","status":"passed","title":"loads","duration":34.023252999999386,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.6454670000021,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":36.60455599999841,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant loads","status":"passed","title":"loads","duration":35.890378999996756,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":34.99015299999883,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.570213999999396,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant loads","status":"passed","title":"loads","duration":43.57010699999955,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.999025999997684,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":41.011686999998346,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant loads","status":"passed","title":"loads","duration":36.58625200000097,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":35.96784400000615,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":37.16748899999948,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant loads","status":"passed","title":"loads","duration":34.16488799999934,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.0612620000029,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":40.513184999996156,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant loads","status":"passed","title":"loads","duration":40.7182180000018,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":39.34887400000298,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'anomaly-detection'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'anomaly-detection' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":38.32206099999894,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant loads","status":"passed","title":"loads","duration":44.36875300000247,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.40085900000122,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":42.36279700000159,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant loads","status":"passed","title":"loads","duration":45.24097500000062,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.058877999996184,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.63740200000029,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant loads","status":"passed","title":"loads","duration":44.65563000000111,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":46.245928000003914,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":43.492362000004505,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant loads","status":"passed","title":"loads","duration":38.32340400000248,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.35780800000066,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.55279000000155,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant loads","status":"passed","title":"loads","duration":44.513113000000885,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":42.23265399999946,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.99703800000134,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant loads","status":"passed","title":"loads","duration":40.85001500000362,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.643110000004526,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":39.76307000000088,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant loads","status":"passed","title":"loads","duration":37.59098300000187,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.58111399999325,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":44.28978500000085,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant loads","status":"passed","title":"loads","duration":44.88564100000076,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.177966000002925,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.42305900000065,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant loads","status":"passed","title":"loads","duration":45.80647499999759,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.68452199999592,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":51.92641400000139,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant loads","status":"passed","title":"loads","duration":46.833667000006244,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.22730199999933,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.13070499999594,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant loads","status":"passed","title":"loads","duration":48.64607100000285,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.78833299999678,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.97249000000011,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant loads","status":"passed","title":"loads","duration":48.41245300000446,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.582180999997945,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.30973800000356,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant loads","status":"passed","title":"loads","duration":48.290194000001065,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":44.712383999998565,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'ministers'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'ministers' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.3139730000039,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant loads","status":"passed","title":"loads","duration":47.74810900000011,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.549559999999474,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'sv' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'sv' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.48370100000466,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant loads","status":"passed","title":"loads","duration":46.36221300000034,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.01890600000479,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'da' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'da' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.07706699999835,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant loads","status":"passed","title":"loads","duration":42.5612159999946,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":41.54126499999984,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nb' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nb' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.57852599999751,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant loads","status":"passed","title":"loads","duration":44.3757839999962,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":43.74263799999608,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fi' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fi' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.51357499999722,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant loads","status":"passed","title":"loads","duration":46.82864699999482,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.88565899999958,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'de' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'de' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":46.00246999999945,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant loads","status":"passed","title":"loads","duration":48.568114000001515,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.79377499999828,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'fr' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'fr' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":45.6508909999975,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant loads","status":"passed","title":"loads","duration":48.68537400000059,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":48.60107599999901,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'es' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'es' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.103837000002386,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant loads","status":"passed","title":"loads","duration":49.49246600000333,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.308463999994274,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'nl' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'nl' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":52.430006999995385,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant loads","status":"passed","title":"loads","duration":50.84267399999953,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":51.300821999997424,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ar' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ar' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":51.98520400000416,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant loads","status":"passed","title":"loads","duration":50.039310000000114,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":52.07690599999478,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'he' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'he' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":48.71176299999934,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant loads","status":"passed","title":"loads","duration":47.50866099999985,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":49.501321999996435,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ja' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ja' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":47.99707600000693,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant loads","status":"passed","title":"loads","duration":50.190081000000646,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":47.15821500000311,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'ko' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'ko' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":49.197283000001335,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant loads","status":"passed","title":"loads","duration":50.5102509999997,"failureMessages":[],"location":{"line":271,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant <meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","status":"passed","title":"<meta name=\"keywords\"> contains no English topic seed fragments for this dashboard","duration":50.624455999997735,"failureMessages":[],"location":{"line":276,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — dashboard hubs do not leak English topic keywords into non-EN pages","'risk'","'zh' variant"],"fullName":"W5 — dashboard hubs do not leak English topic keywords into non-EN pages 'risk' 'zh' variant JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","status":"passed","title":"JSON-LD Dataset.keywords contains no English topic seed fragments for this dashboard","duration":50.16401300000143,"failureMessages":[],"location":{"line":291,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'parties'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'parties' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":47.803501999995206,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'election-cycle'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'election-cycle' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":49.64211599999544,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'committees'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'committees' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":50.66860799999995,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'coalitions'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'coalitions' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":50.06668100000388,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'seasonal-patterns'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'seasonal-patterns' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":49.385385000001406,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'pre-election'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'pre-election' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":45.741941000000224,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'anomaly-detection'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'anomaly-detection' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":44.27487399999518,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'ministers'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'ministers' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":42.61721000000398,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["W5 — EN dashboard pages preserve their English topic seed (no over-correction)","'risk'"],"fullName":"W5 — EN dashboard pages preserve their English topic seed (no over-correction) 'risk' <meta name=\"keywords\"> still contains at least one English topic seed fragment","status":"passed","title":"<meta name=\"keywords\"> still contains at least one English topic seed fragment","duration":47.342328999999154,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'en' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'en' variant hub section exists","status":"passed","title":"hub section exists","duration":48.67845099999977,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'en' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'en' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":48.688670000003185,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'sv' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'sv' variant hub section exists","status":"passed","title":"hub section exists","duration":46.55332199999975,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'sv' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'sv' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":44.31462899999315,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'da' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'da' variant hub section exists","status":"passed","title":"hub section exists","duration":43.877770999999484,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'da' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'da' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":44.910234000002674,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nb' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nb' variant hub section exists","status":"passed","title":"hub section exists","duration":44.26220099999773,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nb' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nb' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":43.110954999996466,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fi' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fi' variant hub section exists","status":"passed","title":"hub section exists","duration":42.99732199999562,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fi' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fi' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":50.37300400000095,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'de' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'de' variant hub section exists","status":"passed","title":"hub section exists","duration":52.52471399999922,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'de' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'de' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":48.90497599999799,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fr' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fr' variant hub section exists","status":"passed","title":"hub section exists","duration":49.64543199999753,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'fr' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'fr' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":49.99855299999763,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'es' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'es' variant hub section exists","status":"passed","title":"hub section exists","duration":50.60428800000227,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'es' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'es' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":53.23404300000402,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nl' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nl' variant hub section exists","status":"passed","title":"hub section exists","duration":52.023574999999255,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'nl' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'nl' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":51.19019500000286,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ar' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ar' variant hub section exists","status":"passed","title":"hub section exists","duration":51.52849900000001,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ar' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ar' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":51.03998399999546,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'he' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'he' variant hub section exists","status":"passed","title":"hub section exists","duration":53.308271000001696,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'he' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'he' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":52.145855000002484,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ja' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ja' variant hub section exists","status":"passed","title":"hub section exists","duration":53.23385199999757,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ja' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ja' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":52.403386999998474,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ko' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ko' variant hub section exists","status":"passed","title":"hub section exists","duration":53.8014650000041,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'ko' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'ko' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":50.8674600000013,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'zh' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'zh' variant hub section exists","status":"passed","title":"hub section exists","duration":49.02865700000257,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["index*.html hub — political-intelligence-dashboards section","'zh' variant"],"fullName":"index*.html hub — political-intelligence-dashboards section 'zh' variant hub links to every dashboard in the matching language","status":"passed","title":"hub links to every dashboard in the matching language","duration":46.48196800000005,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["sitemap source — dashboard page registration"],"fullName":"sitemap source — dashboard page registration scripts/sitemap-xml/render/sitemap.ts registers all 9 dashboard slugs","status":"passed","title":"scripts/sitemap-xml/render/sitemap.ts registers all 9 dashboard slugs","duration":50.58527199999662,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]}],"startTime":1787953737269,"endTime":1787953783016.5852,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/dashboard-pages.test.js"},{"assertionResults":[{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should prefer dok_id as the primary identifier","status":"passed","title":"should prefer dok_id as the primary identifier","duration":7.484974999999963,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to dokument_id when dok_id is missing","status":"passed","title":"should fall back to dokument_id when dok_id is missing","duration":1.1705520000000433,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to rel_dok_id when dok_id and dokument_id are missing","status":"passed","title":"should fall back to rel_dok_id when dok_id and dokument_id are missing","duration":1.0154210000000035,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to id when higher-priority fields are missing","status":"passed","title":"should fall back to id when higher-priority fields are missing","duration":1.0647539999999935,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","dokId resolution order"],"fullName":"data-downloader enrichment dokId resolution order should fall back to dokumentnamn as last resort","status":"passed","title":"should fall back to dokumentnamn as last resort","duration":1.031722000000002,"failureMessages":[],"location":{"line":135,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","whitespace trimming on IDs"],"fullName":"data-downloader enrichment whitespace trimming on IDs should trim whitespace from dok_id before calling fetchDocumentDetails","status":"passed","title":"should trim whitespace from dok_id before calling fetchDocumentDetails","duration":0.8431780000000231,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","whitespace trimming on IDs"],"fullName":"data-downloader enrichment whitespace trimming on IDs should skip empty/whitespace-only IDs and fall back","status":"passed","title":"should skip empty/whitespace-only IDs and fall back","duration":0.9183190000000536,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should assign fullText when length exceeds FULL_TEXT_MIN_LENGTH","status":"passed","title":"should assign fullText when length exceeds FULL_TEXT_MIN_LENGTH","duration":1.4587619999999788,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should NOT assign fullText when length is <= FULL_TEXT_MIN_LENGTH","status":"passed","title":"should NOT assign fullText when length is <= FULL_TEXT_MIN_LENGTH","duration":1.249890999999991,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should assign fullContent (from html) when length exceeds FULL_TEXT_MIN_LENGTH","status":"passed","title":"should assign fullContent (from html) when length exceeds FULL_TEXT_MIN_LENGTH","duration":0.9720110000000091,"failureMessages":[],"location":{"line":210,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","fullText/fullContent assignment threshold"],"fullName":"data-downloader enrichment fullText/fullContent assignment threshold should NOT assign fullContent when html length is <= FULL_TEXT_MIN_LENGTH","status":"passed","title":"should NOT assign fullContent when html length is <= FULL_TEXT_MIN_LENGTH","duration":0.8208470000000148,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should not overwrite existing summary","status":"passed","title":"should not overwrite existing summary","duration":0.8785950000000184,"failureMessages":[],"location":{"line":238,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should not overwrite existing notis","status":"passed","title":"should not overwrite existing notis","duration":0.9925089999999841,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","existing summary/notis fields are not overwritten"],"fullName":"data-downloader enrichment existing summary/notis fields are not overwritten should set summary when doc does not already have one","status":"passed","title":"should set summary when doc does not already have one","duration":1.0191389999999956,"failureMessages":[],"location":{"line":266,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","isPersonProfileText sanitization"],"fullName":"data-downloader enrichment isPersonProfileText sanitization should filter out MP profile text from fullText","status":"passed","title":"should filter out MP profile text from fullText","duration":0.9681530000000294,"failureMessages":[],"location":{"line":282,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","isPersonProfileText sanitization"],"fullName":"data-downloader enrichment isPersonProfileText sanitization should filter out deceased notice text from summary","status":"passed","title":"should filter out deceased notice text from summary","duration":0.9923379999999611,"failureMessages":[],"location":{"line":298,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","enrichment skips when no IDs available"],"fullName":"data-downloader enrichment enrichment skips when no IDs available should not call fetchDocumentDetails when no ID fields are present","status":"passed","title":"should not call fetchDocumentDetails when no ID fields are present","duration":1.2616729999999734,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","enrichment disabled when enrichLimit is 0"],"fullName":"data-downloader enrichment enrichment disabled when enrichLimit is 0 should skip enrichment when enrichLimit is 0","status":"passed","title":"should skip enrichment when enrichLimit is 0","duration":1.2092150000000288,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should assign fullContent from MCP text field when length exceeds threshold","status":"passed","title":"should assign fullContent from MCP text field when length exceeds threshold","duration":1.1032760000000508,"failureMessages":[],"location":{"line":350,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should prefer text field over html field for fullContent","status":"passed","title":"should prefer text field over html field for fullContent","duration":1.1399339999999825,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should use snippet as summary fallback when no legacy summary field exists","status":"passed","title":"should use snippet as summary fallback when no legacy summary field exists","duration":1.2936219999999707,"failureMessages":[],"location":{"line":378,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-downloader enrichment","MCP response field mapping (text/snippet)"],"fullName":"data-downloader enrichment MCP response field mapping (text/snippet) should not overwrite existing summary with snippet","status":"passed","title":"should not overwrite existing summary with snippet","duration":1.1404249999999934,"failureMessages":[],"location":{"line":392,"column":5},"meta":{},"tags":[]}],"startTime":1787953789500,"endTime":1787953789531.1404,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/data-downloader-enrichment.test.ts"},{"assertionResults":[{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for live data","status":"passed","title":"should create a disclaimer element for live data","duration":9.54386199999999,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for synthetic data","status":"passed","title":"should create a disclaimer element for synthetic data","duration":1.6409530000000245,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Creation"],"fullName":"Data Source Disclaimer Creation should create a disclaimer element for mock data","status":"passed","title":"should create a disclaimer element for mock data","duration":0.8634770000000458,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-live class for live data","status":"passed","title":"should have data-source-live class for live data","duration":0.8241129999999544,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-synthetic class for synthetic data","status":"passed","title":"should have data-source-synthetic class for synthetic data","duration":0.7241970000000038,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","CSS Classes"],"fullName":"Data Source Disclaimer CSS Classes should have data-source-mock class for mock data","status":"passed","title":"should have data-source-mock class for mock data","duration":0.6975369999999543,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Accessibility"],"fullName":"Data Source Disclaimer Accessibility should have role=\"status\" for screen readers","status":"passed","title":"should have role=\"status\" for screen readers","duration":0.6847420000000284,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should insert after heading when heading exists","status":"passed","title":"should insert after heading when heading exists","duration":0.7380319999999756,"failureMessages":[],"location":{"line":96,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should prepend to container when no heading exists","status":"passed","title":"should prepend to container when no heading exists","duration":1.0120049999999878,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Positioning"],"fullName":"Data Source Disclaimer Positioning should insert after heading when heading is the last child","status":"passed","title":"should insert after heading when heading is the last child","duration":0.8131630000000314,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Deduplication"],"fullName":"Data Source Disclaimer Deduplication should replace existing disclaimer when called again","status":"passed","title":"should replace existing disclaimer when called again","duration":1.4063540000000216,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Deduplication"],"fullName":"Data Source Disclaimer Deduplication should update CSS class when source type changes","status":"passed","title":"should update CSS class when source type changes","duration":0.7795000000000414,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show ✅ icon for live data","status":"passed","title":"should show ✅ icon for live data","duration":0.6483139999999707,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show ⚠️ icon for synthetic data","status":"passed","title":"should show ⚠️ icon for synthetic data","duration":0.5734630000000038,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Icons"],"fullName":"Data Source Disclaimer Icons should show 🔧 icon for mock data","status":"passed","title":"should show 🔧 icon for mock data","duration":0.6209629999999606,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Data Source Disclaimer","Type Safety"],"fullName":"Data Source Disclaimer Type Safety should accept all valid DataSourceType values","status":"passed","title":"should accept all valid DataSourceType values","duration":0.8729840000000308,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]}],"startTime":1787953847239,"endTime":1787953847261.873,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/data-source-disclaimer.test.ts"},{"assertionResults":[{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback replaces existing container content","status":"passed","title":"replaces existing container content","duration":7.838318000000015,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback renders a skeleton wrapper with role=status","status":"passed","title":"renders a skeleton wrapper with role=status","duration":1.6971880000000397,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback has aria-live=\"polite\" on the skeleton wrapper","status":"passed","title":"has aria-live=\"polite\" on the skeleton wrapper","duration":0.7319800000000214,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback uses the default \"Loading…\" aria-label when no label is supplied","status":"passed","title":"uses the default \"Loading…\" aria-label when no label is supplied","duration":0.6162939999999821,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback uses a custom aria-label when loadingLabel is provided","status":"passed","title":"uses a custom aria-label when loadingLabel is provided","duration":0.6823880000000031,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderLoadingFallback"],"fullName":"renderLoadingFallback renders at least one skeleton bar","status":"passed","title":"renders at least one skeleton bar","duration":1.2767810000000281,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback replaces existing container content","status":"passed","title":"replaces existing container content","duration":1.206278999999995,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders an error card with role=alert","status":"passed","title":"renders an error card with role=alert","duration":0.6850729999999885,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback displays the provided message","status":"passed","title":"displays the provided message","duration":0.7813129999999546,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses default message when none is provided","status":"passed","title":"uses default message when none is provided","duration":0.5471850000000131,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback does not render a retry button when retryFn is omitted","status":"passed","title":"does not render a retry button when retryFn is omitted","duration":0.5878510000000006,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders a retry button when retryFn is provided","status":"passed","title":"renders a retry button when retryFn is provided","duration":1.0546150000000125,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses the default \"Retry\" label for the retry button","status":"passed","title":"uses the default \"Retry\" label for the retry button","duration":0.7898590000000354,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback uses a custom label for the retry button when retryLabel is provided","status":"passed","title":"uses a custom label for the retry button when retryLabel is provided","duration":0.8082130000000234,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback calls retryFn when the retry button is clicked","status":"passed","title":"calls retryFn when the retry button is clicked","duration":1.8575890000000186,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderErrorFallback"],"fullName":"renderErrorFallback renders an icon element","status":"passed","title":"renders an icon element","duration":0.8427780000000098,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback calls the renderFn on success","status":"passed","title":"calls the renderFn on success","duration":7.597696999999982,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback renders error fallback when renderFn throws synchronously","status":"passed","title":"renders error fallback when renderFn throws synchronously","duration":2.0402709999999615,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback renders error fallback when renderFn rejects","status":"passed","title":"renders error fallback when renderFn rejects","duration":1.7916250000000105,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback shows a retry button after failure","status":"passed","title":"shows a retry button after failure","duration":1.7636319999999728,"failureMessages":[],"location":{"line":183,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback re-runs renderFn when retry button is clicked","status":"passed","title":"re-runs renderFn when retry button is clicked","duration":3.528457000000003,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback does not render error card when renderFn succeeds","status":"passed","title":"does not render error card when renderFn succeeds","duration":1.7269739999999842,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback uses default fallback message when none is supplied","status":"passed","title":"uses default fallback message when none is supplied","duration":2.319474000000014,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback removes the loading overlay after a successful render","status":"passed","title":"removes the loading overlay after a successful render","duration":2.157880999999975,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback removes the loading overlay after a failed render","status":"passed","title":"removes the loading overlay after a failed render","duration":1.7970250000000192,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback ignores concurrent retry clicks while an attempt is already in flight","status":"passed","title":"ignores concurrent retry clicks while an attempt is already in flight","duration":3.0493000000000166,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback preserves existing container HTML when renderFn runs on the first attempt","status":"passed","title":"preserves existing container HTML when renderFn runs on the first attempt","duration":2.2180040000000076,"failureMessages":[],"location":{"line":270,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback restores original HTML before retry after failure","status":"passed","title":"restores original HTML before retry after failure","duration":4.186538999999982,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback forwards options.loadingLabel to the loading overlay ARIA label","status":"passed","title":"forwards options.loadingLabel to the loading overlay ARIA label","duration":1.4529899999999998,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderWithFallback"],"fullName":"renderWithFallback forwards options.retryLabel to the retry button on failure","status":"passed","title":"forwards options.retryLabel to the retry button on failure","duration":1.6381069999999909,"failureMessages":[],"location":{"line":321,"column":3},"meta":{},"tags":[]}],"startTime":1787953808335,"endTime":1787953808394.6382,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/error-boundary.test.ts"},{"assertionResults":[{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks removes a single ```mermaid block while preserving surrounding prose","status":"passed","title":"removes a single ```mermaid block while preserving surrounding prose","duration":3.8649970000000167,"failureMessages":[],"location":{"line":8,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks preserves non-mermaid fenced code blocks","status":"passed","title":"preserves non-mermaid fenced code blocks","duration":0.5914080000000013,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks strips multiple ```mermaid blocks independently","status":"passed","title":"strips multiple ```mermaid blocks independently","duration":0.4930529999999749,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripMermaidBlocks"],"fullName":"stripMermaidBlocks is case-insensitive on the mermaid fence opener","status":"passed","title":"is case-insensitive on the mermaid fence opener","duration":0.4340230000000247,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns true for identical inputs","status":"passed","title":"returns true for identical inputs","duration":0.4953570000000127,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns true when the only change is inside a ```mermaid block (autofix case)","status":"passed","title":"returns true when the only change is inside a ```mermaid block (autofix case)","duration":0.41799300000002404,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a brand-new ```mermaid block is appended with surrounding blank lines","status":"passed","title":"returns false when a brand-new ```mermaid block is appended with surrounding blank lines","duration":0.4077429999999822,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a narrative line changes","status":"passed","title":"returns false when a narrative line changes","duration":0.377708000000041,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a non-mermaid fenced block changes","status":"passed","title":"returns false when a non-mermaid fenced block changes","duration":0.4320189999999684,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly returns false when a heading is added","status":"passed","title":"returns false when a heading is added","duration":0.49704100000002427,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDiffMermaidOnly"],"fullName":"isDiffMermaidOnly normalises CRLF vs LF line endings","status":"passed","title":"normalises CRLF vs LF line endings","duration":0.3860230000000229,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]}],"startTime":1787953913948,"endTime":1787953913957.386,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/exec-brief-narrative-drift.test.ts"},{"assertionResults":[{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":5.016440999999986,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.8750280000001567,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":17.303875000000062,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":6.510487999999896,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.812953000000107,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.888522999999623,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":5.966891000000032,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7868430000003173,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Propositions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Propositions] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.8530369999998584,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.2997610000002169,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3904609999999593,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.218221999999969,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.124693000000207,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.898520999999619,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.463946999999735,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.7946640000000116,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.5780119999999442,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Motions] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Motions] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.5048850000002858,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.2917760000000271,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3611959999998362,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.69183699999985,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.162452999999914,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.597740000000158,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":13.805897000000186,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":2.895140000000083,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.6360610000001543,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Committee reports] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Committee reports] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.6002639999996973,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.43916200000012395,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.3451660000000629,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.873665999999957,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.93370700000014,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":7.222271999999975,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.17506800000001,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.733339000000342,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7614460000004328,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Interpellations] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Interpellations] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.557875000000422,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.4904679999999644,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.39901700000018536,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":7.247799000000214,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.2230759999997645,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.85823500000015,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.384449000000131,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.598488999999972,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7594719999997324,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Evening analysis] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Evening analysis] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.6680999999998676,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.49559799999997267,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.47481900000002497,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.96959599999991,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.207056000000193,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.861532000000352,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":14.264754999999695,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.859827999999652,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.9671210000001338,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime pulse] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Realtime pulse] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.7935359999996763,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.6155519999997523,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.5901249999997162,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":1.6289790000000721,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":1.1307969999998022,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":1.300894999999855,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":1.6713989999998375,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":1.129584999999679,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":0.7352659999996831,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Election cycle] SEO contract — 1 random briefs × 14 languages"],"fullName":"[Election cycle] SEO contract — 1 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":0.7111620000000585,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.7632190000003902,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.76767800000016,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.893385999999737,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.651459000000159,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.276708999999755,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.956811000000016,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.376702999999907,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.1460250000000087,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Month ahead] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Month ahead] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.0956919999998718,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":0.8855979999998453,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":0.9392079999997804,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":6.473809999999958,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.880947000000106,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":6.810469999999896,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":9.59509399999979,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":4.5787320000004,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.856927000000269,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Monthly review] SEO contract — 10 random briefs × 14 languages"],"fullName":"[Monthly review] SEO contract — 10 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.8523279999999431,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.755537000000004,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.7740210000001753,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":8.238152999999784,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.329145000000153,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.61296799999991,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":8.80328099999997,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.7292019999999866,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.4378719999999703,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Year ahead] SEO contract — 9 random briefs × 14 languages"],"fullName":"[Year ahead] SEO contract — 9 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.3646859999998924,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.1966899999997622,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.3082490000001599,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":5.440875999999662,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.126534999999876,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":4.728451999999834,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":8.498810999999932,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.6939360000001216,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.5879429999999957,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Week ahead] SEO contract — 8 random briefs × 14 languages"],"fullName":"[Week ahead] SEO contract — 8 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.497534000000087,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.3850440000001072,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.6042030000003251,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":4.885706999999911,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":3.367334000000028,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":3.7876510000000962,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":5.743301999999858,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":3.0686650000002373,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.712485999999899,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Weekly review] SEO contract — 5 random briefs × 14 languages"],"fullName":"[Weekly review] SEO contract — 5 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.7243889999999737,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages has corpus coverage","status":"passed","title":"has corpus coverage","duration":1.5486789999999928,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages English rows mostly produce non-null SEO","status":"passed","title":"English rows mostly produce non-null SEO","duration":1.935573000000204,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a non-empty, ceiling-bounded title","status":"passed","title":"every row produces a non-empty, ceiling-bounded title","duration":8.682045000000016,"failureMessages":[],"location":{"line":448,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a non-empty, ceiling-bounded description","status":"passed","title":"every row produces a non-empty, ceiling-bounded description","duration":4.539800000000014,"failureMessages":[],"location":{"line":455,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages every row produces a brand-anchored keywords line","status":"passed","title":"every row produces a brand-anchored keywords line","duration":5.005620999999792,"failureMessages":[],"location":{"line":462,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages no row leaks admin-byline VALUES into the SEO surface","status":"passed","title":"no row leaks admin-byline VALUES into the SEO surface","duration":6.859852000000046,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages non-EN rows stay below the per-language English-marker density threshold","status":"passed","title":"non-EN rows stay below the per-language English-marker density threshold","duration":2.7987699999998767,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages titles are unique per language across the sample","status":"passed","title":"titles are unique per language across the sample","duration":1.8755409999998847,"failureMessages":[],"location":{"line":501,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["[Realtime monitor] SEO contract — 6 random briefs × 14 languages"],"fullName":"[Realtime monitor] SEO contract — 6 random briefs × 14 languages at least 20% of titles per language reach the softMin SERP floor","status":"passed","title":"at least 20% of titles per language reach the softMin SERP floor","duration":1.8274109999997563,"failureMessages":[],"location":{"line":530,"column":5},"meta":{},"tags":[]}],"startTime":1787953665517,"endTime":1787953665953.8274,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/executive-brief-seo-corpus.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records parses --date and --doc-type and --persist happy path","status":"passed","title":"parses --date and --doc-type and --persist happy path","duration":3.976937000000021,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records defaults date to today when not provided","status":"passed","title":"defaults date to today when not provided","duration":1.0664470000000392,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records returns error for invalid date format","status":"passed","title":"returns error for invalid date format","duration":0.746688000000006,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records returns error for non-date string","status":"passed","title":"returns error for non-date string","duration":0.5257249999999658,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records parses --date without --doc-type","status":"passed","title":"parses --date without --doc-type","duration":0.4732360000000426,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs — fetch-voting-records"],"fullName":"parseArgs — fetch-voting-records persist defaults to false when flag is absent","status":"passed","title":"persist defaults to false when flag is absent","duration":0.631672999999978,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors returns vote_pending status when input is empty","status":"passed","title":"returns vote_pending status when input is empty","duration":1.653316000000018,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors detects an MP voting Nej when party majority is Ja","status":"passed","title":"detects an MP voting Nej when party majority is Ja","duration":1.906630000000007,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors detects no defectors when all MPs vote with their party","status":"passed","title":"detects no defectors when all MPs vote with their party","duration":0.6699440000000436,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors excludes Frånvarande from defector list","status":"passed","title":"excludes Frånvarande from defector list","duration":0.5549589999999966,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors handles multiple defectors across multiple parties","status":"passed","title":"handles multiple defectors across multiple parties","duration":0.9299510000000168,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectDefectors"],"fullName":"detectDefectors handles votes with alternative field names","status":"passed","title":"handles votes with alternative field names","duration":0.6127670000000194,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart produces a valid mermaid string for party votes","status":"passed","title":"produces a valid mermaid string for party votes","duration":0.7006920000000036,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart returns a flowchart-style diagram when there are no party votes","status":"passed","title":"returns a flowchart-style diagram when there are no party votes","duration":0.5254740000000311,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generateMermaidVoteChart"],"fullName":"generateMermaidVoteChart includes x-axis and y-axis labels","status":"passed","title":"includes x-axis and y-axis labels","duration":0.481521999999984,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues extracts beteckning values from manifest text","status":"passed","title":"extracts beteckning values from manifest text","duration":0.8356850000000122,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues filters out common false-positive acronyms","status":"passed","title":"filters out common false-positive acronyms","duration":0.7407870000000116,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBetValues"],"fullName":"extractBetValues returns empty array for manifest with no beteckning values","status":"passed","title":"returns empty array for manifest with no beteckning values","duration":0.6032490000000053,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet lowercases and preserves alphanumeric content","status":"passed","title":"lowercases and preserves alphanumeric content","duration":0.5385089999999764,"failureMessages":[],"location":{"line":238,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet replaces special characters with hyphens","status":"passed","title":"replaces special characters with hyphens","duration":0.5227489999999761,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sanitizeBet"],"fullName":"sanitizeBet collapses multiple hyphens","status":"passed","title":"collapses multiple hyphens","duration":0.45041300000002593,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract: voting records have status field"],"fullName":"contract: voting records have status field every voting record JSON in data/voteringar/ has a status field","status":"passed","title":"every voting record JSON in data/voteringar/ has a status field","duration":0.6113740000000121,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["contract: voting records have status field"],"fullName":"contract: voting records have status field cited betänkanden have either a voting record or an explicit pending/not-found/error annotation","status":"passed","title":"cited betänkanden have either a voting record or an explicit pending/not-found/error annotation","duration":1.9332599999999616,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]}],"startTime":1787953790982,"endTime":1787953791004.9333,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-voting-records.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc loads and validates the real registry without error","status":"passed","title":"loads and validates the real registry without error","duration":4.09987799999999,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc renders a table containing all registry IDs","status":"passed","title":"renders a table containing all registry IDs","duration":1.3256119999999783,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc replaces content between sentinels correctly","status":"passed","title":"replaces content between sentinels correctly","duration":0.8002390000000332,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc is idempotent — running twice produces same output","status":"passed","title":"is idempotent — running twice produces same output","duration":0.7114520000000084,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on missing sentinels","status":"passed","title":"throws on missing sentinels","duration":1.3618210000000204,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on invalid registry (empty types)","status":"passed","title":"throws on invalid registry (empty types)","duration":1.3881089999999858,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing articleWordFloor","status":"passed","title":"throws on registry entry missing articleWordFloor","duration":0.961731000000043,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc renders dispatch-only types with italic marker","status":"passed","title":"renders dispatch-only types with italic marker","duration":0.5191429999999855,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc does not modify content outside sentinels in Article-Generation.md","status":"passed","title":"does not modify content outside sentinels in Article-Generation.md","duration":0.973041999999964,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry missing version field","status":"passed","title":"throws on registry missing version field","duration":0.800249000000008,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing id/family/horizonDays/tierCMultiplier","status":"passed","title":"throws on registry entry missing id/family/horizonDays/tierCMultiplier","duration":0.9926190000000474,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing electionCycleAnchor","status":"passed","title":"throws on registry entry missing electionCycleAnchor","duration":0.7950389999999743,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws on registry entry missing cronExpression when not dispatchOnly","status":"passed","title":"throws on registry entry missing cronExpression when not dispatchOnly","duration":0.7469180000000506,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc throws when END sentinel appears before BEGIN sentinel","status":"passed","title":"throws when END sentinel appears before BEGIN sentinel","duration":0.5689160000000015,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-article-types-doc"],"fullName":"generate-article-types-doc generate() writes updated content to a temp doc","status":"passed","title":"generate() writes updated content to a temp doc","duration":0.9576729999999998,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]}],"startTime":1787953830469,"endTime":1787953830485.9578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-article-types-doc.test.ts"},{"assertionResults":[{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects methodology catalog with all expected entries","status":"passed","title":"collects methodology catalog with all expected entries","duration":15.241341000000034,"failureMessages":[],"location":{"line":42,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects template catalog with all expected entries","status":"passed","title":"collects template catalog with all expected entries","duration":1.8827260000000479,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Data collection"],"fullName":"Political Intelligence HTML Generation Data collection collects daily artifacts grouped by date (newest first)","status":"passed","title":"collects daily artifacts grouped by date (newest first)","duration":91.88651600000003,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":6.644252000000051,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8799679999999626,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.5232300000000123,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.5422259999999142,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.3949890000000096,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.811719999999923,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.4808709999999792,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.46976999999992586,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.221270000000004,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","en"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) en uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.6748039999999946,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":6.473494000000073,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.818702999999914,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.6048019999999497,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.4870420000000877,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.3791200000000572,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.9316749999999274,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.45097500000008495,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.4572160000000167,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.193829000000051,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","sv"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) sv uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.5246329999999944,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.519071000000167,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.7787479999999505,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.48790299999996023,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.4833659999999327,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.37968099999989136,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.6390069999999923,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.486601999999948,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.6139299999999821,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.392871000000014,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","da"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) da uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.7250070000000051,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.450934999999845,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8088540000001103,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.5485869999999977,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.5903060000000551,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.47820499999988897,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.6576419999998961,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.5393599999999878,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.4918210000000727,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.477558999999928,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","no"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) no uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.7707729999999628,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.682086000000027,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":0.8976920000000064,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.519172000000026,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.6009950000000117,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.5191529999999602,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.7501949999998487,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.6373730000000251,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.5960969999998724,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.307620999999926,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fi"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fi uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":0.8289219999999204,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.882039999999961,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.031631999999945,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.7374919999999747,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.7283039999999801,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.6422029999998813,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":0.8565739999999096,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.7557150000000092,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.734185000000025,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.537372000000005,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","de"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) de uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.0506069999999,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.344785999999885,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.16269699999998,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":0.879758000000038,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":0.9280979999998635,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.8034350000000359,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.0272029999998722,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":0.8886640000000625,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":0.8461839999999938,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":6.596042000000125,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","fr"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) fr uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.170562000000018,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.801107999999886,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.78707600000007,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.0220240000001013,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.0708559999998215,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":0.9722609999998895,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.4481719999998859,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.2993039999998928,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.075563000000102,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.0041459999999915,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","es"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) es uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.615664999999808,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":7.869134000000031,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.6742749999998523,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.186151000000109,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.192303000000038,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.2594890000000305,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.46850900000004,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.2371160000000145,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.188385000000153,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.049980999999889,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","nl"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) nl uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":1.668685000000096,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":9.280056000000059,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":1.995486000000028,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.3790120000001025,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.4506559999999808,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.431831000000102,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.6398910000000342,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.5079840000000786,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.7935990000000857,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.127584999999954,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ar"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ar uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":3.9127659999999196,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.312143000000106,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.3757190000001174,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.5426390000002357,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.5440110000004097,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.4696619999999712,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":1.692047999999886,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.5704109999996945,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.5606419999999162,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.1632220000001325,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","he"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) he uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.151789000000008,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.40231199999971,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.252769000000171,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.71330799999987,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.723117000000002,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":1.7388960000002953,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.038206000000173,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.867978000000221,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":1.7056539999998677,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.204670000000078,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ja"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ja uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.0517219999996996,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":8.792352999999821,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.356231000000207,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":1.8189659999998185,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":1.9584569999997257,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":2.5640109999999368,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.1654849999999897,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":1.943398999999772,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":2.0561800000000403,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.333119999999781,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","ko"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) ko uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.3363039999999273,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh declares DOCTYPE and html lang/dir","status":"passed","title":"declares DOCTYPE and html lang/dir","duration":10.554462000000058,"failureMessages":[],"location":{"line":97,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh contains canonical and hreflang alternates for every language","status":"passed","title":"contains canonical and hreflang alternates for every language","duration":2.618872999999894,"failureMessages":[],"location":{"line":106,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh includes Open Graph, Twitter Card, and JSON-LD structured data","status":"passed","title":"includes Open Graph, Twitter Card, and JSON-LD structured data","duration":2.0278080000002774,"failureMessages":[],"location":{"line":117,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh includes methodology, template, and daily sections","status":"passed","title":"includes methodology, template, and daily sections","duration":2.1345470000001114,"failureMessages":[],"location":{"line":130,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh links methodology and template entries to GitHub","status":"passed","title":"links methodology and template entries to GitHub","duration":2.0487459999999373,"failureMessages":[],"location":{"line":136,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh links back to home, sitemap, and other-language versions","status":"passed","title":"links back to home, sitemap, and other-language versions","duration":2.2395430000001397,"failureMessages":[],"location":{"line":143,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh renders a skip-link, semantic main, and ARIA-labelled TOC","status":"passed","title":"renders a skip-link, semantic main, and ARIA-labelled TOC","duration":2.1676189999998314,"failureMessages":[],"location":{"line":156,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"uses the unified `rm-site-header` chrome with theme toggle","duration":2.1176249999998618,"failureMessages":[],"location":{"line":164,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses the unified 3-column `rm-site-footer`","status":"passed","title":"uses the unified 3-column `rm-site-footer`","duration":7.5961230000002615,"failureMessages":[],"location":{"line":170,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","HTML generation (per language)","zh"],"fullName":"Political Intelligence HTML Generation HTML generation (per language) zh uses localized title and subtitle from PI_TRANSLATIONS","status":"passed","title":"uses localized title and subtitle from PI_TRANSLATIONS","duration":2.7829609999998866,"failureMessages":[],"location":{"line":177,"column":9},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence.html on disk","status":"passed","title":"writes political-intelligence.html on disk","duration":14.128293999999642,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_sv.html on disk","status":"passed","title":"writes political-intelligence_sv.html on disk","duration":12.673048000000108,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_da.html on disk","status":"passed","title":"writes political-intelligence_da.html on disk","duration":9.960979999999836,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_no.html on disk","status":"passed","title":"writes political-intelligence_no.html on disk","duration":9.853379000000132,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_fi.html on disk","status":"passed","title":"writes political-intelligence_fi.html on disk","duration":9.821429999999964,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_de.html on disk","status":"passed","title":"writes political-intelligence_de.html on disk","duration":10.488418999999794,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_fr.html on disk","status":"passed","title":"writes political-intelligence_fr.html on disk","duration":14.370887999999923,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_es.html on disk","status":"passed","title":"writes political-intelligence_es.html on disk","duration":29.221854999999778,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_nl.html on disk","status":"passed","title":"writes political-intelligence_nl.html on disk","duration":9.745898000000125,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ar.html on disk","status":"passed","title":"writes political-intelligence_ar.html on disk","duration":10.148682999999892,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_he.html on disk","status":"passed","title":"writes political-intelligence_he.html on disk","duration":10.120950999999877,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ja.html on disk","status":"passed","title":"writes political-intelligence_ja.html on disk","duration":9.959789,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_ko.html on disk","status":"passed","title":"writes political-intelligence_ko.html on disk","duration":10.468181000000186,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","Generated files"],"fullName":"Political Intelligence HTML Generation Generated files writes political-intelligence_zh.html on disk","status":"passed","title":"writes political-intelligence_zh.html on disk","duration":23.486135000000104,"failureMessages":[],"location":{"line":190,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ aggregates keywords from methodology + template titles (capped at 30)","status":"passed","title":"aggregates keywords from methodology + template titles (capped at 30)","duration":10.52614900000026,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ deduplicates keyword entries","status":"passed","title":"deduplicates keyword entries","duration":3.1451090000000477,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ does NOT leak English methodology/template titles into non-EN keywords (W3 regression)","status":"passed","title":"does NOT leak English methodology/template titles into non-EN keywords (W3 regression)","duration":1415.0040209999997,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ keeps the EN methodology titles in the EN PI page (sanity check — no over-correction)","status":"passed","title":"keeps the EN methodology titles in the EN PI page (sanity check — no over-correction)","duration":114.28237100000024,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ emits a FAQPage JSON-LD block","status":"passed","title":"emits a FAQPage JSON-LD block","duration":3.517095000000154,"failureMessages":[],"location":{"line":274,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":7.553944000000229,"failureMessages":[],"location":{"line":278,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Political Intelligence HTML Generation","SEO uplift: keywords + FAQ"],"fullName":"Political Intelligence HTML Generation SEO uplift: keywords + FAQ localises the FAQ heading for non-English pages","status":"passed","title":"localises the FAQ heading for non-English pages","duration":114.23523300000033,"failureMessages":[],"location":{"line":284,"column":5},"meta":{},"tags":[]}],"startTime":1787953809472,"endTime":1787953813420.2354,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-political-intelligence.test.ts"},{"assertionResults":[{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape ampersand","status":"passed","title":"should escape ampersand","duration":3.4250729999999976,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape angle brackets","status":"passed","title":"should escape angle brackets","duration":0.5270270000000892,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape quotes","status":"passed","title":"should escape quotes","duration":0.3818949999999859,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should escape apostrophes","status":"passed","title":"should escape apostrophes","duration":0.3906819999999698,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should handle plain text","status":"passed","title":"should handle plain text","duration":0.5521340000000237,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode existing numeric entities","status":"passed","title":"should not double-encode existing numeric entities","duration":0.3893190000000004,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode decimal entities","status":"passed","title":"should not double-encode decimal entities","duration":0.40818400000000565,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","escapeXml"],"fullName":"RSS Feed Generation escapeXml should not double-encode named entities","status":"passed","title":"should not double-encode named entities","duration":0.3673479999999927,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should return articles","status":"passed","title":"should return articles","duration":137.2899309999999,"failureMessages":[],"location":{"line":90,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should return English articles only","status":"passed","title":"should return English articles only","duration":131.03243199999997,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have multi-language alternates","status":"passed","title":"should have multi-language alternates","duration":172.91293700000006,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should extract article titles","status":"passed","title":"should extract article titles","duration":128.14704800000004,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have valid links","status":"passed","title":"should have valid links","duration":126.58995299999992,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should be sorted by date (most recent first)","status":"passed","title":"should be sorted by date (most recent first)","duration":165.65114300000005,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should limit to 50 articles","status":"passed","title":"should limit to 50 articles","duration":125.03715499999998,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have author field on articles","status":"passed","title":"should have author field on articles","duration":125.45652900000005,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should have category field on articles","status":"passed","title":"should have category field on articles","duration":122.95050400000014,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","getRssArticles"],"fullName":"RSS Feed Generation getRssArticles should derive stable pubDate from filename when meta tag is missing","status":"passed","title":"should derive stable pubDate from filename when meta tag is missing","duration":186.38644399999998,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should return valid RSS 2.0 XML","status":"passed","title":"should return valid RSS 2.0 XML","duration":1.40954899999997,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel element","status":"passed","title":"should have channel element","duration":0.4804300000000694,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel title","status":"passed","title":"should have channel title","duration":0.4859700000001794,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel link","status":"passed","title":"should have channel link","duration":0.3720570000000407,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel description","status":"passed","title":"should have channel description","duration":0.4299850000002152,"failureMessages":[],"location":{"line":188,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have language element","status":"passed","title":"should have language element","duration":0.37470200000007026,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have atom self link","status":"passed","title":"should have atom self link","duration":0.43840100000034,"failureMessages":[],"location":{"line":196,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have atom namespace","status":"passed","title":"should have atom namespace","duration":0.4079229999997551,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have dc namespace","status":"passed","title":"should have dc namespace","duration":0.3778069999998479,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel image","status":"passed","title":"should have channel image","duration":0.4622159999998985,"failureMessages":[],"location":{"line":208,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have items","status":"passed","title":"should have items","duration":0.45662499999980355,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item titles","status":"passed","title":"should have item titles","duration":0.5390200000001641,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item links","status":"passed","title":"should have item links","duration":0.5371259999997164,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have item guids","status":"passed","title":"should have item guids","duration":0.5331690000002709,"failureMessages":[],"location":{"line":227,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have pubDate elements","status":"passed","title":"should have pubDate elements","duration":0.5497299999997267,"failureMessages":[],"location":{"line":231,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have dc:creator elements","status":"passed","title":"should have dc:creator elements","duration":0.49108899999964706,"failureMessages":[],"location":{"line":235,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have per-item category elements","status":"passed","title":"should have per-item category elements","duration":0.5547289999999521,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have multi-language hreflang alternates","status":"passed","title":"should have multi-language hreflang alternates","duration":0.46345800000017334,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have hreflang alternates for multiple languages","status":"passed","title":"should have hreflang alternates for multiple languages","duration":0.8948760000002949,"failureMessages":[],"location":{"line":249,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have channel categories","status":"passed","title":"should have channel categories","duration":0.5528960000001462,"failureMessages":[],"location":{"line":255,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have copyright","status":"passed","title":"should have copyright","duration":0.4946460000001025,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have ttl element","status":"passed","title":"should have ttl element","duration":0.49074800000016694,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have lastBuildDate","status":"passed","title":"should have lastBuildDate","duration":0.47954799999979514,"failureMessages":[],"location":{"line":269,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have generator element","status":"passed","title":"should have generator element","duration":0.5049859999999171,"failureMessages":[],"location":{"line":273,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","generateRss"],"fullName":"RSS Feed Generation generateRss should have docs link","status":"passed","title":"should have docs link","duration":0.5014489999998659,"failureMessages":[],"location":{"line":277,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should pass for valid RSS","status":"passed","title":"should pass for valid RSS","duration":2.2519970000003013,"failureMessages":[],"location":{"line":283,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing XML declaration","status":"passed","title":"should throw for missing XML declaration","duration":0.9507000000003245,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing RSS version","status":"passed","title":"should throw for missing RSS version","duration":0.7497440000001916,"failureMessages":[],"location":{"line":292,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for missing channel","status":"passed","title":"should throw for missing channel","duration":0.738503000000037,"failureMessages":[],"location":{"line":296,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","validateRss"],"fullName":"RSS Feed Generation validateRss should throw for empty feed","status":"passed","title":"should throw for empty feed","duration":0.7367899999999281,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds English feed keeps the branded channel title and en language","status":"passed","title":"English feed keeps the branded channel title and en language","duration":0.6180469999999332,"failureMessages":[],"location":{"line":307,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds Swedish feed localizes title, description, language and self link","status":"passed","title":"Swedish feed localizes title, description, language and self link","duration":127.90203900000006,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds German feed localizes the channel header","status":"passed","title":"German feed localizes the channel header","duration":121.87650799999983,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds Norwegian feed uses BCP-47 hreflang \"nb\" for <language>","status":"passed","title":"Norwegian feed uses BCP-47 hreflang \"nb\" for <language>","duration":117.0616299999997,"failureMessages":[],"location":{"line":330,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds localized item link/guid point at the requested language variant","status":"passed","title":"localized item link/guid point at the requested language variant","duration":183.30492700000013,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["RSS Feed Generation","localized feeds"],"fullName":"RSS Feed Generation localized feeds getRssArticles(lang) anchors items on that language variant","status":"passed","title":"getRssArticles(lang) anchors items on that language variant","duration":131.05940099999998,"failureMessages":[],"location":{"line":345,"column":5},"meta":{},"tags":[]}],"startTime":1787953804640,"endTime":1787953806770.0593,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-rss.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap HTML Generation","escapeHtml"],"fullName":"Sitemap HTML Generation escapeHtml should escape HTML special characters","status":"passed","title":"should escape HTML special characters","duration":3.725485000000049,"failureMessages":[],"location":{"line":42,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","escapeHtml"],"fullName":"Sitemap HTML Generation escapeHtml should handle plain text without changes","status":"passed","title":"should handle plain text without changes","duration":0.6137590000000159,"failureMessages":[],"location":{"line":49,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have metadata for all 14 languages","status":"passed","title":"should have metadata for all 14 languages","duration":1.587742999999989,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have RTL direction for Arabic and Hebrew","status":"passed","title":"should have RTL direction for Arabic and Hebrew","duration":0.4693889999999783,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should have LTR direction for other languages","status":"passed","title":"should have LTR direction for other languages","duration":0.814534999999978,"failureMessages":[],"location":{"line":69,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","LANGUAGE_META"],"fullName":"Sitemap HTML Generation LANGUAGE_META should use nb hreflang for Norwegian","status":"passed","title":"should use nb hreflang for Norwegian","duration":0.46601200000003473,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should return articles grouped by language","status":"passed","title":"should return articles grouped by language","duration":1799.6112320000002,"failureMessages":[],"location":{"line":82,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should include English articles","status":"passed","title":"should include English articles","duration":1902.408343,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should include Swedish articles","status":"passed","title":"should include Swedish articles","duration":1864.633769,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should extract article titles","status":"passed","title":"should extract article titles","duration":1877.6908780000003,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should populate an ISO date (YYYY-MM-DD) parsed from the filename","status":"passed","title":"should populate an ISO date (YYYY-MM-DD) parsed from the filename","duration":1866.0611510000008,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","getArticlesByLanguage"],"fullName":"Sitemap HTML Generation getArticlesByLanguage should return articles sorted by date descending (newest first)","status":"passed","title":"should return articles sorted by date descending (newest first)","duration":1832.7099040000012,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","all-pages contract"],"fullName":"Sitemap HTML Generation all-pages contract should list every English article in the generated HTML (no artificial cap)","status":"passed","title":"should list every English article in the generated HTML (no artificial cap)","duration":1831.878525,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","all-pages contract"],"fullName":"Sitemap HTML Generation all-pages contract should render articles in chronological (desc) order in the HTML","status":"passed","title":"should render articles in chronological (desc) order in the HTML","duration":1817.0226950000015,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate valid HTML for English","status":"passed","title":"should generate valid HTML for English","duration":1827.4968449999978,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate RTL HTML for Arabic","status":"passed","title":"should generate RTL HTML for Arabic","duration":1832.725555000001,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should generate RTL HTML for Hebrew","status":"passed","title":"should generate RTL HTML for Hebrew","duration":1837.6454159999994,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include hreflang tags","status":"passed","title":"should include hreflang tags","duration":1833.2851420000006,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include article links for the target language","status":"passed","title":"should include article links for the target language","duration":1815.5746330000002,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include dashboard links","status":"passed","title":"should include dashboard links","duration":1820.9017459999995,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include docs section when docs exist","status":"passed","title":"should include docs section when docs exist","duration":1841.8231349999987,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include proper meta tags","status":"passed","title":"should include proper meta tags","duration":1827.2917000000016,"failureMessages":[],"location":{"line":216,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include skip link for accessibility","status":"passed","title":"should include skip link for accessibility","duration":1827.209745,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include localized section headings","status":"passed","title":"should include localized section headings","duration":1832.5752219999958,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include JSON-LD structured data","status":"passed","title":"should include JSON-LD structured data","duration":1849.2409079999998,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should use index.html for English home link","status":"passed","title":"should use index.html for English home link","duration":1838.0931860000055,"failureMessages":[],"location":{"line":258,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should use language-specific home link for non-English languages","status":"passed","title":"should use language-specific home link for non-English languages","duration":1846.669259000002,"failureMessages":[],"location":{"line":267,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","generateSitemapHtml"],"fullName":"Sitemap HTML Generation generateSitemapHtml should include the unified `rm-site-header` brand row","status":"passed","title":"should include the unified `rm-site-header` brand row","duration":1855.4431669999976,"failureMessages":[],"location":{"line":279,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the canonical `rm-site-header` (with theme toggle and lang switcher)","status":"passed","title":"emits the canonical `rm-site-header` (with theme toggle and lang switcher)","duration":1.7950409999975818,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the canonical 3-column `rm-site-footer` and footer language row","status":"passed","title":"emits the canonical 3-column `rm-site-footer` and footer language row","duration":1.1258680000028107,"failureMessages":[],"location":{"line":304,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits the anti-flash inline theme bootstrap in <head>","status":"passed","title":"emits the anti-flash inline theme bootstrap in <head>","duration":0.4882339999967371,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits a `BreadcrumbList` JSON-LD blob (Home > Sitemap)","status":"passed","title":"emits a `BreadcrumbList` JSON-LD blob (Home > Sitemap)","duration":0.4951770000043325,"failureMessages":[],"location":{"line":318,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) emits a localised footer (Swedish)","status":"passed","title":"emits a localised footer (Swedish)","duration":1862.9123130000007,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) uses the sitemap-specific lang switcher fallback (`sitemap_sv.html`, not `index_sv.html`)","status":"passed","title":"uses the sitemap-specific lang switcher fallback (`sitemap_sv.html`, not `index_sv.html`)","duration":1.3445579999970505,"failureMessages":[],"location":{"line":331,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Unified chrome contract (parity with article + news-index renderers)"],"fullName":"Sitemap HTML Generation Unified chrome contract (parity with article + news-index renderers) uses og:type=\"website\" (suppresses article:* meta)","status":"passed","title":"uses og:type=\"website\" (suppresses article:* meta)","duration":0.6299790000048233,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a meta description between 140 and 200 chars (EN budget per seo-metadata-contract.md §4)","status":"passed","title":"emits a meta description between 140 and 200 chars (EN budget per seo-metadata-contract.md §4)","duration":2.253629999999248,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a FAQPage JSON-LD block","status":"passed","title":"emits a FAQPage JSON-LD block","duration":0.6086190000060014,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":0.8160879999995814,"failureMessages":[],"location":{"line":362,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ localises the FAQ heading for non-English pages","status":"passed","title":"localises the FAQ heading for non-English pages","duration":1841.7026069999993,"failureMessages":[],"location":{"line":368,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits a WebPage JSON-LD node with @id","status":"passed","title":"emits a WebPage JSON-LD node with @id","duration":1.7952809999987949,"failureMessages":[],"location":{"line":374,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","SEO uplift: meta description + FAQ"],"fullName":"Sitemap HTML Generation SEO uplift: meta description + FAQ emits an ItemList JSON-LD of catalogued articles (up to 200)","status":"passed","title":"emits an ItemList JSON-LD of catalogued articles (up to 200)","duration":0.61600300000282,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap HTML Generation","Generated Files Validation"],"fullName":"Sitemap HTML Generation Generated Files Validation should have valid HTML structure in all existing files","status":"passed","title":"should have valid HTML structure in all existing files","duration":0.6741020000044955,"failureMessages":[],"location":{"line":396,"column":5},"meta":{},"tags":[]}],"startTime":1787953687094,"endTime":1787953734989.674,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-sitemap-html.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should return valid XML string","status":"passed","title":"should return valid XML string","duration":353.885979,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include main index page","status":"passed","title":"should include main index page","duration":258.094651,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include language index pages","status":"passed","title":"should include language index pages","duration":191.20198799999991,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include politician dashboard page","status":"passed","title":"should include politician dashboard page","duration":201.76572699999997,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include dashboard pages","status":"passed","title":"should include dashboard pages","duration":199.43017499999996,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include sitemap HTML pages","status":"passed","title":"should include sitemap HTML pages","duration":242.33588900000018,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include xhtml namespace for hreflang","status":"passed","title":"should include xhtml namespace for hreflang","duration":189.91596900000013,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include hreflang alternate links","status":"passed","title":"should include hreflang alternate links","duration":183.25120000000015,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include changefreq and priority tags","status":"passed","title":"should include changefreq and priority tags","duration":184.4254289999999,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include lastmod tags","status":"passed","title":"should include lastmod tags","duration":225.11570200000006,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include news index pages","status":"passed","title":"should include news index pages","duration":200.06671300000016,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include all 14 news index languages when they exist","status":"passed","title":"should include all 14 news index languages when they exist","duration":186.23659099999986,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should include localized rss feeds that exist on disk","status":"passed","title":"should include localized rss feeds that exist on disk","duration":186.0032940000001,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","generateSitemap"],"fullName":"Sitemap Generation generateSitemap should only reference URLs whose backing files exist","status":"passed","title":"should only reference URLs whose backing files exist","duration":230.13685499999974,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should pass for valid sitemap XML","status":"passed","title":"should pass for valid sitemap XML","duration":195.80874399999993,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should return true for valid sitemap","status":"passed","title":"should return true for valid sitemap","duration":189.205019,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for missing XML declaration","status":"passed","title":"should throw for missing XML declaration","duration":1.0754339999998592,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for missing sitemap namespace","status":"passed","title":"should throw for missing sitemap namespace","duration":0.7003610000001572,"failureMessages":[],"location":{"line":171,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for empty sitemap with no URLs","status":"passed","title":"should throw for empty sitemap with no URLs","duration":0.6373640000001615,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","validateSitemap"],"fullName":"Sitemap Generation validateSitemap should throw for sitemap with no <loc> tags","status":"passed","title":"should throw for sitemap with no <loc> tags","duration":0.6605570000001535,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]}],"startTime":1787953850071,"endTime":1787953853491.6606,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-sitemap.test.ts"},{"assertionResults":[{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh script is executable and bash-syntax clean (and shellcheck-clean if available)","status":"passed","title":"script is executable and bash-syntax clean (and shellcheck-clean if available)","duration":2060.204425,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 1: primary path with bundle + manifest succeeds (dry run)","status":"passed","title":"scenario 1: primary path with bundle + manifest succeeds (dry run)","duration":576.8515520000001,"failureMessages":[],"location":{"line":183,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 1b: auto-probes manifest at agent/aw-fallback.json (current contract location)","status":"passed","title":"scenario 1b: auto-probes manifest at agent/aw-fallback.json (current contract location)","duration":568.8577249999998,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 2: primary path with bundle only derives branch from bundle","status":"passed","title":"scenario 2: primary path with bundle only derives branch from bundle","duration":259.4626980000003,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 3: secondary path on session-not-found + dirty workspace","status":"passed","title":"scenario 3: secondary path on session-not-found + dirty workspace","duration":169.86076900000035,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh scenario 4: no-op when no handoff and no session-not-found marker","status":"passed","title":"scenario 4: no-op when no handoff and no session-not-found marker","duration":75.33140300000014,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh skip when safeoutputs already created the PR","status":"passed","title":"skip when safeoutputs already created the PR","duration":141.88150399999995,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh recovers failed safeoutputs aw-main bundle instead of treating the request as success","status":"passed","title":"recovers failed safeoutputs aw-main bundle instead of treating the request as success","duration":278.46063799999956,"failureMessages":[],"location":{"line":303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh fails non-zero when manifest is malformed JSON","status":"passed","title":"fails non-zero when manifest is malformed JSON","duration":157.87383299999965,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh refuses to push when recovered branch equals the default branch","status":"passed","title":"refuses to push when recovered branch equals the default branch","duration":520.5280279999997,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh refuses to push when recovered commit modifies protected paths","status":"passed","title":"refuses to push when recovered commit modifies protected paths","duration":569.8963890000005,"failureMessages":[],"location":{"line":398,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["gh-aw-pat-pr-fallback.sh"],"fullName":"gh-aw-pat-pr-fallback.sh preflight: exits as a no-op when safeoutputs primary path already opened the PR at recovered SHA","status":"passed","title":"preflight: exits as a no-op when safeoutputs primary path already opened the PR at recovered SHA","duration":709.1469809999999,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]}],"startTime":1787953668871,"endTime":1787953674960.147,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/gh-aw-pat-pr-fallback.test.ts"},{"assertionResults":[{"ancestorTitles":["horizon-context — registry loading"],"fullName":"horizon-context — registry loading loads and returns the registry","status":"passed","title":"loads and returns the registry","duration":4.031298000000049,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — registry loading"],"fullName":"horizon-context — registry loading caches the result (same reference on repeat call)","status":"passed","title":"caches the result (same reference on repeat call)","duration":0.7050489999999741,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType returns the canonical entry for week-ahead","status":"passed","title":"returns the canonical entry for week-ahead","duration":0.6541149999999902,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType returns election-cycle with correct multiplier","status":"passed","title":"returns election-cycle with correct multiplier","duration":0.5046349999999507,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — getArticleType"],"fullName":"horizon-context — getArticleType throws on unknown id","status":"passed","title":"throws on unknown id","duration":1.4073850000000334,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is positive for dates before 2026-09-13","status":"passed","title":"is positive for dates before 2026-09-13","duration":0.726509999999962,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is negative for dates after 2026-09-13","status":"passed","title":"is negative for dates after 2026-09-13","duration":0.49073900000001913,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — daysToElection"],"fullName":"horizon-context — daysToElection is zero on election day","status":"passed","title":"is zero on election day","duration":0.37580400000001646,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — activeCycleAnchor"],"fullName":"horizon-context — activeCycleAnchor returns current before 2026-09-13","status":"passed","title":"returns current before 2026-09-13","duration":0.48357600000002776,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — activeCycleAnchor"],"fullName":"horizon-context — activeCycleAnchor returns next on or after 2026-09-13","status":"passed","title":"returns next on or after 2026-09-13","duration":0.40877499999999145,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Apr-YEAR for May–Oct of YEAR","status":"passed","title":"Apr-YEAR for May–Oct of YEAR","duration":0.5049060000000054,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Oct-YEAR for Nov–Dec of YEAR","status":"passed","title":"Oct-YEAR for Nov–Dec of YEAR","duration":0.4333609999999908,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — weoVintage"],"fullName":"horizon-context — weoVintage Oct-YEAR-1 for Jan–Apr of YEAR","status":"passed","title":"Oct-YEAR-1 for Jan–Apr of YEAR","duration":0.3655039999999872,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase autumn covers Sep–early Dec","status":"passed","title":"autumn covers Sep–early Dec","duration":0.44121599999999717,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase xmas-recess covers late Dec–Jan","status":"passed","title":"xmas-recess covers late Dec–Jan","duration":0.4053389999999695,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase spring covers Feb–early Jun","status":"passed","title":"spring covers Feb–early Jun","duration":0.3856519999999932,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — sessionPhase"],"fullName":"horizon-context — sessionPhase summer-recess covers late Jun–Aug","status":"passed","title":"summer-recess covers late Jun–Aug","duration":0.4451829999999859,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition composes a coherent record for year-ahead 2026-07-05 (typical run)","status":"passed","title":"composes a coherent record for year-ahead 2026-07-05 (typical run)","duration":0.49104900000003227,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition flags cycleRolloverActive within ± 30 days of election","status":"passed","title":"flags cycleRolloverActive within ± 30 days of election","duration":0.38891799999998966,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon-context — horizonContext composition"],"fullName":"horizon-context — horizonContext composition flags cycleRolloverActive outside ± 30 days as false","status":"passed","title":"flags cycleRolloverActive outside ± 30 days as false","duration":0.3554849999999874,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]}],"startTime":1787953894577,"endTime":1787953894592.3555,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/horizon-context.test.ts"},{"assertionResults":[{"ancestorTitles":["hreflang validation across all HTML files"],"fullName":"hreflang validation across all HTML files should find HTML files with hreflang links","status":"passed","title":"should find HTML files with hreflang links","duration":3.6082360000000335,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","absolute URLs"],"fullName":"hreflang validation across all HTML files absolute URLs all hreflang links must use absolute URLs (not relative)","status":"passed","title":"all hreflang links must use absolute URLs (not relative)","duration":0.4352650000000722,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","x-default entry"],"fullName":"hreflang validation across all HTML files x-default entry all multi-language pages must include hreflang=\"x-default\"","status":"passed","title":"all multi-language pages must include hreflang=\"x-default\"","duration":0.49434499999915715,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","valid hreflang codes"],"fullName":"hreflang validation across all HTML files valid hreflang codes all hreflang codes must be valid BCP-47 codes (Norwegian = nb, not no)","status":"passed","title":"all hreflang codes must be valid BCP-47 codes (Norwegian = nb, not no)","duration":0.36284899999918707,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang validation across all HTML files","hreflang href format"],"fullName":"hreflang validation across all HTML files hreflang href format all absolute hreflang URLs must use the correct base URL","status":"passed","title":"all absolute hreflang URLs must use the correct base URL","duration":0.43195900000137044,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["renderHreflangBlock helper"],"fullName":"renderHreflangBlock helper generates absolute URLs with BASE_URL prefix","status":"passed","title":"generates absolute URLs with BASE_URL prefix","duration":23.540281999999934,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderHreflangBlock helper"],"fullName":"renderHreflangBlock helper uses nb hreflang for Norwegian (no) file suffix","status":"passed","title":"uses nb hreflang for Norwegian (no) file suffix","duration":0.6322540000001027,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) all root HTML pages should have hreflang links","status":"passed","title":"all root HTML pages should have hreflang links","duration":89.13662399999885,"failureMessages":[],"location":{"line":244,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) root pages should have absolute hreflang URLs","status":"passed","title":"root pages should have absolute hreflang URLs","duration":64.5268329999999,"failureMessages":[],"location":{"line":252,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","static root pages (index, political-intelligence, politician-dashboard)"],"fullName":"hreflang coverage by page type static root pages (index, political-intelligence, politician-dashboard) root pages should have x-default","status":"passed","title":"root pages should have x-default","duration":51.66113099999893,"failureMessages":[],"location":{"line":264,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) all dashboard pages should have hreflang links","status":"passed","title":"all dashboard pages should have hreflang links","duration":9.271031000000221,"failureMessages":[],"location":{"line":280,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) dashboard pages should have absolute hreflang URLs","status":"passed","title":"dashboard pages should have absolute hreflang URLs","duration":8.732451999998375,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard pages (dashboards/)"],"fullName":"hreflang coverage by page type dashboard pages (dashboards/) dashboard pages should have x-default","status":"passed","title":"dashboard pages should have x-default","duration":9.176483999999618,"failureMessages":[],"location":{"line":300,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard index pages (dashboard/)"],"fullName":"hreflang coverage by page type dashboard index pages (dashboard/) all dashboard index pages should have hreflang links","status":"passed","title":"all dashboard index pages should have hreflang links","duration":1.4154099999996106,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","dashboard index pages (dashboard/)"],"fullName":"hreflang coverage by page type dashboard index pages (dashboard/) dashboard index pages should have absolute hreflang URLs","status":"passed","title":"dashboard index pages should have absolute hreflang URLs","duration":1.5082339999989927,"failureMessages":[],"location":{"line":324,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["hreflang coverage by page type","news article pages"],"fullName":"hreflang coverage by page type news article pages news articles with hreflang should have absolute URLs and x-default","status":"passed","title":"news articles with hreflang should have absolute URLs and x-default","duration":12.067587999999887,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]}],"startTime":1787953803675,"endTime":1787953803953.0676,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/hreflang-validation.test.ts"},{"assertionResults":[{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape ampersands","status":"passed","title":"should escape ampersands","duration":4.024917000000016,"failureMessages":[],"location":{"line":9,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape angle brackets","status":"passed","title":"should escape angle brackets","duration":0.5319160000000238,"failureMessages":[],"location":{"line":13,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape double quotes","status":"passed","title":"should escape double quotes","duration":0.509884999999997,"failureMessages":[],"location":{"line":19,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape single quotes","status":"passed","title":"should escape single quotes","duration":0.3819459999999708,"failureMessages":[],"location":{"line":23,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle null input","status":"passed","title":"should handle null input","duration":0.5342909999999961,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle undefined input","status":"passed","title":"should handle undefined input","duration":0.3692219999999793,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle empty string","status":"passed","title":"should handle empty string","duration":0.3755729999999744,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle numeric input via String coercion","status":"passed","title":"should handle numeric input via String coercion","duration":0.3327129999999556,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should handle strings with no special characters","status":"passed","title":"should handle strings with no special characters","duration":0.590816000000018,"failureMessages":[],"location":{"line":43,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","escapeHtml"],"fullName":"html-utils escapeHtml should escape all special characters together","status":"passed","title":"should escape all special characters together","duration":0.35797999999999774,"failureMessages":[],"location":{"line":47,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode Swedish numeric entities to UTF-8","status":"passed","title":"should decode Swedish numeric entities to UTF-8","duration":0.7387929999999869,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode ä ö å entities","status":"passed","title":"should decode ä ö å entities","duration":0.5656089999999949,"failureMessages":[],"location":{"line":59,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode uppercase Swedish entities","status":"passed","title":"should decode uppercase Swedish entities","duration":0.3938180000000102,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode em-dash and en-dash entities","status":"passed","title":"should decode em-dash and en-dash entities","duration":0.560058999999967,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode hex entities","status":"passed","title":"should decode hex entities","duration":0.44587400000000343,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode named entities","status":"passed","title":"should decode named entities","duration":0.5384180000000356,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode mixed content with entities and regular text","status":"passed","title":"should decode mixed content with entities and regular text","duration":0.3669170000000008,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle text with no entities","status":"passed","title":"should handle text with no entities","duration":0.3468599999999924,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle null input","status":"passed","title":"should handle null input","duration":0.4244850000000042,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle undefined input","status":"passed","title":"should handle undefined input","duration":0.35339100000004464,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should handle empty string","status":"passed","title":"should handle empty string","duration":0.42810200000002396,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should preserve valid UTF-8 characters","status":"passed","title":"should preserve valid UTF-8 characters","duration":0.3712850000000003,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode author name with entities","status":"passed","title":"should decode author name with entities","duration":0.4430889999999863,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["html-utils","decodeHtmlEntities"],"fullName":"html-utils decodeHtmlEntities should decode article title with multiple entity types","status":"passed","title":"should decode article title with multiple entity types","duration":0.5285890000000109,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]}],"startTime":1787953901102,"endTime":1787953901116.5286,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/html-utils.test.ts"},{"assertionResults":[{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":4.317352000000028,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete every entry has non-empty nativeName, flag, locale, hreflang","status":"passed","title":"every entry has non-empty nativeName, flag, locale, hreflang","duration":1.6021590000000288,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete RTL languages have dir=\"rtl\"","status":"passed","title":"RTL languages have dir=\"rtl\"","duration":0.6033390000000054,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete LTR languages have dir=\"ltr\"","status":"passed","title":"LTR languages have dir=\"ltr\"","duration":0.6415920000000597,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete Norwegian uses BCP-47 \"nb\" for hreflang","status":"passed","title":"Norwegian uses BCP-47 \"nb\" for hreflang","duration":0.4387810000000627,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete every language has complete translations object","status":"passed","title":"every language has complete translations object","duration":8.002292000000011,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANGUAGE_META — all 14 languages complete"],"fullName":"LANGUAGE_META — all 14 languages complete non-EN articleEnglishCoverageHeading is translated (not EN copy-paste)","status":"passed","title":"non-EN articleEnglishCoverageHeading is translated (not EN copy-paste)","duration":1.6345000000000027,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness returns a non-null ChromeStrings for every language","status":"passed","title":"returns a non-null ChromeStrings for every language","duration":0.6473719999999048,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness fallback to English for unknown language codes","status":"passed","title":"fallback to English for unknown language codes","duration":0.5560110000000122,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness every language has non-empty sample chrome strings","status":"passed","title":"every language has non-empty sample chrome strings","duration":1.9745770000000675,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness non-EN languages have translated headerTagline (no EN leak)","status":"passed","title":"non-EN languages have translated headerTagline (no EN leak)","duration":0.8840850000000273,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chromeStrings — fallback and completeness"],"fullName":"chromeStrings — fallback and completeness non-EN languages have translated heroSubtitle (no EN leak)","status":"passed","title":"non-EN languages have translated heroSubtitle (no EN leak)","duration":0.691765999999916,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback returns translated label for known types in every language","status":"passed","title":"returns translated label for known types in every language","duration":0.9094619999999622,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback falls back to English for unknown type IDs (all languages get same fallback)","status":"passed","title":"falls back to English for unknown type IDs (all languages get same fallback)","duration":0.5840930000000526,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["articleTypeLabel — per-language with EN fallback"],"fullName":"articleTypeLabel — per-language with EN fallback every registered type has all 14 languages","status":"passed","title":"every registered type has all 14 languages","duration":3.046944000000053,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback en: produces non-empty title from localized input","status":"passed","title":"en: produces non-empty title from localized input","duration":0.8363959999999224,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback en: falls back gracefully when title is empty","status":"passed","title":"en: falls back gracefully when title is empty","duration":0.6836399999999685,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback sv: produces non-empty title from localized input","status":"passed","title":"sv: produces non-empty title from localized input","duration":0.4035660000000689,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback sv: falls back gracefully when title is empty","status":"passed","title":"sv: falls back gracefully when title is empty","duration":0.37549300000000585,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback da: produces non-empty title from localized input","status":"passed","title":"da: produces non-empty title from localized input","duration":0.31679300000007515,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback da: falls back gracefully when title is empty","status":"passed","title":"da: falls back gracefully when title is empty","duration":0.49709999999993215,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback no: produces non-empty title from localized input","status":"passed","title":"no: produces non-empty title from localized input","duration":0.31950799999992796,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback no: falls back gracefully when title is empty","status":"passed","title":"no: falls back gracefully when title is empty","duration":0.33802300000002106,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fi: produces non-empty title from localized input","status":"passed","title":"fi: produces non-empty title from localized input","duration":0.34490500000003976,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fi: falls back gracefully when title is empty","status":"passed","title":"fi: falls back gracefully when title is empty","duration":0.32931700000006003,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback de: produces non-empty title from localized input","status":"passed","title":"de: produces non-empty title from localized input","duration":0.3090589999999338,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback de: falls back gracefully when title is empty","status":"passed","title":"de: falls back gracefully when title is empty","duration":0.3937870000000885,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fr: produces non-empty title from localized input","status":"passed","title":"fr: produces non-empty title from localized input","duration":0.35328100000003815,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback fr: falls back gracefully when title is empty","status":"passed","title":"fr: falls back gracefully when title is empty","duration":0.343913999999927,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback es: produces non-empty title from localized input","status":"passed","title":"es: produces non-empty title from localized input","duration":0.3739699999999857,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback es: falls back gracefully when title is empty","status":"passed","title":"es: falls back gracefully when title is empty","duration":0.5313540000000785,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback nl: produces non-empty title from localized input","status":"passed","title":"nl: produces non-empty title from localized input","duration":0.7031259999999975,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback nl: falls back gracefully when title is empty","status":"passed","title":"nl: falls back gracefully when title is empty","duration":0.41339400000003934,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ar: produces non-empty title from localized input","status":"passed","title":"ar: produces non-empty title from localized input","duration":0.7166620000000421,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ar: falls back gracefully when title is empty","status":"passed","title":"ar: falls back gracefully when title is empty","duration":0.4748780000001034,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback he: produces non-empty title from localized input","status":"passed","title":"he: produces non-empty title from localized input","duration":0.4018019999999751,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback he: falls back gracefully when title is empty","status":"passed","title":"he: falls back gracefully when title is empty","duration":0.40168199999993703,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ja: produces non-empty title from localized input","status":"passed","title":"ja: produces non-empty title from localized input","duration":0.46255600000006325,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ja: falls back gracefully when title is empty","status":"passed","title":"ja: falls back gracefully when title is empty","duration":0.5933710000000474,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ko: produces non-empty title from localized input","status":"passed","title":"ko: produces non-empty title from localized input","duration":0.4884140000000343,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback ko: falls back gracefully when title is empty","status":"passed","title":"ko: falls back gracefully when title is empty","duration":0.48095999999998185,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback zh: produces non-empty title from localized input","status":"passed","title":"zh: produces non-empty title from localized input","duration":0.4560840000000326,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback zh: falls back gracefully when title is empty","status":"passed","title":"zh: falls back gracefully when title is empty","duration":0.5581549999999424,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback CJK titles respect 45-char budget","status":"passed","title":"CJK titles respect 45-char budget","duration":0.64822300000003,"failureMessages":[],"location":{"line":266,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback RTL titles respect 60-char budget","status":"passed","title":"RTL titles respect 60-char budget","duration":0.7690900000000056,"failureMessages":[],"location":{"line":280,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — all 14 languages respect budgets and fallback"],"fullName":"buildSeoTitle — all 14 languages respect budgets and fallback Latin LTR titles respect 70-char budget","status":"passed","title":"Latin LTR titles respect 70-char budget","duration":0.8580860000000712,"failureMessages":[],"location":{"line":294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets en: produces non-empty description","status":"passed","title":"en: produces non-empty description","duration":1.5126719999999523,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets en: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"en: synthesises a non-empty fallback from the title for an empty description","duration":0.77647300000001,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets sv: produces non-empty description","status":"passed","title":"sv: produces non-empty description","duration":0.7474690000000237,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets sv: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"sv: synthesises a non-empty fallback from the title for an empty description","duration":0.7367189999999937,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets da: produces non-empty description","status":"passed","title":"da: produces non-empty description","duration":0.7122739999999794,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets da: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"da: synthesises a non-empty fallback from the title for an empty description","duration":0.7381320000000642,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets no: produces non-empty description","status":"passed","title":"no: produces non-empty description","duration":0.7423800000000256,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets no: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"no: synthesises a non-empty fallback from the title for an empty description","duration":0.725447000000031,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fi: produces non-empty description","status":"passed","title":"fi: produces non-empty description","duration":0.7883160000000089,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fi: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"fi: synthesises a non-empty fallback from the title for an empty description","duration":0.7400149999999712,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets de: produces non-empty description","status":"passed","title":"de: produces non-empty description","duration":0.8068099999999276,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets de: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"de: synthesises a non-empty fallback from the title for an empty description","duration":0.930531999999971,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fr: produces non-empty description","status":"passed","title":"fr: produces non-empty description","duration":0.8657709999999952,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets fr: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"fr: synthesises a non-empty fallback from the title for an empty description","duration":0.8347730000000411,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets es: produces non-empty description","status":"passed","title":"es: produces non-empty description","duration":0.8611419999999725,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets es: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"es: synthesises a non-empty fallback from the title for an empty description","duration":0.902198999999996,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets nl: produces non-empty description","status":"passed","title":"nl: produces non-empty description","duration":0.863666999999964,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets nl: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"nl: synthesises a non-empty fallback from the title for an empty description","duration":1.088647999999921,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ar: produces non-empty description","status":"passed","title":"ar: produces non-empty description","duration":1.5515349999999444,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ar: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ar: synthesises a non-empty fallback from the title for an empty description","duration":1.0176950000000033,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets he: produces non-empty description","status":"passed","title":"he: produces non-empty description","duration":1.0139380000000529,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets he: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"he: synthesises a non-empty fallback from the title for an empty description","duration":1.1805500000000393,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ja: produces non-empty description","status":"passed","title":"ja: produces non-empty description","duration":1.1925529999999753,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ja: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ja: synthesises a non-empty fallback from the title for an empty description","duration":1.1391929999999775,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ko: produces non-empty description","status":"passed","title":"ko: produces non-empty description","duration":1.0053820000000542,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets ko: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"ko: synthesises a non-empty fallback from the title for an empty description","duration":1.0542639999999892,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets zh: produces non-empty description","status":"passed","title":"zh: produces non-empty description","duration":1.0198689999999715,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets zh: synthesises a non-empty fallback from the title for an empty description","status":"passed","title":"zh: synthesises a non-empty fallback from the title for an empty description","duration":1.0837690000000748,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets CJK descriptions respect 120-char budget","status":"passed","title":"CJK descriptions respect 120-char budget","duration":1.3166350000000193,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets RTL descriptions respect 170-char budget","status":"passed","title":"RTL descriptions respect 170-char budget","duration":1.4024060000000418,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — all 14 languages respect budgets"],"fullName":"buildSeoDescription — all 14 languages respect budgets Latin LTR descriptions respect 200-char budget","status":"passed","title":"Latin LTR descriptions respect 200-char budget","duration":1.4102289999999584,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy en: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"en: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":2.1148889999999483,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy sv: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"sv: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.5522760000000062,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy da: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"da: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3750340000000278,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy no: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"no: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.2695169999999507,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy fi: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"fi: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3478730000000496,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy de: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"de: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.6330770000000712,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy fr: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"fr: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.6988300000000436,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy es: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"es: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3267439999999624,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy nl: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"nl: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3756459999999606,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ar: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ar: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.7853619999999637,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy he: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"he: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.346420999999964,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ja: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ja: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.3823680000000422,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy ko: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"ko: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.405571000000009,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy zh: produces non-empty keywords containing Riksdagsmonitor and OSINT","status":"passed","title":"zh: produces non-empty keywords containing Riksdagsmonitor and OSINT","duration":1.43301299999996,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy non-EN keywords do NOT contain English-only tokens","status":"passed","title":"non-EN keywords do NOT contain English-only tokens","duration":2.6891440000000557,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildArticleKeywords — all 14 languages with fallback strategy"],"fullName":"buildArticleKeywords — all 14 languages with fallback strategy keywords with briefEntities seeded correctly for all languages","status":"passed","title":"keywords with briefEntities seeded correctly for all languages","duration":3.3262569999999414,"failureMessages":[],"location":{"line":420,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages returns English unchanged for lang=en","status":"passed","title":"returns English unchanged for lang=en","duration":3.035131999999976,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages sv: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"sv: merges with empty localized markdown (pure EN fallback)","duration":8.928626000000008,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages sv: merges localized body with English coverage boundary","status":"passed","title":"sv: merges localized body with English coverage boundary","duration":3.1114350000000286,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages da: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"da: merges with empty localized markdown (pure EN fallback)","duration":5.305732999999918,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages da: merges localized body with English coverage boundary","status":"passed","title":"da: merges localized body with English coverage boundary","duration":1.8644600000000082,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages no: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"no: merges with empty localized markdown (pure EN fallback)","duration":1.5966000000000804,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages no: merges localized body with English coverage boundary","status":"passed","title":"no: merges localized body with English coverage boundary","duration":2.066438000000062,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fi: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"fi: merges with empty localized markdown (pure EN fallback)","duration":1.8085459999999784,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fi: merges localized body with English coverage boundary","status":"passed","title":"fi: merges localized body with English coverage boundary","duration":1.992840000000001,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages de: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"de: merges with empty localized markdown (pure EN fallback)","duration":1.8592200000000503,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages de: merges localized body with English coverage boundary","status":"passed","title":"de: merges localized body with English coverage boundary","duration":1.6431870000000117,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fr: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"fr: merges with empty localized markdown (pure EN fallback)","duration":1.6103140000000167,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages fr: merges localized body with English coverage boundary","status":"passed","title":"fr: merges localized body with English coverage boundary","duration":2.130529000000024,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages es: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"es: merges with empty localized markdown (pure EN fallback)","duration":1.4770249999999123,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages es: merges localized body with English coverage boundary","status":"passed","title":"es: merges localized body with English coverage boundary","duration":1.6125789999999824,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages nl: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"nl: merges with empty localized markdown (pure EN fallback)","duration":1.559570000000008,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages nl: merges localized body with English coverage boundary","status":"passed","title":"nl: merges localized body with English coverage boundary","duration":1.786465000000021,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ar: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ar: merges with empty localized markdown (pure EN fallback)","duration":1.6122980000000098,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ar: merges localized body with English coverage boundary","status":"passed","title":"ar: merges localized body with English coverage boundary","duration":2.417204999999967,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages he: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"he: merges with empty localized markdown (pure EN fallback)","duration":1.6621020000000044,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages he: merges localized body with English coverage boundary","status":"passed","title":"he: merges localized body with English coverage boundary","duration":1.6807369999999082,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ja: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ja: merges with empty localized markdown (pure EN fallback)","duration":1.6365240000000085,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ja: merges localized body with English coverage boundary","status":"passed","title":"ja: merges localized body with English coverage boundary","duration":1.718166999999994,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ko: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"ko: merges with empty localized markdown (pure EN fallback)","duration":1.643626999999924,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages ko: merges localized body with English coverage boundary","status":"passed","title":"ko: merges localized body with English coverage boundary","duration":1.7977359999999862,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages zh: merges with empty localized markdown (pure EN fallback)","status":"passed","title":"zh: merges with empty localized markdown (pure EN fallback)","duration":1.7511580000000322,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages zh: merges localized body with English coverage boundary","status":"passed","title":"zh: merges localized body with English coverage boundary","duration":1.8120720000000574,"failureMessages":[],"location":{"line":479,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["mergeLocalizedWithEnglish — fallback to English for all languages"],"fullName":"mergeLocalizedWithEnglish — fallback to English for all languages buildEnglishCoverageBoundary produces unique heading per language","status":"passed","title":"buildEnglishCoverageBoundary produces unique heading per language","duration":2.1504659999999376,"failureMessages":[],"location":{"line":507,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages CLEAR_FILTERS_LABELS has entry for every language","status":"passed","title":"CLEAR_FILTERS_LABELS has entry for every language","duration":1.8658530000000155,"failureMessages":[],"location":{"line":524,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages RECENCY_LABELS has entry for every language with all 3 keys","status":"passed","title":"RECENCY_LABELS has entry for every language with all 3 keys","duration":2.8082979999999225,"failureMessages":[],"location":{"line":530,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages HERO_METRIC_LABELS has entry for every language with all 4 keys","status":"passed","title":"HERO_METRIC_LABELS has entry for every language with all 4 keys","duration":2.3627440000000206,"failureMessages":[],"location":{"line":540,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages localizeClearFilters falls back to English for unknown language","status":"passed","title":"localizeClearFilters falls back to English for unknown language","duration":1.8444230000000061,"failureMessages":[],"location":{"line":551,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages buildRecencyLabels falls back to English for unknown language","status":"passed","title":"buildRecencyLabels falls back to English for unknown language","duration":1.7915540000000192,"failureMessages":[],"location":{"line":555,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages heroMetricLabels falls back to English for unknown language","status":"passed","title":"heroMetricLabels falls back to English for unknown language","duration":1.9143440000000282,"failureMessages":[],"location":{"line":562,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages non-EN recency labels are translated (differ from EN)","status":"passed","title":"non-EN recency labels are translated (differ from EN)","duration":2.2686169999999493,"failureMessages":[],"location":{"line":568,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-index template i18n — all 14 languages"],"fullName":"news-index template i18n — all 14 languages non-EN hero metric labels are translated (differ from EN)","status":"passed","title":"non-EN hero metric labels are translated (differ from EN)","duration":2.557136999999898,"failureMessages":[],"location":{"line":580,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization maps \"no\" to \"nb\"","status":"passed","title":"maps \"no\" to \"nb\"","duration":2.5707420000001093,"failureMessages":[],"location":{"line":592,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization passes through other codes unchanged","status":"passed","title":"passes through other codes unchanged","duration":2.269278999999983,"failureMessages":[],"location":{"line":596,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["toBcp47 — Norwegian normalization"],"fullName":"toBcp47 — Norwegian normalization uses fallback for undefined/empty input","status":"passed","title":"uses fallback for undefined/empty input","duration":2.45307200000002,"failureMessages":[],"location":{"line":602,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for DE vs. EN on same article","status":"passed","title":"produces distinct translated keywords for DE vs. EN on same article","duration":2.507163999999989,"failureMessages":[],"location":{"line":611,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for JA vs. EN on same article","status":"passed","title":"produces distinct translated keywords for JA vs. EN on same article","duration":2.3873499999999694,"failureMessages":[],"location":{"line":638,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) produces distinct translated keywords for AR vs. EN on same article","status":"passed","title":"produces distinct translated keywords for AR vs. EN on same article","duration":2.402967999999987,"failureMessages":[],"location":{"line":653,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["end-to-end SEO — with translations vs. without (EN fallback)"],"fullName":"end-to-end SEO — with translations vs. without (EN fallback) articleTypeIcon returns an icon for every known type (language-neutral)","status":"passed","title":"articleTypeIcon returns an icon for every known type (language-neutral)","duration":3.088702000000012,"failureMessages":[],"location":{"line":668,"column":3},"meta":{},"tags":[]}],"startTime":1787953662433,"endTime":1787953662633.0886,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/i18n-fallback-all-languages.test.ts"},{"assertionResults":[{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants runs image optimization before page generation in the build pipeline","status":"passed","title":"runs image optimization before page generation in the build pipeline","duration":4.314527999999996,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants keeps every generated variant present with the expected dimensions","status":"passed","title":"keeps every generated variant present with the expected dimensions","duration":24.366424999999992,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants serves every local HTML image (excluding generated news/ pages) through srcset or a picture fallback","status":"passed","title":"serves every local HTML image (excluding generated news/ pages) through srcset or a picture fallback","duration":365.96271200000007,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["responsive image variants"],"fullName":"responsive image variants keeps all local HTML srcset image URLs (excluding generated news/ pages) backed by generated files","status":"passed","title":"keeps all local HTML srcset image URLs (excluding generated news/ pages) backed by generated files","duration":445.70853599999987,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["S3 image content types"],"fullName":"S3 image content types deploys each supported image format with explicit MIME metadata","status":"passed","title":"deploys each supported image format with explicit MIME metadata","duration":1.1253679999999804,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["S3 image content types"],"fullName":"S3 image content types can repair AVIF MIME metadata on existing bucket objects","status":"passed","title":"can repair AVIF MIME metadata on existing bucket objects","duration":0.6640330000000176,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]}],"startTime":1787953871569,"endTime":1787953872411.664,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/image-optimization.test.ts"},{"assertionResults":[{"ancestorTitles":["imf-codes","COUNTRY_CODES"],"fullName":"imf-codes COUNTRY_CODES exposes Nordic + German + EU peer set in ISO-3","status":"passed","title":"exposes Nordic + German + EU peer set in ISO-3","duration":3.903749000000005,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA covers the full Nordic + DE peer set","status":"passed","title":"covers the full Nordic + DE peer set","duration":0.79618099999999,"failureMessages":[],"location":{"line":34,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA is deep-frozen (immutable)","status":"passed","title":"is deep-frozen (immutable)","duration":0.42782099999999446,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","ISO3_TO_IMF_AREA"],"fullName":"imf-codes ISO3_TO_IMF_AREA has a consistent inverse map","status":"passed","title":"has a consistent inverse map","duration":0.8121009999999842,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toDatamapperCode"],"fullName":"imf-codes toDatamapperCode returns ISO-3 codes uppercase, trimmed","status":"passed","title":"returns ISO-3 codes uppercase, trimmed","duration":0.4677149999999983,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toDatamapperCode"],"fullName":"imf-codes toDatamapperCode passes through EU / EURO aggregates","status":"passed","title":"passes through EU / EURO aggregates","duration":0.5310439999999517,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode converts ISO-3 to 3-digit IMF AREA code","status":"passed","title":"converts ISO-3 to 3-digit IMF AREA code","duration":0.5706789999999842,"failureMessages":[],"location":{"line":64,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode throws for unknown ISO-3 instead of silently dropping the request","status":"passed","title":"throws for unknown ISO-3 instead of silently dropping the request","duration":1.2292620000000056,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","toImfAreaCode"],"fullName":"imf-codes toImfAreaCode throws for empty / whitespace input","status":"passed","title":"throws for empty / whitespace input","duration":0.6446469999999636,"failureMessages":[],"location":{"line":74,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","isKnownIso3"],"fullName":"imf-codes isKnownIso3 returns true for mapped codes","status":"passed","title":"returns true for mapped codes","duration":0.5016990000000305,"failureMessages":[],"location":{"line":81,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","isKnownIso3"],"fullName":"imf-codes isKnownIso3 returns false for unknown codes","status":"passed","title":"returns false for unknown codes","duration":0.39789500000000544,"failureMessages":[],"location":{"line":86,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","COUNTRY_NAMES_EN"],"fullName":"imf-codes COUNTRY_NAMES_EN carries English display names for the peer set","status":"passed","title":"carries English display names for the peer set","duration":0.40818500000000313,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","COUNTRY_NAMES_EN"],"fullName":"imf-codes COUNTRY_NAMES_EN covers the expanded Eurozone comparator set (BEL / AUT / IRL)","status":"passed","title":"covers the expanded Eurozone comparator set (BEL / AUT / IRL)","duration":0.3507769999999937,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes returns every ISO-3 code in ISO3_TO_IMF_AREA, sorted","status":"passed","title":"returns every ISO-3 code in ISO3_TO_IMF_AREA, sorted","duration":1.1391229999999837,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes includes the Nordic + DE peer set","status":"passed","title":"includes the Nordic + DE peer set","duration":1.2688459999999964,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-codes","listKnownIso3Codes"],"fullName":"imf-codes listKnownIso3Codes is frozen (immutable)","status":"passed","title":"is frozen (immutable)","duration":0.41212200000001076,"failureMessages":[],"location":{"line":121,"column":5},"meta":{},"tags":[]}],"startTime":1787953903959,"endTime":1787953903973.412,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-codes.test.ts"},{"assertionResults":[{"ancestorTitles":["parseVintage"],"fullName":"parseVintage parses a canonical WEO tag","status":"passed","title":"parses a canonical WEO tag","duration":4.449310000000025,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseVintage"],"fullName":"parseVintage parses a Fiscal Monitor tag","status":"passed","title":"parses a Fiscal Monitor tag","duration":0.7501249999999686,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseVintage"],"fullName":"parseVintage returns null on malformed input","status":"passed","title":"returns null on malformed input","duration":0.7418890000000147,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths reports 0 months for the current vintage","status":"passed","title":"reports 0 months for the current vintage","duration":0.6758560000000102,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths reports the gap in months for older vintages","status":"passed","title":"reports the gap in months for older vintages","duration":0.4893260000000055,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths clamps future-dated vintages to 0","status":"passed","title":"clamps future-dated vintages to 0","duration":0.6200110000000336,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vintageAgeMonths"],"fullName":"vintageAgeMonths returns +Infinity for malformed vintages","status":"passed","title":"returns +Infinity for malformed vintages","duration":0.4264479999999935,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports ok=true on all three probes when the client succeeds","status":"passed","title":"reports ok=true on all three probes when the client succeeds","duration":2.4769469999999956,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes captures network failures into ok=false + error","status":"passed","title":"captures network failures into ok=false + error","duration":1.0491240000000062,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks empty WEO/FM series as not ok (defensive against silent schema drift)","status":"passed","title":"marks empty WEO/FM series as not ok (defensive against silent schema drift)","duration":0.8020209999999679,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks non-object SDMX responses as not ok","status":"passed","title":"marks non-object SDMX responses as not ok","duration":0.8074019999999678,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes marks SDMX 200-but-empty-series responses as not ok with sdmx-empty-series (silent-drift guard)","status":"passed","title":"marks SDMX 200-but-empty-series responses as not ok with sdmx-empty-series (silent-drift guard)","duration":0.5806869999999549,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured when key missing AND endpoint returns 401/403","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured when key missing AND endpoint returns 401/403","duration":0.6737210000000005,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured on 403 when key missing","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured on 403 when key missing","duration":0.6678809999999658,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes reports SDMX as sdmx-subscription-key-not-configured on 404 (real APIM gateway response when no key sent)","status":"passed","title":"reports SDMX as sdmx-subscription-key-not-configured on 404 (real APIM gateway response when no key sent)","duration":0.6322630000000231,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes preserves the raw SDMX error when a key IS configured (so ops can see real cause)","status":"passed","title":"preserves the raw SDMX error when a key IS configured (so ops can see real cause)","duration":1.023727000000008,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes preserves a non-auth SDMX failure (e.g. 503) even when key missing","status":"passed","title":"preserves a non-auth SDMX failure (e.g. 503) even when key missing","duration":0.6880570000000148,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runProbes"],"fullName":"runProbes enforces PROBE_TIMEOUT_MS so a hung IMF endpoint cannot starve the composite-action budget","status":"passed","title":"enforces PROBE_TIMEOUT_MS so a hung IMF endpoint cannot starve the composite-action budget","duration":4.1031920000000355,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=ok with no warning block when fresh + all probes ok","status":"passed","title":"returns status=ok with no warning block when fresh + all probes ok","duration":0.8289519999999584,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=stale-vintage with ℹ️ annotation when vintage > 6 months","status":"passed","title":"returns status=stale-vintage with ℹ️ annotation when vintage > 6 months","duration":0.8669529999999668,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=degraded with ℹ️ block when only the auxiliary SDMX probe failed","status":"passed","title":"returns status=degraded with ℹ️ block when only the auxiliary SDMX probe failed","duration":0.8670930000000681,"failureMessages":[],"location":{"line":317,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport returns status=unavailable with ⚠️ block when a critical WEO/FM probe failed","status":"passed","title":"returns status=unavailable with ⚠️ block when a critical WEO/FM probe failed","duration":0.6672190000000455,"failureMessages":[],"location":{"line":329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildReport"],"fullName":"buildReport treats malformed vintage as definitely stale","status":"passed","title":"treats malformed vintage as definitely stale","duration":0.550200000000018,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatUnavailableWarning"],"fullName":"formatUnavailableWarning renders failed probes with their dataflow + error in the warning text","status":"passed","title":"renders failed probes with their dataflow + error in the warning text","duration":0.6989690000000337,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation mentions the vintage tag and the age in months","status":"passed","title":"mentions the vintage tag and the age in months","duration":0.5979900000000953,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation uses STALE_VINTAGE_MAX_MONTHS in the heading instead of a hardcoded number","status":"passed","title":"uses STALE_VINTAGE_MAX_MONTHS in the heading instead of a hardcoded number","duration":0.5415649999999914,"failureMessages":[],"location":{"line":375,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatStaleVintageAnnotation"],"fullName":"formatStaleVintageAnnotation renders -1 (sentinel for malformed vintage) as \"unknown age\" instead of a literal \"-1 months\"","status":"passed","title":"renders -1 (sentinel for malformed vintage) as \"unknown age\" instead of a literal \"-1 months\"","duration":0.5217370000000301,"failureMessages":[],"location":{"line":380,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatDegradedWarning"],"fullName":"formatDegradedWarning renders failed auxiliary probes without saying IMF is unavailable","status":"passed","title":"renders failed auxiliary probes without saying IMF is unavailable","duration":0.6331959999999981,"failureMessages":[],"location":{"line":389,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport writes imf-context.json on success and does NOT write the unavailable flag","status":"passed","title":"writes imf-context.json on success and does NOT write the unavailable flag","duration":1.267513000000008,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport writes BOTH imf-context.json AND imf-unavailable.flag on connectivity failure","status":"passed","title":"writes BOTH imf-context.json AND imf-unavailable.flag on connectivity failure","duration":1.2398220000000038,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport does NOT write the unavailable flag on degraded auxiliary SDMX failure","status":"passed","title":"does NOT write the unavailable flag on degraded auxiliary SDMX failure","duration":1.4257090000000971,"failureMessages":[],"location":{"line":457,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["writeReport"],"fullName":"writeReport does NOT write the unavailable flag when status is stale-vintage (annotate, do not block)","status":"passed","title":"does NOT write the unavailable flag when status is stale-vintage (annotate, do not block)","duration":1.154991999999993,"failureMessages":[],"location":{"line":475,"column":3},"meta":{},"tags":[]}],"startTime":1787953679676,"endTime":1787953679710.155,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-connectivity.test.ts"},{"assertionResults":[{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue exposes the headline WEO indicators used by article workflows","status":"passed","title":"exposes the headline WEO indicators used by article workflows","duration":4.315208999999982,"failureMessages":[],"location":{"line":25,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue marks every WEO/FM indicator as projection-capable","status":"passed","title":"marks every WEO/FM indicator as projection-capable","duration":0.9359119999999734,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_INDICATORS catalogue"],"fullName":"imf-context IMF_INDICATORS catalogue has policyAreas and committees for every entry","status":"passed","title":"has policyAreas and committees for every entry","duration":2.2168000000000347,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains returns fiscal-policy indicators for \"fiscal policy\"","status":"passed","title":"returns fiscal-policy indicators for \"fiscal policy\"","duration":1.4055309999999963,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains is case-insensitive","status":"passed","title":"is case-insensitive","duration":1.3620910000000208,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains returns an empty list for an empty domain array","status":"passed","title":"returns an empty list for an empty domain array","duration":0.5833519999999908,"failureMessages":[],"location":{"line":69,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForDomains"],"fullName":"imf-context findImfIndicatorsForDomains matches substrings defensively","status":"passed","title":"matches substrings defensively","duration":0.5587859999999978,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee returns FiU (finance) headline indicators","status":"passed","title":"returns FiU (finance) headline indicators","duration":0.692136000000005,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee returns AU (labour market) indicators","status":"passed","title":"returns AU (labour market) indicators","duration":0.6873870000000011,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorsForCommittee"],"fullName":"imf-context findImfIndicatorsForCommittee is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.6008139999999571,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_NORDIC_PEERS"],"fullName":"imf-context IMF_NORDIC_PEERS contains the SE/DK/NO/FI/DE peer set","status":"passed","title":"contains the SE/DK/NO/FI/DE peer set","duration":0.6781700000000228,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","IMF_NORDIC_PEERS"],"fullName":"imf-context IMF_NORDIC_PEERS is immutable","status":"passed","title":"is immutable","duration":0.4864200000000096,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCountryNameEn"],"fullName":"imf-context imfCountryNameEn returns English display names","status":"passed","title":"returns English display names","duration":0.6275549999999726,"failureMessages":[],"location":{"line":111,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCountryNameEn"],"fullName":"imf-context imfCountryNameEn falls back to the upper-cased code when unknown","status":"passed","title":"falls back to the upper-cased code when unknown","duration":0.6416209999999865,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","imfCitation"],"fullName":"imf-context imfCitation joins database and indicator with a colon","status":"passed","title":"joins database and indicator with a colon","duration":0.7719849999999724,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns the matching indicator for a known (database, id) pair","status":"passed","title":"returns the matching indicator for a known (database, id) pair","duration":0.6702450000000226,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode keeps strict ImfDatabase literal callers backwards compatible","status":"passed","title":"keeps strict ImfDatabase literal callers backwards compatible","duration":0.4699590000000171,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode is case-insensitive on both arguments","status":"passed","title":"is case-insensitive on both arguments","duration":0.4869520000000307,"failureMessages":[],"location":{"line":143,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode trims whitespace before matching","status":"passed","title":"trims whitespace before matching","duration":0.47043100000001914,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns undefined for an unknown indicator id","status":"passed","title":"returns undefined for an unknown indicator id","duration":0.5088729999999941,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode returns undefined when database and id do not co-occur","status":"passed","title":"returns undefined when database and id do not co-occur","duration":0.6117150000000038,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCode"],"fullName":"imf-context findImfIndicatorByCode resolves GFS_COFOG committee-aligned spending indicators (post-2026-05 codes)","status":"passed","title":"resolves GFS_COFOG committee-aligned spending indicators (post-2026-05 codes)","duration":0.669885000000022,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation parses a canonical DATABASE:INDICATOR citation","status":"passed","title":"parses a canonical DATABASE:INDICATOR citation","duration":0.6398179999999911,"failureMessages":[],"location":{"line":172,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation normalizes citation database prefixes without unsafe casts","status":"passed","title":"normalizes citation database prefixes without unsafe casts","duration":0.5180000000000291,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation round-trips imfCitation for every catalogue entry","status":"passed","title":"round-trips imfCitation for every catalogue entry","duration":0.9689239999999586,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","findImfIndicatorByCitation"],"fullName":"imf-context findImfIndicatorByCitation returns undefined for malformed citations","status":"passed","title":"returns undefined for malformed citations","duration":0.7339339999999765,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfDatabasesInUse"],"fullName":"imf-context getImfDatabasesInUse includes the IMF databases actually referenced by the catalogue","status":"passed","title":"includes the IMF databases actually referenced by the catalogue","duration":0.7447940000000131,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfDatabasesInUse"],"fullName":"imf-context getImfDatabasesInUse never contains databases absent from IMF_INDICATORS","status":"passed","title":"never contains databases absent from IMF_INDICATORS","duration":0.7012630000000399,"failureMessages":[],"location":{"line":208,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix keys are UPPER-CASE committee codes","status":"passed","title":"keys are UPPER-CASE committee codes","duration":1.0428019999999947,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix FIU surfaces the headline macro+fiscal indicator set","status":"passed","title":"FIU surfaces the headline macro+fiscal indicator set","duration":0.762346999999977,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix FÖU surfaces COFOG GF02_T (defence spending, post-2026-05 code)","status":"passed","title":"FÖU surfaces COFOG GF02_T (defence spending, post-2026-05 code)","duration":0.929128999999989,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix each entry is sorted and deduplicated","status":"passed","title":"each entry is sorted and deduplicated","duration":1.5998050000000035,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","getImfCommitteeMatrix"],"fullName":"imf-context getImfCommitteeMatrix covers every committee referenced by any indicator","status":"passed","title":"covers every committee referenced by any indicator","duration":0.8783540000000016,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","listImfCitations"],"fullName":"imf-context listImfCitations returns every DATABASE:INDICATOR citation, sorted and frozen","status":"passed","title":"returns every DATABASE:INDICATOR citation, sorted and frozen","duration":0.8642480000000319,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","listImfCitations"],"fullName":"imf-context listImfCitations citations are unique","status":"passed","title":"citations are unique","duration":0.6036700000000224,"failureMessages":[],"location":{"line":268,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["imf-context","connectivity pre-flight integration"],"fullName":"imf-context connectivity pre-flight integration exposes the pre-flight surface that workflows depend on","status":"passed","title":"exposes the pre-flight surface that workflows depend on","duration":5.12392600000004,"failureMessages":[],"location":{"line":281,"column":5},"meta":{},"tags":[]}],"startTime":1787953824824,"endTime":1787953824861.124,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-context.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchWeoPayload"],"fullName":"fetchWeoPayload retries transient failures and succeeds before exhausting the budget","status":"passed","title":"retries transient failures and succeeds before exhausting the budget","duration":5.492713999999978,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWeoPayload"],"fullName":"fetchWeoPayload falls back to direct Datamapper REST when repeated empty-series failures persist","status":"passed","title":"falls back to direct Datamapper REST when repeated empty-series failures persist","duration":4.664742999999987,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]}],"startTime":1787953917575,"endTime":1787953917585.6648,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch-cli.test.ts"},{"assertionResults":[{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) identifies IMF as the authoritative economic source","status":"passed","title":"identifies IMF as the authoritative economic source","duration":3.567010000000039,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) carries a current WEO vintage tag in the standard format","status":"passed","title":"carries a current WEO vintage tag in the standard format","duration":0.5926690000000008,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) declares all 9 canonical IMF SDMX 3.0 dataflows (post-2026-05 refactor)","status":"passed","title":"declares all 9 canonical IMF SDMX 3.0 dataflows (post-2026-05 refactor)","duration":0.6050619999999753,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) declares core policy domains with IMF-primary ownership","status":"passed","title":"declares core policy domains with IMF-primary ownership","duration":0.7119329999999877,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) lists at least the core WEO macro+fiscal headline indicators","status":"passed","title":"lists at least the core WEO macro+fiscal headline indicators","duration":0.7511470000000031,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) every indicator has the minimum required fields","status":"passed","title":"every indicator has the minimum required fields","duration":2.085555999999997,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) IMF inventory uses provider routing (no deprecation block)","status":"passed","title":"IMF inventory uses provider routing (no deprecation block)","duration":0.4124519999999734,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) committee matrix covers the main economic committees with IMF provider","status":"passed","title":"committee matrix covers the main economic committees with IMF provider","duration":0.6447979999999802,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/imf/indicators-inventory.json (v1.0 canonical)"],"fullName":"analysis/imf/indicators-inventory.json (v1.0 canonical) totalIndicators count matches the unique indicator-ID count across domains","status":"passed","title":"totalIndicators count matches the unique indicator-ID count across domains","duration":0.6305009999999811,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) is at version 4.1 or higher","status":"passed","title":"is at version 4.1 or higher","duration":0.4324699999999666,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) points at the canonical IMF inventory","status":"passed","title":"points at the canonical IMF inventory","duration":0.3788990000000467,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) master and IMF inventories use provider routing (no deprecation block)","status":"passed","title":"master and IMF inventories use provider routing (no deprecation block)","duration":0.5079709999999977,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/economic-indicators-inventory.json (v4.1 multi-provider)"],"fullName":"analysis/economic-indicators-inventory.json (v4.1 multi-provider) IMF inventory indicators use IMF dataflows directly (no `supersedes` mapping)","status":"passed","title":"IMF inventory indicators use IMF dataflows directly (no `supersedes` mapping)","duration":1.0000220000000013,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]}],"startTime":1787953849632,"endTime":1787953849644,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-inventory.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfDataPoint provider invariant"],"fullName":"ImfDataPoint provider invariant IMF data points must carry provider \"imf\" (compile-time type)","status":"passed","title":"IMF data points must carry provider \"imf\" (compile-time type)","duration":4.713625000000036,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfDataPoint provider invariant"],"fullName":"ImfDataPoint provider invariant a list of IMF data points can be sorted before WB/SCB/Riksbank points","status":"passed","title":"a list of IMF data points can be sorted before WB/SCB/Riksbank points","duration":0.7756620000000112,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCBEconomicProvenance type enforces provider \"scb\"","status":"passed","title":"SCBEconomicProvenance type enforces provider \"scb\"","duration":0.8695069999999987,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB provider is never \"imf\"","status":"passed","title":"SCB provider is never \"imf\"","duration":0.5208049999999957,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB provider is never \"riksbank\"","status":"passed","title":"SCB provider is never \"riksbank\"","duration":0.5601790000000051,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCBFetchPayload top-level provider is \"scb\"","status":"passed","title":"SCBFetchPayload top-level provider is \"scb\"","duration":0.6514500000000112,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract fetchSCBTablePayload emits provider \"scb\" on fail-soft (network down)","status":"passed","title":"fetchSCBTablePayload emits provider \"scb\" on fail-soft (network down)","duration":1.7595039999999926,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB economicProvenance contract"],"fullName":"SCB economicProvenance contract SCB retrieved_at is a valid ISO timestamp","status":"passed","title":"SCB retrieved_at is a valid ISO timestamp","duration":0.48448700000000144,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract RiksbankEconomicProvenance type enforces provider \"riksbank\"","status":"passed","title":"RiksbankEconomicProvenance type enforces provider \"riksbank\"","duration":0.7154499999999757,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract Riksbank provider is never \"imf\"","status":"passed","title":"Riksbank provider is never \"imf\"","duration":0.49777199999999766,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract Riksbank provider is never \"scb\"","status":"passed","title":"Riksbank provider is never \"scb\"","duration":0.5571630000000027,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract RiksbankFetchPayload top-level provider is \"riksbank\"","status":"passed","title":"RiksbankFetchPayload top-level provider is \"riksbank\"","duration":0.5353719999999953,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank economicProvenance contract"],"fullName":"Riksbank economicProvenance contract fetchRiksbankPayload emits provider \"riksbank\" on HTML response","status":"passed","title":"fetchRiksbankPayload emits provider \"riksbank\" on HTML response","duration":7.000786000000005,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence inventory version is at least 4.x","status":"passed","title":"inventory version is at least 4.x","duration":0.7548329999999623,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence macro domain prefers IMF","status":"passed","title":"macro domain prefers IMF","duration":0.6189790000000244,"failureMessages":[],"location":{"line":324,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence fiscal domain prefers IMF","status":"passed","title":"fiscal domain prefers IMF","duration":0.6330449999999814,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence monetary domain prefers IMF","status":"passed","title":"monetary domain prefers IMF","duration":0.6013960000000225,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence external sector prefers IMF","status":"passed","title":"external sector prefers IMF","duration":0.6202410000000214,"failureMessages":[],"location":{"line":336,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence Sweden primary provider is SCB, not IMF","status":"passed","title":"Sweden primary provider is SCB, not IMF","duration":0.7990259999999694,"failureMessages":[],"location":{"line":340,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence IMF databases list includes the canonical SDMX 3.0 dataflows","status":"passed","title":"IMF databases list includes the canonical SDMX 3.0 dataflows","duration":2.3849739999999997,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence master inventory uses provider routing (not a deprecation block)","status":"passed","title":"master inventory uses provider routing (not a deprecation block)","duration":0.7784670000000347,"failureMessages":[],"location":{"line":356,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence master inventory carries IMF identifiers for every macro / fiscal / monetary / external / trade indicator","status":"passed","title":"master inventory carries IMF identifiers for every macro / fiscal / monetary / external / trade indicator","duration":1.0979460000000358,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence every economic indicator (provider !== \"scb\" Swedish-specific & domain ∈ macro/fiscal/monetary/external/trade) MUST come from IMF","status":"passed","title":"every economic indicator (provider !== \"scb\" Swedish-specific & domain ∈ macro/fiscal/monetary/external/trade) MUST come from IMF","duration":0.8016210000000115,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence headline real GDP growth indicator uses IMF WEO","status":"passed","title":"headline real GDP growth indicator uses IMF WEO","duration":0.8498109999999883,"failureMessages":[],"location":{"line":384,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["economic-indicators-inventory.json IMF precedence"],"fullName":"economic-indicators-inventory.json IMF precedence IMF indicators never carry provider \"scb\"","status":"passed","title":"IMF indicators never carry provider \"scb\"","duration":2.372873000000027,"failureMessages":[],"location":{"line":390,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses table command with required --table-id flag","status":"passed","title":"parses table command with required --table-id flag","duration":1.1796390000000088,"failureMessages":[],"location":{"line":406,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses preset command with required --preset flag","status":"passed","title":"parses preset command with required --preset flag","duration":0.9292489999999702,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parses list-presets command","status":"passed","title":"parses list-presets command","duration":0.5281489999999849,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for unknown command","status":"passed","title":"throws for unknown command","duration":1.3273159999999962,"failureMessages":[],"location":{"line":424,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for missing required flag","status":"passed","title":"throws for missing required flag","duration":0.6625510000000077,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing throws for unexpected positional arg","status":"passed","title":"throws for unexpected positional arg","duration":0.8907080000000178,"failureMessages":[],"location":{"line":432,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing parseSCBArgs defaults to help when no command given","status":"passed","title":"parseSCBArgs defaults to help when no command given","duration":0.9155640000000176,"failureMessages":[],"location":{"line":436,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB CLI parsing"],"fullName":"SCB CLI parsing SCB_PRESETS covers all four preset keys","status":"passed","title":"SCB_PRESETS covers all four preset keys","duration":1.171042,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses repo-rate-path command","status":"passed","title":"parses repo-rate-path command","duration":0.8284010000000421,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses fetch command with --kind and --url flags","status":"passed","title":"parses fetch command with --kind and --url flags","duration":0.789828,"failureMessages":[],"location":{"line":460,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parses --persist boolean alongside repo-rate-path","status":"passed","title":"parses --persist boolean alongside repo-rate-path","duration":0.8624249999999734,"failureMessages":[],"location":{"line":467,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing throws for unknown command","status":"passed","title":"throws for unknown command","duration":0.8259259999999813,"failureMessages":[],"location":{"line":472,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing throws for unexpected positional arg","status":"passed","title":"throws for unexpected positional arg","duration":3.597485000000006,"failureMessages":[],"location":{"line":476,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankArgs defaults to help when no command given","status":"passed","title":"parseRiksbankArgs defaults to help when no command given","duration":0.4883440000000405,"failureMessages":[],"location":{"line":480,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankKind accepts all valid kinds","status":"passed","title":"parseRiksbankKind accepts all valid kinds","duration":0.589572999999973,"failureMessages":[],"location":{"line":485,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing parseRiksbankKind throws for invalid kind","status":"passed","title":"parseRiksbankKind throws for invalid kind","duration":0.6075379999999768,"failureMessages":[],"location":{"line":491,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget accepts valid riksbank.se HTTPS URLs","status":"passed","title":"assertRiksbankFetchTarget accepts valid riksbank.se HTTPS URLs","duration":0.9604979999999728,"failureMessages":[],"location":{"line":495,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget rejects non-HTTPS","status":"passed","title":"assertRiksbankFetchTarget rejects non-HTTPS","duration":0.5658189999999763,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank CLI parsing"],"fullName":"Riksbank CLI parsing assertRiksbankFetchTarget rejects non-Riksbank hosts","status":"passed","title":"assertRiksbankFetchTarget rejects non-Riksbank hosts","duration":0.6672399999999925,"failureMessages":[],"location":{"line":503,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants SCB and Riksbank providers are distinct strings","status":"passed","title":"SCB and Riksbank providers are distinct strings","duration":0.6450080000000185,"failureMessages":[],"location":{"line":513,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants neither SCB nor Riksbank providers equal \"imf\"","status":"passed","title":"neither SCB nor Riksbank providers equal \"imf\"","duration":0.5845850000000041,"failureMessages":[],"location":{"line":532,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants neither SCB nor Riksbank providers equal \"worldBank\"","status":"passed","title":"neither SCB nor Riksbank providers equal \"worldBank\"","duration":0.5691749999999729,"failureMessages":[],"location":{"line":537,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Cross-provider identity invariants"],"fullName":"Cross-provider identity invariants a synthetic IMF data point is sorted before SCB and Riksbank","status":"passed","title":"a synthetic IMF data point is sorted before SCB and Riksbank","duration":0.6017359999999599,"failureMessages":[],"location":{"line":542,"column":3},"meta":{},"tags":[]}],"startTime":1787953680789,"endTime":1787953680843.6018,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-precedence-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd produces a valid NewsArticle with required Schema.org fields","status":"passed","title":"produces a valid NewsArticle with required Schema.org fields","duration":5.574057999999923,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes author as Organization","status":"passed","title":"includes author as Organization","duration":0.6712969999999814,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes publisher with logo","status":"passed","title":"includes publisher with logo","duration":0.5816190000000461,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd marks content as isAccessibleForFree","status":"passed","title":"marks content as isAccessibleForFree","duration":0.35966399999995247,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes isPartOf WebSite reference","status":"passed","title":"includes isPartOf WebSite reference","duration":0.48298399999998765,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd includes isBasedOn when provenance is provided","status":"passed","title":"includes isBasedOn when provenance is provided","duration":1.418676000000005,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd omits isBasedOn when provenance is empty","status":"passed","title":"omits isBasedOn when provenance is empty","duration":0.5163770000000341,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd produces valid JSON when serialized","status":"passed","title":"produces valid JSON when serialized","duration":1.199907000000053,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd emits NewsArticle.keywords as a deduped array when keywords are supplied","status":"passed","title":"emits NewsArticle.keywords as a deduped array when keywords are supplied","duration":1.2573149999999487,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd drops NewsArticle.keywords entirely when only blanks are supplied","status":"passed","title":"drops NewsArticle.keywords entirely when only blanks are supplied","duration":0.4067209999999477,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd drops NewsArticle.keywords entirely when no keywords field is supplied","status":"passed","title":"drops NewsArticle.keywords entirely when no keywords field is supplied","duration":0.3850209999999379,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd emits NewsArticle.articleSection when a non-empty value is supplied","status":"passed","title":"emits NewsArticle.articleSection when a non-empty value is supplied","duration":0.34653900000000704,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd trims NewsArticle.articleSection and drops it when only whitespace","status":"passed","title":"trims NewsArticle.articleSection and drops it when only whitespace","duration":0.3685199999999895,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildNewsArticleLd"],"fullName":"jsonld.ts — buildNewsArticleLd survives JSON.stringify with keywords + articleSection both set","status":"passed","title":"survives JSON.stringify with keywords + articleSection both set","duration":0.5223680000000286,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd produces a valid BreadcrumbList with positions","status":"passed","title":"produces a valid BreadcrumbList with positions","duration":0.6561990000000151,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd last entry omits item URL (current page)","status":"passed","title":"last entry omits item URL (current page)","duration":0.39431899999999587,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd intermediate entries include item URL","status":"passed","title":"intermediate entries include item URL","duration":0.34760099999994054,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd throws when entries array is empty","status":"passed","title":"throws when entries array is empty","duration":0.5281089999999722,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd throws when intermediate entry is missing item","status":"passed","title":"throws when intermediate entry is missing item","duration":0.4516559999999572,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildBreadcrumbListLd"],"fullName":"jsonld.ts — buildBreadcrumbListLd exports BREADCRUMB_TITLE_MAX_LENGTH constant","status":"passed","title":"exports BREADCRUMB_TITLE_MAX_LENGTH constant","duration":0.35227999999995063,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd produces a valid WebPage with speakable","status":"passed","title":"produces a valid WebPage with speakable","duration":0.8622239999999692,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd includes isPartOf WebSite reference","status":"passed","title":"includes isPartOf WebSite reference","duration":0.4334720000000516,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd throws when no valid selectors provided","status":"passed","title":"throws when no valid selectors provided","duration":0.5495190000000321,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld.ts — buildSpeakableWebPageLd"],"fullName":"jsonld.ts — buildSpeakableWebPageLd filters blank selectors","status":"passed","title":"filters blank selectors","duration":0.6512000000000171,"failureMessages":[],"location":{"line":247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renderMarkdownToHtml works without importing chrome modules","status":"passed","title":"renderMarkdownToHtml works without importing chrome modules","duration":20.536548999999923,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renders GFM tables","status":"passed","title":"renders GFM tables","duration":5.745409999999993,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome renders GFM strikethrough","status":"passed","title":"renders GFM strikethrough","duration":2.681502000000023,"failureMessages":[],"location":{"line":274,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes script tags in markdown","status":"passed","title":"sanitizes script tags in markdown","duration":3.768367000000012,"failureMessages":[],"location":{"line":279,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes javascript: URLs","status":"passed","title":"sanitizes javascript: URLs","duration":4.181129999999939,"failureMessages":[],"location":{"line":285,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome sanitizes iframe tags","status":"passed","title":"sanitizes iframe tags","duration":2.2778749999999945,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome preserves mermaid code blocks","status":"passed","title":"preserves mermaid code blocks","duration":6.211402999999905,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome generates heading IDs (rehype-slug)","status":"passed","title":"generates heading IDs (rehype-slug)","duration":1.3874779999999873,"failureMessages":[],"location":{"line":302,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown pipeline — independent from chrome"],"fullName":"markdown pipeline — independent from chrome wraps tables in responsive container","status":"passed","title":"wraps tables in responsive container","duration":1.8141669999999976,"failureMessages":[],"location":{"line":307,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries allows className on pre (for mermaid)","status":"passed","title":"allows className on pre (for mermaid)","duration":0.5159060000000864,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries allows id on heading elements (for slug anchors)","status":"passed","title":"allows id on heading elements (for slug anchors)","duration":0.8082839999999578,"failureMessages":[],"location":{"line":327,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown sanitize-schema — security boundaries"],"fullName":"markdown sanitize-schema — security boundaries does not allow onclick or event handlers","status":"passed","title":"does not allow onclick or event handlers","duration":0.6185289999999668,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor converts mermaid code fences to <pre class=\"mermaid\">","status":"passed","title":"converts mermaid code fences to <pre class=\"mermaid\">","duration":0.6298090000000229,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor leaves non-mermaid code fences untouched","status":"passed","title":"leaves non-mermaid code fences untouched","duration":0.5040030000000115,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor handles multiple mermaid blocks","status":"passed","title":"handles multiple mermaid blocks","duration":0.5168879999999945,"failureMessages":[],"location":{"line":359,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor auto-repairs `-->|label]` edge-label closing typo","status":"passed","title":"auto-repairs `-->|label]` edge-label closing typo","duration":0.5378569999999172,"failureMessages":[],"location":{"line":374,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor repairs the typo across multiple arrow shapes","status":"passed","title":"repairs the typo across multiple arrow shapes","duration":0.5297219999999925,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor leaves correct `-->|label|` syntax untouched","status":"passed","title":"leaves correct `-->|label|` syntax untouched","duration":0.8152570000000878,"failureMessages":[],"location":{"line":397,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor does not rewrite `]` inside flowchart node bodies","status":"passed","title":"does not rewrite `]` inside flowchart node bodies","duration":0.7060519999999997,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown — mermaid preprocessor"],"fullName":"markdown — mermaid preprocessor preserves `data-mermaid-source=\"true\"` after sanitization","status":"passed","title":"preserves `data-mermaid-source=\"true\"` after sanitization","duration":4.573564999999917,"failureMessages":[],"location":{"line":412,"column":3},"meta":{},"tags":[]}],"startTime":1787953784174,"endTime":1787953784253.5735,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/jsonld-and-markdown-pipeline.test.ts"},{"assertionResults":[{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch extracts matching Lagrådet entries from search HTML","status":"passed","title":"extracts matching Lagrådet entries from search HTML","duration":5.29158799999999,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch returns not_configured when no reference is provided","status":"passed","title":"returns not_configured when no reference is provided","duration":1.4493640000000028,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["lagradet-fetch"],"fullName":"lagradet-fetch does not match adjacent longer reference numbers","status":"passed","title":"does not match adjacent longer reference numbers","duration":0.5019100000000094,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953938511,"endTime":1787953938517.502,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/lagradet-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["initLazyDashboards","Skeleton class"],"fullName":"initLazyDashboards Skeleton class adds chart-skeleton class to container while loading","status":"passed","title":"adds chart-skeleton class to container while loading","duration":12.106395999999961,"failureMessages":[],"location":{"line":78,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Skeleton class"],"fullName":"initLazyDashboards Skeleton class removes chart-skeleton class when loader rejects","status":"passed","title":"removes chart-skeleton class when loader rejects","duration":2.723137999999949,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading does not call loader before intersection","status":"passed","title":"does not call loader before intersection","duration":1.3944810000000416,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading calls loader when container intersects viewport","status":"passed","title":"calls loader when container intersects viewport","duration":1.2463730000000055,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading does not call loader for non-intersecting entries","status":"passed","title":"does not call loader for non-intersecting entries","duration":1.0043400000000133,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading unobserves element after first intersection","status":"passed","title":"unobserves element after first intersection","duration":1.0719270000000165,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Viewport-triggered loading"],"fullName":"initLazyDashboards Viewport-triggered loading calls loader only once even when intersected multiple times","status":"passed","title":"calls loader only once even when intersected multiple times","duration":1.0159119999999575,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Multiple dashboards"],"fullName":"initLazyDashboards Multiple dashboards observes all containers on registration","status":"passed","title":"observes all containers on registration","duration":1.5194649999999683,"failureMessages":[],"location":{"line":178,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Multiple dashboards"],"fullName":"initLazyDashboards Multiple dashboards loads dashboards independently when each intersects","status":"passed","title":"loads dashboards independently when each intersects","duration":1.6982889999999884,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Missing containers"],"fullName":"initLazyDashboards Missing containers skips dashboards whose container is not in the DOM","status":"passed","title":"skips dashboards whose container is not in the DOM","duration":1.9115589999999543,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Missing containers"],"fullName":"initLazyDashboards Missing containers still loads present dashboards when some containers are missing","status":"passed","title":"still loads present dashboards when some containers are missing","duration":1.1988639999999577,"failureMessages":[],"location":{"line":234,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Return value"],"fullName":"initLazyDashboards Return value returns the IntersectionObserver when IO is available","status":"passed","title":"returns the IntersectionObserver when IO is available","duration":0.8849669999999605,"failureMessages":[],"location":{"line":256,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Return value"],"fullName":"initLazyDashboards Return value returns undefined in fallback mode (no IntersectionObserver)","status":"passed","title":"returns undefined in fallback mode (no IntersectionObserver)","duration":0.6689430000000129,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Sync-throw safety"],"fullName":"initLazyDashboards Sync-throw safety removes skeleton and does not propagate when loader throws synchronously (IO path)","status":"passed","title":"removes skeleton and does not propagate when loader throws synchronously (IO path)","duration":2.2537490000000275,"failureMessages":[],"location":{"line":277,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Sync-throw safety"],"fullName":"initLazyDashboards Sync-throw safety removes skeleton and does not propagate when loader throws synchronously (fallback path)","status":"passed","title":"removes skeleton and does not propagate when loader throws synchronously (fallback path)","duration":2.1718159999999784,"failureMessages":[],"location":{"line":295,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) loads all present dashboards immediately when IntersectionObserver is unavailable","status":"passed","title":"loads all present dashboards immediately when IntersectionObserver is unavailable","duration":1.3880889999999795,"failureMessages":[],"location":{"line":314,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) skips missing containers in fallback mode","status":"passed","title":"skips missing containers in fallback mode","duration":0.663772999999992,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) does not throw when IntersectionObserver is unavailable","status":"passed","title":"does not throw when IntersectionObserver is unavailable","duration":0.8468250000000239,"failureMessages":[],"location":{"line":344,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["initLazyDashboards","Fallback (no IntersectionObserver)"],"fullName":"initLazyDashboards Fallback (no IntersectionObserver) applies and removes skeleton class in fallback mode","status":"passed","title":"applies and removes skeleton class in fallback mode","duration":2.3378270000000043,"failureMessages":[],"location":{"line":353,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CHART_SKELETON_CLASS"],"fullName":"CHART_SKELETON_CLASS is \"chart-skeleton\"","status":"passed","title":"is \"chart-skeleton\"","duration":0.6176869999999894,"failureMessages":[],"location":{"line":380,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports DEFAULT_ROOT_MARGIN = \"2000px\"","status":"passed","title":"exports DEFAULT_ROOT_MARGIN = \"2000px\"","duration":0.8524770000000217,"failureMessages":[],"location":{"line":409,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports DEFAULT_THRESHOLD = 0.01","status":"passed","title":"exports DEFAULT_THRESHOLD = 0.01","duration":0.5980099999999879,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract passes DEFAULT_ROOT_MARGIN + DEFAULT_THRESHOLD to the IntersectionObserver by default","status":"passed","title":"passes DEFAULT_ROOT_MARGIN + DEFAULT_THRESHOLD to the IntersectionObserver by default","duration":1.0655450000000428,"failureMessages":[],"location":{"line":417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract exports HOMEPAGE_ROOT_MARGIN = \"300px\"","status":"passed","title":"exports HOMEPAGE_ROOT_MARGIN = \"300px\"","duration":0.5888320000000249,"failureMessages":[],"location":{"line":437,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["DEFAULT_ROOT_MARGIN regression contract"],"fullName":"DEFAULT_ROOT_MARGIN regression contract parses HOMEPAGE_ROOT_MARGIN to a positive sub-viewport pixel count","status":"passed","title":"parses HOMEPAGE_ROOT_MARGIN to a positive sub-viewport pixel count","duration":0.6476630000000227,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx parses single px value","status":"passed","title":"parses single px value","duration":0.5636049999999955,"failureMessages":[],"location":{"line":451,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx parses first component of multi-side margin","status":"passed","title":"parses first component of multi-side margin","duration":0.7811330000000112,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx handles negative values","status":"passed","title":"handles negative values","duration":0.7438129999999887,"failureMessages":[],"location":{"line":459,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for percentage values (cannot resolve without root)","status":"passed","title":"returns 0 for percentage values (cannot resolve without root)","duration":0.6130779999999731,"failureMessages":[],"location":{"line":463,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for undefined","status":"passed","title":"returns 0 for undefined","duration":0.5947130000000129,"failureMessages":[],"location":{"line":467,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for empty string","status":"passed","title":"returns 0 for empty string","duration":0.536233999999979,"failureMessages":[],"location":{"line":471,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRootMarginPx"],"fullName":"parseRootMarginPx returns 0 for malformed input","status":"passed","title":"returns 0 for malformed input","duration":0.6394470000000183,"failureMessages":[],"location":{"line":475,"column":3},"meta":{},"tags":[]}],"startTime":1787953685951,"endTime":1787953685999.6394,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/lazy-loader.test.js"},{"assertionResults":[{"ancestorTitles":["Load CIA Stats Script","Script Configuration"],"fullName":"Load CIA Stats Script Script Configuration should have load-cia-stats.ts script","status":"passed","title":"should have load-cia-stats.ts script","duration":3.829119999999989,"failureMessages":[],"location":{"line":16,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Script Configuration"],"fullName":"Load CIA Stats Script Script Configuration should be a Node.js ES module","status":"passed","title":"should be a Node.js ES module","duration":0.7883260000000405,"failureMessages":[],"location":{"line":21,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CIA Data Source"],"fullName":"Load CIA Stats Script CIA Data Source should reference extraction_summary_report.csv","status":"passed","title":"should reference extraction_summary_report.csv","duration":0.5647880000000214,"failureMessages":[],"location":{"line":30,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CIA Data Source"],"fullName":"Load CIA Stats Script CIA Data Source should fetch from GitHub cia repository","status":"passed","title":"should fetch from GitHub cia repository","duration":0.5055769999999598,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should include ISO 27001 compliance comments","status":"passed","title":"should include ISO 27001 compliance comments","duration":0.6060139999999592,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should document data classification","status":"passed","title":"should document data classification","duration":0.48930599999999913,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should reference GDPR compliance","status":"passed","title":"should reference GDPR compliance","duration":0.45789700000000266,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","ISMS Compliance Documentation"],"fullName":"Load CIA Stats Script ISMS Compliance Documentation should reference Swedish Offentlighetsprincipen","status":"passed","title":"should reference Swedish Offentlighetsprincipen","duration":0.42329300000000103,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_persons statistic","status":"passed","title":"should extract total_persons statistic","duration":0.5587260000000356,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_votes statistic","status":"passed","title":"should extract total_votes statistic","duration":0.4979930000000081,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_documents statistic","status":"passed","title":"should extract total_documents statistic","duration":0.6166949999999929,"failureMessages":[],"location":{"line":82,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_committee_documents statistic","status":"passed","title":"should extract total_committee_documents statistic","duration":0.5588159999999789,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Statistics Extraction"],"fullName":"Load CIA Stats Script Statistics Extraction should extract total_rule_violations statistic","status":"passed","title":"should extract total_rule_violations statistic","duration":0.5816489999999703,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Output Generation"],"fullName":"Load CIA Stats Script Output Generation should output to cia-data/production-stats.json","status":"passed","title":"should output to cia-data/production-stats.json","duration":0.6011450000000309,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Output Generation"],"fullName":"Load CIA Stats Script Output Generation should create JSON output with proper structure","status":"passed","title":"should create JSON output with proper structure","duration":0.7891680000000179,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Caching Strategy"],"fullName":"Load CIA Stats Script Caching Strategy should implement cache freshness check","status":"passed","title":"should implement cache freshness check","duration":0.706813000000011,"failureMessages":[],"location":{"line":119,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Caching Strategy"],"fullName":"Load CIA Stats Script Caching Strategy should include last_updated timestamp","status":"passed","title":"should include last_updated timestamp","duration":0.6404289999999833,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Error Handling"],"fullName":"Load CIA Stats Script Error Handling should have error handling for network failures","status":"passed","title":"should have error handling for network failures","duration":0.6177270000000021,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Error Handling"],"fullName":"Load CIA Stats Script Error Handling should have try-catch blocks","status":"passed","title":"should have try-catch blocks","duration":0.531394999999975,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CSV Parsing"],"fullName":"Load CIA Stats Script CSV Parsing should parse CSV content","status":"passed","title":"should parse CSV content","duration":0.653082999999981,"failureMessages":[],"location":{"line":148,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","CSV Parsing"],"fullName":"Load CIA Stats Script CSV Parsing should handle CSV headers","status":"passed","title":"should handle CSV headers","duration":0.611614999999972,"failureMessages":[],"location":{"line":154,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Data Validation"],"fullName":"Load CIA Stats Script Data Validation should validate extracted statistics are numbers","status":"passed","title":"should validate extracted statistics are numbers","duration":1.1527980000000184,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Data Validation"],"fullName":"Load CIA Stats Script Data Validation should have reasonable statistic values (sanity check)","status":"passed","title":"should have reasonable statistic values (sanity check)","duration":0.7954190000000381,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","Integration with Update Script"],"fullName":"Load CIA Stats Script Integration with Update Script should be compatible with update-stats-from-cia.ts","status":"passed","title":"should be compatible with update-stats-from-cia.ts","duration":0.6881479999999556,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","GitHub Actions Integration"],"fullName":"Load CIA Stats Script GitHub Actions Integration should be referenced in update-cia-csv-data workflow","status":"passed","title":"should be referenced in update-cia-csv-data workflow","duration":0.6980970000000184,"failureMessages":[],"location":{"line":202,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Load CIA Stats Script","GitHub Actions Integration"],"fullName":"Load CIA Stats Script GitHub Actions Integration should have scheduled workflow for daily updates","status":"passed","title":"should have scheduled workflow for daily updates","duration":0.6636120000000005,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]}],"startTime":1787953835330,"endTime":1787953835350.6636,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/load-cia-stats.test.ts"},{"assertionResults":[{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects literal REPLACE THIS H1 placeholder","status":"passed","title":"rejects literal REPLACE THIS H1 placeholder","duration":3.998927999999978,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects Executive Brief Template heading","status":"passed","title":"rejects Executive Brief Template heading","duration":0.6811260000000061,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects AI_MUST_REPLACE marker","status":"passed","title":"rejects AI_MUST_REPLACE marker","duration":0.8240030000000047,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects the banned phrase \"AI-generated political intelligence\"","status":"passed","title":"rejects the banned phrase \"AI-generated political intelligence\"","duration":0.5811380000000099,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects bare boilerplate \"Executive Brief\" (case- and emoji-tolerant)","status":"passed","title":"rejects bare boilerplate \"Executive Brief\" (case- and emoji-tolerant)","duration":1.0576599999999985,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 rejects empty / emoji-only headings","status":"passed","title":"rejects empty / emoji-only headings","duration":0.6934079999999767,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 accepts publishable story-oriented titles","status":"passed","title":"accepts publishable story-oriented titles","duration":0.46033199999999397,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isBannedLocalizedBriefH1"],"fullName":"isBannedLocalizedBriefH1 exposes the banned-pattern list as a frozen contract","status":"passed","title":"exposes the banned-pattern list as a frozen contract","duration":0.8382399999999848,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns both fields when the brief has publishable H1 + BLUF","status":"passed","title":"returns both fields when the brief has publishable H1 + BLUF","duration":31.061849000000052,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 is the REPLACE-THIS-H1 placeholder","status":"passed","title":"falls back to BLUF-derived title when H1 is the REPLACE-THIS-H1 placeholder","duration":4.78635300000002,"failureMessages":[],"location":{"line":163,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 carries the AI_MUST_REPLACE marker","status":"passed","title":"falls back to BLUF-derived title when H1 carries the AI_MUST_REPLACE marker","duration":2.4742729999999824,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 carries the banned phrase \"AI-generated political intelligence\"","status":"passed","title":"falls back to BLUF-derived title when H1 carries the banned phrase \"AI-generated political intelligence\"","duration":5.569818999999995,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null title when H1 is bare boilerplate \"Executive Brief\"","status":"passed","title":"returns null title when H1 is bare boilerplate \"Executive Brief\"","duration":1.0546850000000063,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to a localized BLUF-derived title when the translated H1 is boilerplate","status":"passed","title":"falls back to a localized BLUF-derived title when the translated H1 is boilerplate","duration":8.536433999999986,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo preserves year-led Japanese titles instead of stripping leading digits as emoji","status":"passed","title":"preserves year-led Japanese titles instead of stripping leading digits as emoji","duration":3.877601000000027,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo accepts concise but valid Chinese headlines that are shorter than the Latin minimum","status":"passed","title":"accepts concise but valid Chinese headlines that are shorter than the Latin minimum","duration":2.680880000000002,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to first prose paragraph when no BLUF heading is present","status":"passed","title":"falls back to first prose paragraph when no BLUF heading is present","duration":1.2427470000000085,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null description when BLUF section is empty","status":"passed","title":"returns null description when BLUF section is empty","duration":1.8025250000000597,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo returns null title + null description + empty keywords when markdown is empty or absent","status":"passed","title":"returns null title + null description + empty keywords when markdown is empty or absent","duration":1.4100899999999683,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo truncates a very long BLUF to a sentence boundary","status":"passed","title":"truncates a very long BLUF to a sentence boundary","duration":0.9895930000000135,"failureMessages":[],"location":{"line":287,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo falls back to BLUF-derived title when H1 collapses to the subfolder label after cleaning","status":"passed","title":"falls back to BLUF-derived title when H1 collapses to the subfolder label after cleaning","duration":0.8814200000000483,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo strips new decision-analysis prefix forms from H1 titles","status":"passed","title":"strips new decision-analysis prefix forms from H1 titles","duration":21.441687,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo"],"fullName":"extractLocalizedBriefSeo skips HTML block elements in readFirstParagraph fallback","status":"passed","title":"skips HTML block elements in readFirstParagraph fallback","duration":3.4577540000000226,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]}],"startTime":1787953787859,"endTime":1787953787960.4578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/localized-brief-seo.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should fetch motions with default limit","status":"passed","title":"should fetch motions with default limit","duration":6.212610999999981,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should pass optional rm parameter","status":"passed","title":"should pass optional rm parameter","duration":1.8217410000000314,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.9502390000000105,"failureMessages":[],"location":{"line":58,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMotions"],"fullName":"MCPClient Part 2 fetchMotions should return empty array when response has no motions key","status":"passed","title":"should return empty array when response has no motions key","duration":0.7700510000000236,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should search documents with query parameters","status":"passed","title":"should search documents with query parameters","duration":1.6703569999999672,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.8302040000000375,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should return empty array when response has no documents key","status":"passed","title":"should return empty array when response has no documents key","duration":0.6819169999999986,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=motion on mot documents","status":"passed","title":"should stamp type=motion on mot documents","duration":0.8376480000000015,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=committee-report on bet documents","status":"passed","title":"should stamp type=committee-report on bet documents","duration":1.0529210000000262,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp type=proposition on prop documents","status":"passed","title":"should stamp type=proposition on prop documents","duration":1.0349780000000237,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should stamp subtype from subtyp field","status":"passed","title":"should stamp subtype from subtyp field","duration":0.7221619999999689,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should not overwrite existing type field","status":"passed","title":"should not overwrite existing type field","duration":0.7831059999999752,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should use the dokument key before the documents key","status":"passed","title":"should use the dokument key before the documents key","duration":1.1005010000000084,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchDocuments"],"fullName":"MCPClient Part 2 searchDocuments should expose query diagnostics for empty search results","status":"passed","title":"should expose query diagnostics for empty search results","duration":0.9793530000000032,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should map Swedish doktyp codes to English type strings","status":"passed","title":"should map Swedish doktyp codes to English type strings","duration":0.8873009999999795,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should return the code unchanged for unrecognised doktyp values","status":"passed","title":"should return the code unchanged for unrecognised doktyp values","duration":0.5584559999999783,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should return document for empty/undefined input","status":"passed","title":"should return document for empty/undefined input","duration":0.5689859999999953,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","normalizeDocumentType"],"fullName":"MCPClient Part 2 normalizeDocumentType should be case-insensitive","status":"passed","title":"should be case-insensitive","duration":0.6148509999999874,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should search speeches with query parameters","status":"passed","title":"should search speeches with query parameters","duration":0.9404710000000023,"failureMessages":[],"location":{"line":238,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.87194199999999,"failureMessages":[],"location":{"line":250,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","searchSpeeches"],"fullName":"MCPClient Part 2 searchSpeeches should return empty array when response has no speeches key","status":"passed","title":"should return empty array when response has no speeches key","duration":0.8419260000000008,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should fetch MPs with filters","status":"passed","title":"should fetch MPs with filters","duration":0.9715090000000259,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.7451249999999732,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should pass empty object when no filters provided","status":"passed","title":"should pass empty object when no filters provided","duration":0.7761330000000157,"failureMessages":[],"location":{"line":299,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchMPs"],"fullName":"MCPClient Part 2 fetchMPs should return empty array when response has no mps key","status":"passed","title":"should return empty array when response has no mps key","duration":3.501275000000021,"failureMessages":[],"location":{"line":311,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should fetch voting records with filters","status":"passed","title":"should fetch voting records with filters","duration":1.1637590000000273,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.933618000000024,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should return empty array when response has no votes key","status":"passed","title":"should return empty array when response has no votes key","duration":0.7161010000000374,"failureMessages":[],"location":{"line":347,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchVotingRecords"],"fullName":"MCPClient Part 2 fetchVotingRecords should emit MCP_INDEXING_LAG when current riksmöte is empty but previous has rows","status":"passed","title":"should emit MCP_INDEXING_LAG when current riksmöte is empty but previous has rows","duration":0.8897249999999985,"failureMessages":[],"location":{"line":357,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchDocumentDetailsWithCoverage"],"fullName":"MCPClient Part 2 fetchDocumentDetailsWithCoverage classifies same-day empty content as not_indexed","status":"passed","title":"classifies same-day empty content as not_indexed","duration":0.8926510000000007,"failureMessages":[],"location":{"line":380,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should fetch government documents","status":"passed","title":"should fetch government documents","duration":0.7789980000000014,"failureMessages":[],"location":{"line":400,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should call correct tool name","status":"passed","title":"should call correct tool name","duration":0.7506959999999481,"failureMessages":[],"location":{"line":412,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","fetchGovernmentDocuments"],"fullName":"MCPClient Part 2 fetchGovernmentDocuments should return empty array when response has no documents key","status":"passed","title":"should return empty array when response has no documents key","duration":0.7224019999999882,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should return request statistics","status":"passed","title":"should return request statistics","duration":0.8135429999999815,"failureMessages":[],"location":{"line":437,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should return 0% success rate when no requests made","status":"passed","title":"should return 0% success rate when no requests made","duration":0.9635240000000067,"failureMessages":[],"location":{"line":444,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should calculate success rate correctly","status":"passed","title":"should calculate success rate correctly","duration":1.408296000000064,"failureMessages":[],"location":{"line":449,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","getStats"],"fullName":"MCPClient Part 2 getStats should show 100% success rate when all requests succeed","status":"passed","title":"should show 100% success rate when all requests succeed","duration":1.0317919999999958,"failureMessages":[],"location":{"line":472,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","resetStats"],"fullName":"MCPClient Part 2 resetStats should reset request and error counts to zero","status":"passed","title":"should reset request and error counts to zero","duration":1.0717959999999493,"failureMessages":[],"location":{"line":487,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","resetStats"],"fullName":"MCPClient Part 2 resetStats should reset after errors too","status":"passed","title":"should reset after errors too","duration":1.0685399999999845,"failureMessages":[],"location":{"line":503,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject empty tool names","status":"passed","title":"should reject empty tool names","duration":2.5904800000000705,"failureMessages":[],"location":{"line":514,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject null/undefined tool names","status":"passed","title":"should reject null/undefined tool names","duration":1.1446839999999838,"failureMessages":[],"location":{"line":518,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject non-string tool names","status":"passed","title":"should reject non-string tool names","duration":1.2948240000000624,"failureMessages":[],"location":{"line":523,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject tool names with path traversal characters","status":"passed","title":"should reject tool names with path traversal characters","duration":1.4120539999998982,"failureMessages":[],"location":{"line":527,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should reject tool names with special characters","status":"passed","title":"should reject tool names with special characters","duration":1.207471000000055,"failureMessages":[],"location":{"line":532,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","tool name validation"],"fullName":"MCPClient Part 2 tool name validation should accept valid tool names","status":"passed","title":"should accept valid tool names","duration":1.6545280000000275,"failureMessages":[],"location":{"line":537,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","error counting accuracy"],"fullName":"MCPClient Part 2 error counting accuracy should not over-count errors on retried requests","status":"passed","title":"should not over-count errors on retried requests","duration":1.5499720000000252,"failureMessages":[],"location":{"line":551,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient Part 2","error counting accuracy"],"fullName":"MCPClient Part 2 error counting accuracy should count exactly one error for a fully failed request","status":"passed","title":"should count exactly one error for a fully failed request","duration":1.3384459999999763,"failureMessages":[],"location":{"line":575,"column":5},"meta":{},"tags":[]}],"startTime":1787953667829,"endTime":1787953667886.3384,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-core-part2.test.ts"},{"assertionResults":[{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should export getDefaultClient function","status":"passed","title":"should export getDefaultClient function","duration":3.7039660000000367,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should return MCPClient instance from getDefaultClient","status":"passed","title":"should return MCPClient instance from getDefaultClient","duration":0.9661389999999983,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should return same instance on repeated getDefaultClient calls","status":"passed","title":"should return same instance on repeated getDefaultClient calls","duration":0.39479900000003454,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports should export all convenience functions","status":"passed","title":"should export all convenience functions","duration":0.8043159999999716,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchCalendarEvents should delegate to default client","status":"passed","title":"convenience fetchCalendarEvents should delegate to default client","duration":2.3855970000000184,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchPropositions should delegate to default client","status":"passed","title":"convenience fetchPropositions should delegate to default client","duration":0.8186829999999645,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience searchDocuments should delegate to default client","status":"passed","title":"convenience searchDocuments should delegate to default client","duration":1.5867110000000366,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchMPs should delegate to default client","status":"passed","title":"convenience fetchMPs should delegate to default client","duration":0.8025730000000522,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchMotions should delegate to default client","status":"passed","title":"convenience fetchMotions should delegate to default client","duration":0.9115570000000162,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience searchSpeeches should delegate to default client","status":"passed","title":"convenience searchSpeeches should delegate to default client","duration":0.6348989999999617,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchVotingRecords should delegate to default client","status":"passed","title":"convenience fetchVotingRecords should delegate to default client","duration":0.9735630000000128,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchGovernmentDocuments should delegate to default client","status":"passed","title":"convenience fetchGovernmentDocuments should delegate to default client","duration":0.6671289999999885,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Module convenience exports"],"fullName":"Module convenience exports convenience fetchCommitteeReports should delegate to default client","status":"passed","title":"convenience fetchCommitteeReports should delegate to default client","duration":0.6915149999999812,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]}],"startTime":1787953889950,"endTime":1787953889965.6914,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-exports.test.ts"},{"assertionResults":[{"ancestorTitles":["MCP client smoke"],"fullName":"MCP client smoke returns structured provenance from the live MCP endpoint","status":"skipped","title":"returns structured provenance from the live MCP endpoint","failureMessages":[],"location":{"line":8,"column":3},"meta":{},"tags":[]}],"startTime":1787953656920,"endTime":1787953656920,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-smoke.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchExternalUrlText — abort-during-body regression"],"fullName":"fetchExternalUrlText — abort-during-body regression returns null when the response body rejects after the timeout fires","status":"passed","title":"returns null when the response body rejects after the timeout fires","duration":29.54560299999997,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchExternalUrlText — abort-during-body regression"],"fullName":"fetchExternalUrlText — abort-during-body regression clears the abort timer on transport rejection (no dangling timers)","status":"passed","title":"clears the abort timer on transport rejection (no dangling timers)","duration":0.9305919999999901,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]}],"startTime":1787953911323,"endTime":1787953911353.9307,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client-transport-timeout.test.ts"},{"assertionResults":[{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue deduplicates entries by resource type + id","status":"passed","title":"deduplicates entries by resource type + id","duration":5.495310000000018,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue drains a queued document once full text becomes available","status":"passed","title":"drains a queued document once full text becomes available","duration":2.576334000000031,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue does not write the queue file when there is no retry work","status":"passed","title":"does not write the queue file when there is no retry work","duration":0.8588889999999765,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["mcp retry queue"],"fullName":"mcp retry queue isolates transient document retry failures and emits fetch_error diagnostics","status":"passed","title":"isolates transient document retry failures and emits fetch_error diagnostics","duration":9.121419000000003,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]}],"startTime":1787953866796,"endTime":1787953866815.1213,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-retry-queue.test.ts"},{"assertionResults":[{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all 14 news workflows should exist","status":"passed","title":"all 14 news workflows should exist","duration":4.818591000000026,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should have network.allowed configuration","status":"passed","title":"all workflows should have network.allowed configuration","duration":0.9920880000000238,"failureMessages":[],"location":{"line":295,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should include required MCP service domains","status":"passed","title":"all workflows should include required MCP service domains","duration":4.998518000000047,"failureMessages":[],"location":{"line":304,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency all workflows should have identical network.allowed domain sets","status":"passed","title":"all workflows should have identical network.allowed domain sets","duration":3.5448959999999943,"failureMessages":[],"location":{"line":315,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency network.allowed should include \"defaults\" for gh-aw built-in domains","status":"passed","title":"network.allowed should include \"defaults\" for gh-aw built-in domains","duration":1.0805230000000279,"failureMessages":[],"location":{"line":329,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Network Allowed Domains Consistency"],"fullName":"Network Diagnostics Configuration Network Allowed Domains Consistency network.allowed should include \"node\" for npm registry access","status":"passed","title":"network.allowed should include \"node\" for npm registry access","duration":1.0015349999999899,"failureMessages":[],"location":{"line":338,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-committee-reports.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-committee-reports.md should configure riksdag-regering MCP with correct URL","duration":0.9272060000000124,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-election-cycle.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-election-cycle.md should configure riksdag-regering MCP with correct URL","duration":0.6441859999999906,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-evening-analysis.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-evening-analysis.md should configure riksdag-regering MCP with correct URL","duration":0.7851399999999558,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-interpellations.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-interpellations.md should configure riksdag-regering MCP with correct URL","duration":0.7514170000000036,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-month-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-month-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.7384830000000306,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-monthly-review.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-monthly-review.md should configure riksdag-regering MCP with correct URL","duration":0.5945130000000063,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-motions.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-motions.md should configure riksdag-regering MCP with correct URL","duration":0.6251009999999724,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-propositions.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-propositions.md should configure riksdag-regering MCP with correct URL","duration":0.6729399999999828,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-quarter-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-quarter-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.6819770000000176,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-realtime-monitor.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-realtime-monitor.md should configure riksdag-regering MCP with correct URL","duration":0.6571900000000142,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-translate.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-translate.md should configure riksdag-regering MCP with correct URL","duration":4.921703999999977,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-week-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-week-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.550660999999991,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-weekly-review.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-weekly-review.md should configure riksdag-regering MCP with correct URL","duration":0.6613989999999603,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration news-year-ahead.md should configure riksdag-regering MCP with correct URL","status":"passed","title":"news-year-ahead.md should configure riksdag-regering MCP with correct URL","duration":0.46108299999991686,"failureMessages":[],"location":{"line":350,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration MCP client default URL should match workflow configuration","status":"passed","title":"MCP client default URL should match workflow configuration","duration":0.5818189999999959,"failureMessages":[],"location":{"line":361,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration SCB client default URL should be correctly configured","status":"passed","title":"SCB client default URL should be correctly configured","duration":0.4560840000000326,"failureMessages":[],"location":{"line":377,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Server URL Configuration"],"fullName":"Network Diagnostics Configuration MCP Server URL Configuration mcp-setup.sh should configure gateway URL for AWF sandbox","status":"passed","title":"mcp-setup.sh should configure gateway URL for AWF sandbox","duration":0.6365710000000036,"failureMessages":[],"location":{"line":384,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should document get_sync_status() health check","status":"passed","title":"news-committee-reports.md should document get_sync_status() health check","duration":1.6438670000000002,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-committee-reports.md should have safeoutputs___noop fallback on MCP failure","duration":1.0958109999999124,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-committee-reports.md should use object payload for noop calls","status":"passed","title":"news-committee-reports.md should use object payload for noop calls","duration":1.3707470000000512,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should document get_sync_status() health check","status":"passed","title":"news-election-cycle.md should document get_sync_status() health check","duration":1.1518959999999652,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-election-cycle.md should have safeoutputs___noop fallback on MCP failure","duration":1.3288479999999936,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-election-cycle.md should use object payload for noop calls","status":"passed","title":"news-election-cycle.md should use object payload for noop calls","duration":1.272942999999941,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should document get_sync_status() health check","status":"passed","title":"news-evening-analysis.md should document get_sync_status() health check","duration":1.3434959999999592,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-evening-analysis.md should have safeoutputs___noop fallback on MCP failure","duration":1.1807000000000016,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-evening-analysis.md should use object payload for noop calls","status":"passed","title":"news-evening-analysis.md should use object payload for noop calls","duration":1.3723589999999604,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should document get_sync_status() health check","status":"passed","title":"news-interpellations.md should document get_sync_status() health check","duration":1.0496850000000677,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-interpellations.md should have safeoutputs___noop fallback on MCP failure","duration":0.9888809999999921,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-interpellations.md should use object payload for noop calls","status":"passed","title":"news-interpellations.md should use object payload for noop calls","duration":1.1197459999999637,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should document get_sync_status() health check","status":"passed","title":"news-month-ahead.md should document get_sync_status() health check","duration":1.1386120000000801,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-month-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.0543129999999792,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-month-ahead.md should use object payload for noop calls","status":"passed","title":"news-month-ahead.md should use object payload for noop calls","duration":1.2344509999999218,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should document get_sync_status() health check","status":"passed","title":"news-monthly-review.md should document get_sync_status() health check","duration":1.0799019999999473,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-monthly-review.md should have safeoutputs___noop fallback on MCP failure","duration":1.047070000000076,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-monthly-review.md should use object payload for noop calls","status":"passed","title":"news-monthly-review.md should use object payload for noop calls","duration":1.3374840000000177,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should document get_sync_status() health check","status":"passed","title":"news-motions.md should document get_sync_status() health check","duration":1.4819949999999835,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-motions.md should have safeoutputs___noop fallback on MCP failure","duration":1.460574000000065,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-motions.md should use object payload for noop calls","status":"passed","title":"news-motions.md should use object payload for noop calls","duration":1.5629159999999729,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should document get_sync_status() health check","status":"passed","title":"news-propositions.md should document get_sync_status() health check","duration":1.5184030000000348,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-propositions.md should have safeoutputs___noop fallback on MCP failure","duration":1.5078829999999925,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-propositions.md should use object payload for noop calls","status":"passed","title":"news-propositions.md should use object payload for noop calls","duration":1.6466030000000274,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should document get_sync_status() health check","status":"passed","title":"news-quarter-ahead.md should document get_sync_status() health check","duration":1.684233000000063,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-quarter-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.7658059999999978,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-quarter-ahead.md should use object payload for noop calls","status":"passed","title":"news-quarter-ahead.md should use object payload for noop calls","duration":1.7618589999999585,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should document get_sync_status() health check","status":"passed","title":"news-realtime-monitor.md should document get_sync_status() health check","duration":1.563998999999967,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-realtime-monitor.md should have safeoutputs___noop fallback on MCP failure","duration":1.6656979999999066,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-realtime-monitor.md should use object payload for noop calls","status":"passed","title":"news-realtime-monitor.md should use object payload for noop calls","duration":1.9046260000000075,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should document get_sync_status() health check","status":"passed","title":"news-translate.md should document get_sync_status() health check","duration":1.3372739999999794,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-translate.md should have safeoutputs___noop fallback on MCP failure","duration":1.3838709999999992,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-translate.md should use object payload for noop calls","status":"passed","title":"news-translate.md should use object payload for noop calls","duration":1.6169779999999037,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should document get_sync_status() health check","status":"passed","title":"news-week-ahead.md should document get_sync_status() health check","duration":1.7574299999999994,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-week-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":1.8400050000000192,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-week-ahead.md should use object payload for noop calls","status":"passed","title":"news-week-ahead.md should use object payload for noop calls","duration":1.9258049999999685,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should document get_sync_status() health check","status":"passed","title":"news-weekly-review.md should document get_sync_status() health check","duration":1.7569989999999507,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-weekly-review.md should have safeoutputs___noop fallback on MCP failure","duration":1.7046119999999974,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-weekly-review.md should use object payload for noop calls","status":"passed","title":"news-weekly-review.md should use object payload for noop calls","duration":1.9302640000000792,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should document get_sync_status() health check","status":"passed","title":"news-year-ahead.md should document get_sync_status() health check","duration":1.8409670000000915,"failureMessages":[],"location":{"line":400,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should have safeoutputs___noop fallback on MCP failure","status":"passed","title":"news-year-ahead.md should have safeoutputs___noop fallback on MCP failure","duration":3.1961639999999534,"failureMessages":[],"location":{"line":412,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Health Gate Patterns"],"fullName":"Network Diagnostics Configuration MCP Health Gate Patterns news-year-ahead.md should use object payload for noop calls","status":"passed","title":"news-year-ahead.md should use object payload for noop calls","duration":1.5313370000000077,"failureMessages":[],"location":{"line":425,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-committee-reports.md should set threat detection to warning-only mode","status":"passed","title":"news-committee-reports.md should set threat detection to warning-only mode","duration":1.1976319999999987,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-election-cycle.md should set threat detection to warning-only mode","status":"passed","title":"news-election-cycle.md should set threat detection to warning-only mode","duration":1.0008040000000165,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-evening-analysis.md should set threat detection to warning-only mode","status":"passed","title":"news-evening-analysis.md should set threat detection to warning-only mode","duration":1.6827509999999393,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-interpellations.md should set threat detection to warning-only mode","status":"passed","title":"news-interpellations.md should set threat detection to warning-only mode","duration":1.6254430000000184,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-month-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-month-ahead.md should set threat detection to warning-only mode","duration":1.030909999999949,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-monthly-review.md should set threat detection to warning-only mode","status":"passed","title":"news-monthly-review.md should set threat detection to warning-only mode","duration":0.944248000000016,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-motions.md should set threat detection to warning-only mode","status":"passed","title":"news-motions.md should set threat detection to warning-only mode","duration":0.9308330000000069,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-propositions.md should set threat detection to warning-only mode","status":"passed","title":"news-propositions.md should set threat detection to warning-only mode","duration":0.9605880000000298,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-quarter-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-quarter-ahead.md should set threat detection to warning-only mode","duration":1.0529219999999668,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-realtime-monitor.md should set threat detection to warning-only mode","status":"passed","title":"news-realtime-monitor.md should set threat detection to warning-only mode","duration":1.0711259999999356,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-translate.md should set threat detection to warning-only mode","status":"passed","title":"news-translate.md should set threat detection to warning-only mode","duration":1.076816000000008,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-week-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-week-ahead.md should set threat detection to warning-only mode","duration":1.109136000000035,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-weekly-review.md should set threat detection to warning-only mode","status":"passed","title":"news-weekly-review.md should set threat detection to warning-only mode","duration":1.0306800000000749,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-year-ahead.md should set threat detection to warning-only mode","status":"passed","title":"news-year-ahead.md should set threat detection to warning-only mode","duration":1.2184409999999843,"failureMessages":[],"location":{"line":444,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-committee-reports.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-committee-reports.md should have safe-outputs.allowed-domains covering MCP services","duration":1.9085730000000467,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-election-cycle.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-election-cycle.md should have safe-outputs.allowed-domains covering MCP services","duration":1.336691999999971,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-evening-analysis.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-evening-analysis.md should have safe-outputs.allowed-domains covering MCP services","duration":2.174500999999964,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-interpellations.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-interpellations.md should have safe-outputs.allowed-domains covering MCP services","duration":2.361831000000052,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-month-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-month-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.7682810000000018,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-monthly-review.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-monthly-review.md should have safe-outputs.allowed-domains covering MCP services","duration":1.5559520000000475,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-motions.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-motions.md should have safe-outputs.allowed-domains covering MCP services","duration":1.3972760000000335,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-propositions.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-propositions.md should have safe-outputs.allowed-domains covering MCP services","duration":1.487013999999931,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-quarter-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-quarter-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.3861049999999295,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-realtime-monitor.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-realtime-monitor.md should have safe-outputs.allowed-domains covering MCP services","duration":1.4408680000000231,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-translate.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-translate.md should have safe-outputs.allowed-domains covering MCP services","duration":1.4586910000000444,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-week-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-week-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.530746000000022,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-weekly-review.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-weekly-review.md should have safe-outputs.allowed-domains covering MCP services","duration":1.6933199999999715,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains news-year-ahead.md should have safe-outputs.allowed-domains covering MCP services","status":"passed","title":"news-year-ahead.md should have safe-outputs.allowed-domains covering MCP services","duration":1.513392999999951,"failureMessages":[],"location":{"line":457,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Safe-Output Allowed Domains"],"fullName":"Network Diagnostics Configuration Safe-Output Allowed Domains safe-output domains should be a subset of network.allowed domains (literal or via ecosystem identifier)","status":"passed","title":"safe-output domains should be a subset of network.allowed domains (literal or via ecosystem identifier)","duration":18.919579999999996,"failureMessages":[],"location":{"line":473,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm composite action exists","status":"passed","title":"shared news-prewarm composite action exists","duration":2.0881990000000314,"failureMessages":[],"location":{"line":502,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action labels pre-flight step correctly","status":"passed","title":"shared news-prewarm action labels pre-flight step correctly","duration":1.7791809999999941,"failureMessages":[],"location":{"line":509,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) all workflows reference the shared news-prewarm composite action","status":"passed","title":"all workflows reference the shared news-prewarm composite action","duration":4.1500200000000405,"failureMessages":[],"location":{"line":525,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action has canonical diagnostics content","status":"passed","title":"shared news-prewarm action has canonical diagnostics content","duration":1.768340999999964,"failureMessages":[],"location":{"line":546,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-flight External Reachability Check (runs before MCP Gateway)"],"fullName":"Network Diagnostics Configuration Pre-flight External Reachability Check (runs before MCP Gateway) shared news-prewarm action probes all required MCP/data domains","status":"passed","title":"shared news-prewarm action probes all required MCP/data domains","duration":1.8494719999999916,"failureMessages":[],"location":{"line":554,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-committee-reports.md should expose MCP health gate in effective prompt","status":"passed","title":"news-committee-reports.md should expose MCP health gate in effective prompt","duration":2.3489080000000513,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-committee-reports.md should wire shared pre-flight composite action","status":"passed","title":"news-committee-reports.md should wire shared pre-flight composite action","duration":1.893685000000005,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-election-cycle.md should expose MCP health gate in effective prompt","status":"passed","title":"news-election-cycle.md should expose MCP health gate in effective prompt","duration":2.629232000000002,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-election-cycle.md should wire shared pre-flight composite action","status":"passed","title":"news-election-cycle.md should wire shared pre-flight composite action","duration":1.8011920000000146,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-evening-analysis.md should expose MCP health gate in effective prompt","status":"passed","title":"news-evening-analysis.md should expose MCP health gate in effective prompt","duration":2.4581719999999905,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-evening-analysis.md should wire shared pre-flight composite action","status":"passed","title":"news-evening-analysis.md should wire shared pre-flight composite action","duration":1.8880250000000842,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-interpellations.md should expose MCP health gate in effective prompt","status":"passed","title":"news-interpellations.md should expose MCP health gate in effective prompt","duration":2.334600000000023,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-interpellations.md should wire shared pre-flight composite action","status":"passed","title":"news-interpellations.md should wire shared pre-flight composite action","duration":1.8968919999999798,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-month-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-month-ahead.md should expose MCP health gate in effective prompt","duration":2.4862850000000662,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-month-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-month-ahead.md should wire shared pre-flight composite action","duration":1.8742690000000266,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-monthly-review.md should expose MCP health gate in effective prompt","status":"passed","title":"news-monthly-review.md should expose MCP health gate in effective prompt","duration":3.5111930000000484,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-monthly-review.md should wire shared pre-flight composite action","status":"passed","title":"news-monthly-review.md should wire shared pre-flight composite action","duration":1.868408000000045,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-motions.md should expose MCP health gate in effective prompt","status":"passed","title":"news-motions.md should expose MCP health gate in effective prompt","duration":2.085002999999915,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-motions.md should wire shared pre-flight composite action","status":"passed","title":"news-motions.md should wire shared pre-flight composite action","duration":1.678861999999981,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-propositions.md should expose MCP health gate in effective prompt","status":"passed","title":"news-propositions.md should expose MCP health gate in effective prompt","duration":2.029178999999999,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-propositions.md should wire shared pre-flight composite action","status":"passed","title":"news-propositions.md should wire shared pre-flight composite action","duration":2.520057999999949,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-quarter-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-quarter-ahead.md should expose MCP health gate in effective prompt","duration":2.807235999999989,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-quarter-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-quarter-ahead.md should wire shared pre-flight composite action","duration":1.8105299999999716,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-realtime-monitor.md should expose MCP health gate in effective prompt","status":"passed","title":"news-realtime-monitor.md should expose MCP health gate in effective prompt","duration":2.355278999999996,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-realtime-monitor.md should wire shared pre-flight composite action","status":"passed","title":"news-realtime-monitor.md should wire shared pre-flight composite action","duration":2.07081699999992,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-week-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-week-ahead.md should expose MCP health gate in effective prompt","duration":2.254049000000009,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-week-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-week-ahead.md should wire shared pre-flight composite action","duration":1.7915740000000824,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-weekly-review.md should expose MCP health gate in effective prompt","status":"passed","title":"news-weekly-review.md should expose MCP health gate in effective prompt","duration":2.233812000000057,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-weekly-review.md should wire shared pre-flight composite action","status":"passed","title":"news-weekly-review.md should wire shared pre-flight composite action","duration":1.838512000000037,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-year-ahead.md should expose MCP health gate in effective prompt","status":"passed","title":"news-year-ahead.md should expose MCP health gate in effective prompt","duration":2.2789260000000695,"failureMessages":[],"location":{"line":579,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) news-year-ahead.md should wire shared pre-flight composite action","status":"passed","title":"news-year-ahead.md should wire shared pre-flight composite action","duration":1.8815829999999778,"failureMessages":[],"location":{"line":596,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway)"],"fullName":"Network Diagnostics Configuration In-Prompt MCP Gateway Diagnostics (runs after MCP Gateway) shared news-prewarm action probes the Render MCP endpoint","status":"passed","title":"shared news-prewarm action probes the Render MCP endpoint","duration":2.0133999999999332,"failureMessages":[],"location":{"line":612,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns shared news-prewarm action contains MCP pre-warm step","status":"passed","title":"shared news-prewarm action contains MCP pre-warm step","duration":2.0516509999999926,"failureMessages":[],"location":{"line":625,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-committee-reports.md should reference MCP pre-warm or health check","status":"passed","title":"news-committee-reports.md should reference MCP pre-warm or health check","duration":2.6049970000000258,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-election-cycle.md should reference MCP pre-warm or health check","status":"passed","title":"news-election-cycle.md should reference MCP pre-warm or health check","duration":2.6663619999999355,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-evening-analysis.md should reference MCP pre-warm or health check","status":"passed","title":"news-evening-analysis.md should reference MCP pre-warm or health check","duration":2.6357940000000326,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-interpellations.md should reference MCP pre-warm or health check","status":"passed","title":"news-interpellations.md should reference MCP pre-warm or health check","duration":2.5869729999999436,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-month-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-month-ahead.md should reference MCP pre-warm or health check","duration":2.6252550000000383,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-monthly-review.md should reference MCP pre-warm or health check","status":"passed","title":"news-monthly-review.md should reference MCP pre-warm or health check","duration":2.6068900000000212,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-motions.md should reference MCP pre-warm or health check","status":"passed","title":"news-motions.md should reference MCP pre-warm or health check","duration":2.6914880000000494,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-propositions.md should reference MCP pre-warm or health check","status":"passed","title":"news-propositions.md should reference MCP pre-warm or health check","duration":2.6985630000000356,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-quarter-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-quarter-ahead.md should reference MCP pre-warm or health check","duration":2.8633909999999787,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-realtime-monitor.md should reference MCP pre-warm or health check","status":"passed","title":"news-realtime-monitor.md should reference MCP pre-warm or health check","duration":3.607353000000103,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-translate.md should reference MCP pre-warm or health check","status":"passed","title":"news-translate.md should reference MCP pre-warm or health check","duration":3.2583120000000463,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-week-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-week-ahead.md should reference MCP pre-warm or health check","duration":2.8452960000000758,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-weekly-review.md should reference MCP pre-warm or health check","status":"passed","title":"news-weekly-review.md should reference MCP pre-warm or health check","duration":2.767571999999973,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Pre-warm and Keep-alive Patterns"],"fullName":"Network Diagnostics Configuration Pre-warm and Keep-alive Patterns news-year-ahead.md should reference MCP pre-warm or health check","status":"passed","title":"news-year-ahead.md should reference MCP pre-warm or health check","duration":2.8048820000000205,"failureMessages":[],"location":{"line":638,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Step Ordering Awareness"],"fullName":"Network Diagnostics Configuration Step Ordering Awareness pre-flight steps should be in frontmatter (via shared action), health gate in prompt body","status":"passed","title":"pre-flight steps should be in frontmatter (via shared action), health gate in prompt body","duration":10.546051000000034,"failureMessages":[],"location":{"line":659,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Tool Count Reference"],"fullName":"Network Diagnostics Configuration MCP Tool Count Reference MCP client should reference expected tool count in documentation or code","status":"passed","title":"MCP client should reference expected tool count in documentation or code","duration":2.7959050000000616,"failureMessages":[],"location":{"line":693,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","MCP Tool Count Reference"],"fullName":"Network Diagnostics Configuration MCP Tool Count Reference agentic workflow MCP queries test should exist","status":"passed","title":"agentic workflow MCP queries test should exist","duration":2.318179999999984,"failureMessages":[],"location":{"line":701,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-committee-reports.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-committee-reports.md should reference stakeholder-perspectives artifact","duration":2.6847159999999803,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-election-cycle.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-election-cycle.md should reference stakeholder-perspectives artifact","duration":2.7450589999999693,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-evening-analysis.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-evening-analysis.md should reference stakeholder-perspectives artifact","duration":2.6680249999999432,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-interpellations.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-interpellations.md should reference stakeholder-perspectives artifact","duration":2.645362999999975,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-month-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-month-ahead.md should reference stakeholder-perspectives artifact","duration":2.6690770000000157,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-monthly-review.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-monthly-review.md should reference stakeholder-perspectives artifact","duration":2.624614000000065,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-motions.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-motions.md should reference stakeholder-perspectives artifact","duration":2.9261579999999867,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-propositions.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-propositions.md should reference stakeholder-perspectives artifact","duration":4.1491379999999936,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-quarter-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-quarter-ahead.md should reference stakeholder-perspectives artifact","duration":2.9951469999999745,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-realtime-monitor.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-realtime-monitor.md should reference stakeholder-perspectives artifact","duration":2.9276309999999057,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-week-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-week-ahead.md should reference stakeholder-perspectives artifact","duration":2.920026000000007,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-weekly-review.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-weekly-review.md should reference stakeholder-perspectives artifact","duration":2.9126730000000407,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Network Diagnostics Configuration","Stakeholder Perspectives Reference"],"fullName":"Network Diagnostics Configuration Stakeholder Perspectives Reference news-year-ahead.md should reference stakeholder-perspectives artifact","status":"passed","title":"news-year-ahead.md should reference stakeholder-perspectives artifact","duration":2.97968800000001,"failureMessages":[],"location":{"line":713,"column":7},"meta":{},"tags":[]}],"startTime":1787953663153,"endTime":1787953663473.9797,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/network-diagnostics.test.ts"},{"assertionResults":[{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring wires polling, calendar, lagradet, and RSS context scripts","status":"passed","title":"wires polling, calendar, lagradet, and RSS context scripts","duration":3.8962250000000154,"failureMessages":[],"location":{"line":9,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring exposes optional inputs for calendar org, Lagrådet reference, and RSS dok_ids","status":"passed","title":"exposes optional inputs for calendar org, Lagrådet reference, and RSS dok_ids","duration":0.8737360000000081,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring writes transient pre-warm context artifacts under ignored data/runtime","status":"passed","title":"writes transient pre-warm context artifacts under ignored data/runtime","duration":0.5394099999999753,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action data-context wiring"],"fullName":"news-prewarm composite action data-context wiring derives optional Lagrådet and RSS watch inputs from latest PIR context when inputs are empty","status":"passed","title":"derives optional Lagrådet and RSS watch inputs from latest PIR context when inputs are empty","duration":0.40877499999999145,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]}],"startTime":1787953935870,"endTime":1787953935875.4087,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-prewarm-context-scripts.test.ts"},{"assertionResults":[{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour happy path: writes ARTICLE_DATE / SUBFOLDER / ANALYSIS_DEPTH / FORCE_GENERATION to $GITHUB_ENV","status":"passed","title":"happy path: writes ARTICLE_DATE / SUBFOLDER / ANALYSIS_DEPTH / FORCE_GENERATION to $GITHUB_ENV","duration":12.638585999999975,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour empty article-date defaults to today (UTC, YYYY-MM-DD)","status":"passed","title":"empty article-date defaults to today (UTC, YYYY-MM-DD)","duration":10.078737999999987,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects malformed article_date with an ::error:: annotation","status":"passed","title":"rejects malformed article_date with an ::error:: annotation","duration":8.583320000000015,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects unknown analysis_depth","status":"passed","title":"rejects unknown analysis_depth","duration":9.343261999999982,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects subfolder values with invalid grammar","status":"passed","title":"rejects subfolder values with invalid grammar","duration":6.357762999999977,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour expands language presets for news-translate","status":"passed","title":"expands language presets for news-translate","duration":12.014049999999997,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour clamps out-of-range max_briefs to 2 with a warning","status":"passed","title":"clamps out-of-range max_briefs to 2 with a warning","duration":11.122519000000011,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates cycle_anchor against current|next|both","status":"passed","title":"validates cycle_anchor against current|next|both","duration":19.894884999999988,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates lookback_hours as a positive integer","status":"passed","title":"validates lookback_hours as a positive integer","duration":21.994871999999987,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates focus against votes|debates|questions|all","status":"passed","title":"validates focus against votes|debates|questions|all","duration":19.01087599999994,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour validates article_types as a comma list of [a-z][a-z0-9-]* tokens","status":"passed","title":"validates article_types as a comma list of [a-z][a-z0-9-]* tokens","duration":21.60297300000002,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour rejects non-canonical boolean values for force_generation and force_retranslate","status":"passed","title":"rejects non-canonical boolean values for force_generation and force_retranslate","duration":18.16556099999991,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs runtime behaviour"],"fullName":"news-resolve-inputs runtime behaviour accepts only literal `true` / `false` / empty for force_generation","status":"passed","title":"accepts only literal `true` / `false` / empty for force_generation","duration":83.92504399999996,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]}],"startTime":1787953829776,"endTime":1787953830030.925,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-resolve-inputs-runtime.test.ts"},{"assertionResults":[{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action declares the canonical env-export contract documented in 00-base-contract.md","status":"passed","title":"declares the canonical env-export contract documented in 00-base-contract.md","duration":4.22941000000003,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action rejects malformed article_date (YYYY-MM-DD enforced)","status":"passed","title":"rejects malformed article_date (YYYY-MM-DD enforced)","duration":0.7608040000000074,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts analysis_depth to standard|deep|comprehensive","status":"passed","title":"restricts analysis_depth to standard|deep|comprehensive","duration":0.41046899999997777,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts cycle_anchor to current|next|both","status":"passed","title":"restricts cycle_anchor to current|next|both","duration":0.3424810000000207,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action restricts focus to votes|debates|questions|all","status":"passed","title":"restricts focus to votes|debates|questions|all","duration":0.5124299999999948,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action clamps out-of-range max_briefs to 2 with a warning (matches prior news-translate behaviour)","status":"passed","title":"clamps out-of-range max_briefs to 2 with a warning (matches prior news-translate behaviour)","duration":0.5500200000000177,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action expands the news-translate language presets","status":"passed","title":"expands the news-translate language presets","duration":0.5231499999999869,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-resolve-inputs composite action"],"fullName":"news-resolve-inputs composite action emits a \"Resolved workflow inputs\" audit group to the step log","status":"passed","title":"emits a \"Resolved workflow inputs\" audit group to the step log","duration":0.35312099999998736,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm every news-*.md uses news-prewarm","status":"passed","title":"every news-*.md uses news-prewarm","duration":1.6482159999999908,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-propositions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-propositions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.9976479999999697,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-motions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-motions.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6049029999999789,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-committee-reports.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-committee-reports.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.44844000000000506,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-interpellations.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-interpellations.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.48610000000002174,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-week-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-week-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.46253600000000006,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-month-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-month-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.4922409999999786,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-quarter-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-quarter-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.5347919999999817,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-year-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-year-ahead.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.8141140000000178,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-election-cycle.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-election-cycle.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.7510770000000093,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-weekly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-weekly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6005649999999605,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-monthly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-monthly-review.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.6002550000000042,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-evening-analysis.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-evening-analysis.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.8825429999999983,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-realtime-monitor.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-realtime-monitor.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.717583999999988,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md workflows wire news-resolve-inputs immediately after news-prewarm"],"fullName":"news-*.md workflows wire news-resolve-inputs immediately after news-prewarm news-translate.md wires news-resolve-inputs with correct subfolder/default-depth/extras","status":"passed","title":"news-translate.md wires news-resolve-inputs with correct subfolder/default-depth/extras","duration":0.9332780000000298,"failureMessages":[],"location":{"line":131,"column":49},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md lists every canonical env var","status":"passed","title":"lists every canonical env var","duration":0.7877950000000169,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md cites the news-resolve-inputs composite as the propagation mechanism","status":"passed","title":"cites the news-resolve-inputs composite as the propagation mechanism","duration":0.515235999999959,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runtime input contract is documented in 00-base-contract.md"],"fullName":"runtime input contract is documented in 00-base-contract.md forbids recomputing ARTICLE_DATE/SUBFOLDER inside agent prompts","status":"passed","title":"forbids recomputing ARTICLE_DATE/SUBFOLDER inside agent prompts","duration":0.6416009999999801,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]}],"startTime":1787953828820,"endTime":1787953828841.6416,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-resolve-inputs.test.ts"},{"assertionResults":[{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface declares no scb (pxweb) data MCP server","status":"passed","title":"declares no scb (pxweb) data MCP server","duration":3.887367999999981,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface declares no world-bank data MCP server","status":"passed","title":"declares no world-bank data MCP server","duration":0.7387729999999806,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface does not load the full github toolset (`toolsets: [all]`)","status":"passed","title":"does not load the full github toolset (`toolsets: [all]`)","duration":0.6921760000000177,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface keeps the injected github MCP read-only and minimal for safe-outputs","status":"passed","title":"keeps the injected github MCP read-only and minimal for safe-outputs","duration":0.4264689999999973,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface drops web-fetch and agentic-workflows tools","status":"passed","title":"drops web-fetch and agentic-workflows tools","duration":0.7034370000000081,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface narrows the kept riksdag-regering server to the health-gate tool only","status":"passed","title":"narrows the kept riksdag-regering server to the health-gate tool only","duration":0.6718179999999734,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface keeps the contract-required riksdag-regering MCP URL","status":"passed","title":"keeps the contract-required riksdag-regering MCP URL","duration":0.41693099999997685,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate trimmed per-turn MCP/tool surface"],"fullName":"news-translate trimmed per-turn MCP/tool surface re-baselines max_langs default to 13 (a full source in one run)","status":"passed","title":"re-baselines max_langs default to 13 (a full source in one run)","duration":0.3139679999999885,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]}],"startTime":1787953896864,"endTime":1787953896872.314,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-translate-mcp-surface.test.ts"},{"assertionResults":[{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox never writes the worklist file to /tmp (runner-only, invisible to AWF container)","status":"passed","title":"never writes the worklist file to /tmp (runner-only, invisible to AWF container)","duration":3.6387230000000272,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox writes the worklist file under ${GITHUB_WORKSPACE} so AWF --add-dir exposes it","status":"passed","title":"writes the worklist file under ${GITHUB_WORKSPACE} so AWF --add-dir exposes it","duration":0.5483159999999998,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox writes TRANSLATION_WORKLIST and friends to $GITHUB_ENV (not only $GITHUB_OUTPUT)","status":"passed","title":"writes TRANSLATION_WORKLIST and friends to $GITHUB_ENV (not only $GITHUB_OUTPUT)","duration":1.1091460000000097,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox agent prompt body reads env vars, not unreachable step outputs","status":"passed","title":"agent prompt body reads env vars, not unreachable step outputs","duration":0.669524000000024,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox base contract documents the news-translate runtime env vars","status":"passed","title":"base contract documents the news-translate runtime env vars","duration":0.4999960000000101,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox .gitignore excludes the workspace-scoped worklist file","status":"passed","title":".gitignore excludes the workspace-scoped worklist file","duration":0.46432900000002064,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox emit_bundle is used in every exit path of the worklist step (no leaked OUTPUT-only writes)","status":"passed","title":"emit_bundle is used in every exit path of the worklist step (no leaked OUTPUT-only writes)","duration":0.5226480000000038,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox caps the per-run language batch via max_langs (effective-token control)","status":"passed","title":"caps the per-run language batch via max_langs (effective-token control)","duration":0.6563090000000216,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-translate worklist propagation to agent sandbox"],"fullName":"news-translate worklist propagation to agent sandbox scopes the agent's validator calls to the per-run language batch","status":"passed","title":"scopes the agent's validator calls to the per-run language batch","duration":0.5795549999999707,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]}],"startTime":1787953839649,"endTime":1787953839657.5796,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-translate-worklist-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts realtime monitor is scheduled for the 15:30 UTC catch-up window","status":"passed","title":"realtime monitor is scheduled for the 15:30 UTC catch-up window","duration":3.645655999999974,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts content-generating news workflows use the claude-opus-5 reasoning model","status":"passed","title":"content-generating news workflows use the claude-opus-5 reasoning model","duration":0.7872340000000122,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts the translation workflow stays on the claude-sonnet-4.6 throughput model","status":"passed","title":"the translation workflow stays on the claude-sonnet-4.6 throughput model","duration":0.5281089999999722,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts analysis gate requires explicit full pass-2 declaration and canonical rerun schema fields","status":"passed","title":"analysis gate requires explicit full pass-2 declaration and canonical rerun schema fields","duration":0.5359439999999722,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts methodology-reflection template exposes canonical Pass-2 and Re-run log slots","status":"passed","title":"methodology-reflection template exposes canonical Pass-2 and Re-run log slots","duration":0.8027129999999829,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts time-budget self-monitoring helper is defined in 01 and consumed by 02/03/04/05/06","status":"passed","title":"time-budget self-monitoring helper is defined in 01 and consumed by 02/03/04/05/06","duration":1.125066000000004,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["agentic news workflow pass-2 and budget contracts"],"fullName":"agentic news workflow pass-2 and budget contracts early-scaffold marker is mandated in 03-data-download.md","status":"passed","title":"early-scaffold marker is mandated in 03-data-download.md","duration":0.7652630000000045,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]}],"startTime":1787953894128,"endTime":1787953894135.7654,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-workflow-pass2-budget-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding discovers all 14 news workflow sources","status":"passed","title":"discovers all 14 news workflow sources","duration":3.719404000000054,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-committee-reports.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-committee-reports.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.9581739999999854,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-election-cycle.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-election-cycle.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.537495999999976,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-evening-analysis.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-evening-analysis.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.37525300000004336,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-interpellations.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-interpellations.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4458450000000198,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-month-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-month-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4306359999999927,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-monthly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-monthly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.5082219999999893,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-motions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-motions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.38913800000000265,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-propositions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-propositions.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4476179999999772,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-quarter-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-quarter-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4179430000000366,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-realtime-monitor.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-realtime-monitor.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4233729999999696,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-translate.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-translate.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.47032000000001517,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-week-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-week-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.37143599999996013,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-weekly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-weekly-review.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.350387000000012,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-*.md IMF SDMX subscription key forwarding"],"fullName":"news-*.md IMF SDMX subscription key forwarding news-year-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","status":"passed","title":"news-year-ahead.md forwards secrets.IMF_SDMX_SUBSCRIPTION_KEY to news-prewarm composite action","duration":0.4395230000000083,"failureMessages":[],"location":{"line":44,"column":48},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action declares the IMF SDMX subscription key input"],"fullName":"news-prewarm composite action declares the IMF SDMX subscription key input exposes an `imf-sdmx-subscription-key` input AND exports it to $GITHUB_ENV","status":"passed","title":"exposes an `imf-sdmx-subscription-key` input AND exports it to $GITHUB_ENV","duration":0.8110279999999648,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["news-prewarm composite action declares the IMF SDMX subscription key input"],"fullName":"news-prewarm composite action declares the IMF SDMX subscription key input does not embed `${{ ... }}` template expressions referencing `secrets` or other unsupported contexts","status":"passed","title":"does not embed `${{ ... }}` template expressions referencing `secrets` or other unsupported contexts","duration":0.5363239999999792,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]}],"startTime":1787953893216,"endTime":1787953893228.5364,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/news-workflows-imf-secret.test.ts"},{"assertionResults":[{"ancestorTitles":["no external CDN in runtime JavaScript"],"fullName":"no external CDN in runtime JavaScript no js runtime file loads code from an external CDN host","status":"passed","title":"no js runtime file loads code from an external CDN host","duration":9.867295000000013,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["no external CDN in runtime JavaScript"],"fullName":"no external CDN in runtime JavaScript mermaid-init.mjs imports Mermaid from the vendored same-origin path","status":"passed","title":"mermaid-init.mjs imports Mermaid from the vendored same-origin path","duration":1.0261610000000019,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["no external CDN in rendered news articles"],"fullName":"no external CDN in rendered news articles no rendered news article references an external CDN host","status":"passed","title":"no rendered news article references an external CDN host","duration":7067.9954419999995,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]}],"startTime":1787953857854,"endTime":1787953864932.9954,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/no-external-cdn.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should parse CSV with headers","status":"passed","title":"should parse CSV with headers","duration":5.808335999999997,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should return empty array for empty input","status":"passed","title":"should return empty array for empty input","duration":0.6320729999999912,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","with PapaParse available"],"fullName":"parseCSV with PapaParse available should return empty array for header-only CSV","status":"passed","title":"should return empty array for header-only CSV","duration":0.52346,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should parse CSV with headers using fallback parser","status":"passed","title":"should parse CSV with headers using fallback parser","duration":0.8495209999999815,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should return empty array for empty input","status":"passed","title":"should return empty array for empty input","duration":0.4670239999999808,"failureMessages":[],"location":{"line":84,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should return empty array for header-only CSV","status":"passed","title":"should return empty array for header-only CSV","duration":0.6408999999999878,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should handle quoted fields","status":"passed","title":"should handle quoted fields","duration":0.7589810000000057,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should skip empty lines","status":"passed","title":"should skip empty lines","duration":0.5470550000000003,"failureMessages":[],"location":{"line":99,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseCSV","without PapaParse (CSP-safe fallback)"],"fullName":"parseCSV without PapaParse (CSP-safe fallback) should not use d3.csvParse (CSP-unsafe)","status":"passed","title":"should not use d3.csvParse (CSP-unsafe)","duration":0.8317079999999919,"failureMessages":[],"location":{"line":105,"column":5},"meta":{},"tags":[]}],"startTime":1787953910016,"endTime":1787953910026.8318,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parse-csv.test.ts"},{"assertionResults":[{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have party dashboard container","status":"passed","title":"should have party dashboard container","duration":11.383752999999956,"failureMessages":[],"location":{"line":70,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have dashboard title and description","status":"passed","title":"should have dashboard title and description","duration":5.316473999999971,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Dashboard Structure"],"fullName":"Party Dashboard Dashboard Structure should have footer with data source attribution","status":"passed","title":"should have footer with data source attribution","duration":2.5756620000000225,"failureMessages":[],"location":{"line":85,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyEffectivenessChart canvas","status":"passed","title":"should have partyEffectivenessChart canvas","duration":2.8463890000000447,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyEffectivenessChart should have ARIA role and label","status":"passed","title":"partyEffectivenessChart should have ARIA role and label","duration":3.3495210000000384,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyEffectivenessChart should have screen reader only text","status":"passed","title":"partyEffectivenessChart should have screen reader only text","duration":3.587327000000016,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyComparisonChart canvas","status":"passed","title":"should have partyComparisonChart canvas","duration":2.0675509999999804,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyComparisonChart should have ARIA role and label","status":"passed","title":"partyComparisonChart should have ARIA role and label","duration":2.521370999999988,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyComparisonChart should have screen reader only text","status":"passed","title":"partyComparisonChart should have screen reader only text","duration":2.0946119999999837,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have partyMomentumChart canvas","status":"passed","title":"should have partyMomentumChart canvas","duration":1.755205999999987,"failureMessages":[],"location":{"line":105,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyMomentumChart should have ARIA role and label","status":"passed","title":"partyMomentumChart should have ARIA role and label","duration":2.075615999999968,"failureMessages":[],"location":{"line":111,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements partyMomentumChart should have screen reader only text","status":"passed","title":"partyMomentumChart should have screen reader only text","duration":2.449025000000006,"failureMessages":[],"location":{"line":118,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Canvas Elements"],"fullName":"Party Dashboard Chart Canvas Elements should have coalitionAlignmentChart div container","status":"passed","title":"should have coalitionAlignmentChart div container","duration":1.7208120000000235,"failureMessages":[],"location":{"line":129,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility should have semantic HTML structure","status":"passed","title":"should have semantic HTML structure","duration":4.906406000000061,"failureMessages":[],"location":{"line":143,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility all charts should have proper ARIA attributes","status":"passed","title":"all charts should have proper ARIA attributes","duration":1.802184000000011,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility should have screen reader descriptions for all charts","status":"passed","title":"should have screen reader descriptions for all charts","duration":1.7978259999999864,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Accessibility"],"fullName":"Party Dashboard Accessibility external links should have target=\"_blank\"","status":"passed","title":"external links should have target=\"_blank\"","duration":2.6344830000000456,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Party Configuration"],"fullName":"Party Dashboard Party Configuration should support all 8 Swedish parties","status":"passed","title":"should support all 8 Swedish parties","duration":2.4417009999999664,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Party Configuration"],"fullName":"Party Dashboard Party Configuration should define party colors for Chart.js","status":"passed","title":"should define party colors for Chart.js","duration":2.4102830000000495,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyEffectivenessChart should expect line chart data structure","status":"passed","title":"partyEffectivenessChart should expect line chart data structure","duration":1.5503330000000233,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyComparisonChart should expect bar chart data structure","status":"passed","title":"partyComparisonChart should expect bar chart data structure","duration":1.7314419999999018,"failureMessages":[],"location":{"line":232,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types coalitionAlignmentChart should expect matrix/heatmap structure","status":"passed","title":"coalitionAlignmentChart should expect matrix/heatmap structure","duration":1.5144149999999854,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Chart Types"],"fullName":"Party Dashboard Chart Types partyMomentumChart should expect doughnut/pie chart structure","status":"passed","title":"partyMomentumChart should expect doughnut/pie chart structure","duration":1.4936870000000226,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Data Loading Structure"],"fullName":"Party Dashboard Data Loading Structure dashboard should be ready for real CIA CSV data","status":"passed","title":"dashboard should be ready for real CIA CSV data","duration":1.995657000000051,"failureMessages":[],"location":{"line":262,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Empty State Handling"],"fullName":"Party Dashboard Empty State Handling should have structure to display empty state messages","status":"passed","title":"should have structure to display empty state messages","duration":1.8640199999999822,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should use dashboard-grid for responsive layout","status":"passed","title":"should use dashboard-grid for responsive layout","duration":2.227440999999999,"failureMessages":[],"location":{"line":305,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should have chart cards for consistent styling","status":"passed","title":"should have chart cards for consistent styling","duration":1.842520000000036,"failureMessages":[],"location":{"line":311,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Responsive Design"],"fullName":"Party Dashboard Responsive Design should have grid layout structure","status":"passed","title":"should have grid layout structure","duration":1.703640000000064,"failureMessages":[],"location":{"line":320,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Multi-Language Support"],"fullName":"Party Dashboard Multi-Language Support should have structure ready for i18n translations","status":"passed","title":"should have structure ready for i18n translations","duration":1.910517000000027,"failureMessages":[],"location":{"line":334,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Multi-Language Support"],"fullName":"Party Dashboard Multi-Language Support should support Swedish party name translations","status":"passed","title":"should support Swedish party name translations","duration":6.142090000000053,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should convert 0-1 alignment_rate to percentage for display using real helper","status":"passed","title":"should convert 0-1 alignment_rate to percentage for display using real helper","duration":2.1821260000000393,"failureMessages":[],"location":{"line":367,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should NOT show alignment as 1% when rate is 0.84","status":"passed","title":"should NOT show alignment as 1% when rate is 0.84","duration":1.2058079999999336,"failureMessages":[],"location":{"line":375,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should handle various alignment rates correctly via real helper","status":"passed","title":"should handle various alignment rates correctly via real helper","duration":1.3018879999999626,"failureMessages":[],"location":{"line":385,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Party Dashboard","Coalition Alignment Rate Processing"],"fullName":"Party Dashboard Coalition Alignment Rate Processing should handle momentum filter with zero values","status":"passed","title":"should handle momentum filter with zero values","duration":1.408015999999975,"failureMessages":[],"location":{"line":399,"column":5},"meta":{},"tags":[]}],"startTime":1787953686510,"endTime":1787953686600.408,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/party-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["political-context enrichment"],"fullName":"political-context enrichment expands first party abbreviation and wraps glossary first occurrence in abbr tooltip","status":"passed","title":"expands first party abbreviation and wraps glossary first occurrence in abbr tooltip","duration":20.532925999999975,"failureMessages":[],"location":{"line":7,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-context enrichment"],"fullName":"political-context enrichment uses language-aware context depth","status":"passed","title":"uses language-aware context depth","duration":5.635753000000022,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml political context block"],"fullName":"renderArticleHtml political context block renders collapsible political context on non-Swedish pages with comparative anchors","status":"passed","title":"renders collapsible political context on non-Swedish pages with comparative anchors","duration":68.87869,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml political context block"],"fullName":"renderArticleHtml political context block renders political context with reduced depth for Swedish pages","status":"passed","title":"renders political context with reduced depth for Swedish pages","duration":16.129550999999992,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953915532,"endTime":1787953915643.1296,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/political-context.test.ts"},{"assertionResults":[{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":4.22788700000001,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the en entry has non-empty title, subtitle, and section labels","status":"passed","title":"the en entry has non-empty title, subtitle, and section labels","duration":0.8054879999999685,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the sv entry has non-empty title, subtitle, and section labels","status":"passed","title":"the sv entry has non-empty title, subtitle, and section labels","duration":0.7252480000000219,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the da entry has non-empty title, subtitle, and section labels","status":"passed","title":"the da entry has non-empty title, subtitle, and section labels","duration":0.4427689999999984,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the no entry has non-empty title, subtitle, and section labels","status":"passed","title":"the no entry has non-empty title, subtitle, and section labels","duration":0.5762990000000059,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the fi entry has non-empty title, subtitle, and section labels","status":"passed","title":"the fi entry has non-empty title, subtitle, and section labels","duration":0.4696800000000394,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the de entry has non-empty title, subtitle, and section labels","status":"passed","title":"the de entry has non-empty title, subtitle, and section labels","duration":0.6559379999999919,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the fr entry has non-empty title, subtitle, and section labels","status":"passed","title":"the fr entry has non-empty title, subtitle, and section labels","duration":0.40660099999996646,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the es entry has non-empty title, subtitle, and section labels","status":"passed","title":"the es entry has non-empty title, subtitle, and section labels","duration":0.579734999999971,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the nl entry has non-empty title, subtitle, and section labels","status":"passed","title":"the nl entry has non-empty title, subtitle, and section labels","duration":0.41588899999999285,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ar entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ar entry has non-empty title, subtitle, and section labels","duration":0.5673419999999965,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the he entry has non-empty title, subtitle, and section labels","status":"passed","title":"the he entry has non-empty title, subtitle, and section labels","duration":0.3882669999999848,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ja entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ja entry has non-empty title, subtitle, and section labels","duration":0.44297000000000253,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the ko entry has non-empty title, subtitle, and section labels","status":"passed","title":"the ko entry has non-empty title, subtitle, and section labels","duration":0.49928399999998874,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS the zh entry has non-empty title, subtitle, and section labels","status":"passed","title":"the zh entry has non-empty title, subtitle, and section labels","duration":0.46406899999999496,"failureMessages":[],"location":{"line":50,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS"],"fullName":"political-intelligence/i18n/page-translations.ts — PI_TRANSLATIONS exposes the stat-label / a11y strings the dashboard needs","status":"passed","title":"exposes the stat-label / a11y strings the dashboard needs","duration":2.4255319999999756,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META exports a non-empty methodology catalogue","status":"passed","title":"exports a non-empty methodology catalogue","duration":0.5215469999999982,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META every methodology entry carries an icon and English description","status":"passed","title":"every methodology entry carries an icon and English description","duration":1.8342839999999683,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META"],"fullName":"political-intelligence/i18n/methodology-i18n.ts — METHODOLOGY_META English descriptions cover at least one of the catalogued methodology files","status":"passed","title":"English descriptions cover at least one of the catalogued methodology files","duration":0.4583989999999858,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/template-i18n.ts — TEMPLATE_META"],"fullName":"political-intelligence/i18n/template-i18n.ts — TEMPLATE_META exports a non-empty template catalogue","status":"passed","title":"exports a non-empty template catalogue","duration":0.4241840000000252,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/template-i18n.ts — TEMPLATE_META"],"fullName":"political-intelligence/i18n/template-i18n.ts — TEMPLATE_META every template entry carries an icon and description","status":"passed","title":"every template entry carries an icon and description","duration":3.6825450000000046,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers exports a non-empty stream catalogue","status":"passed","title":"exports a non-empty stream catalogue","duration":0.44454200000001265,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers every stream entry carries an icon and description","status":"passed","title":"every stream entry carries an icon and description","duration":0.8996549999999957,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamIcon returns the catalogued icon for known streams","status":"passed","title":"streamIcon returns the catalogued icon for known streams","duration":0.44841900000000123,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamIcon returns a non-empty fallback for unknown stream names","status":"passed","title":"streamIcon returns a non-empty fallback for unknown stream names","duration":0.535773000000006,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamDisplayName returns a non-empty string for unknown stream names","status":"passed","title":"streamDisplayName returns a non-empty string for unknown stream names","duration":0.7072039999999902,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers streamDescription returns a non-empty string in every language for catalogued streams","status":"passed","title":"streamDescription returns a non-empty string in every language for catalogued streams","duration":3.396179000000018,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers"],"fullName":"political-intelligence/i18n/stream-i18n.ts — STREAM_META + helpers prettifyStream uppercases each word and replaces dashes with spaces","status":"passed","title":"prettifyStream uppercases each word and replaces dashes with spaces","duration":0.5601790000000619,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers prettifyMarkdownTitle strips .md / .json and Title-Cases the slug","status":"passed","title":"prettifyMarkdownTitle strips .md / .json and Title-Cases the slug","duration":0.6773179999999002,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers artifactTitle returns a non-empty localised string for every catalogued slug × language","status":"passed","title":"artifactTitle returns a non-empty localised string for every catalogued slug × language","duration":2.2042069999999967,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/i18n/artifact-i18n.ts — title helpers"],"fullName":"political-intelligence/i18n/artifact-i18n.ts — title helpers artifactTitle prettifies unknown slugs by capitalising and replacing dashes","status":"passed","title":"artifactTitle prettifies unknown slugs by capitalising and replacing dashes","duration":0.6249399999999241,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactBaseName strips a directory prefix and returns the bare filename","status":"passed","title":"artifactBaseName strips a directory prefix and returns the bare filename","duration":0.642814000000044,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactBaseName preserves the extension and date prefix in the filename","status":"passed","title":"artifactBaseName preserves the extension and date prefix in the filename","duration":0.5248420000000351,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon returns a non-empty emoji for every common file type","status":"passed","title":"artifactIcon returns a non-empty emoji for every common file type","duration":0.8621739999999818,"failureMessages":[],"location":{"line":213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon uses the curated TEMPLATE_META icon when the slug is catalogued","status":"passed","title":"artifactIcon uses the curated TEMPLATE_META icon when the slug is catalogued","duration":0.605953999999997,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactIcon resolves alias siblings via FILENAME_ALIASES (stakeholder-impact → stakeholder-perspectives icon)","status":"passed","title":"artifactIcon resolves alias siblings via FILENAME_ALIASES (stakeholder-impact → stakeholder-perspectives icon)","duration":0.7842990000000327,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon"],"fullName":"political-intelligence/render/daily-day.ts — artifactBaseName / artifactIcon artifactTitle resolves alias siblings via FILENAME_ALIASES (political-classification → classification-results title)","status":"passed","title":"artifactTitle resolves alias siblings via FILENAME_ALIASES (political-classification → classification-results title)","duration":0.5687440000000379,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive returns 0 for an empty directory","status":"passed","title":"returns 0 for an empty directory","duration":1.1085359999999582,"failureMessages":[],"location":{"line":263,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive counts .md and .json files and ignores other extensions","status":"passed","title":"counts .md and .json files and ignores other extensions","duration":1.0402779999999439,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — countArtifactsRecursive"],"fullName":"political-intelligence/daily-streams.ts — countArtifactsRecursive recursively counts artifacts in subdirectories","status":"passed","title":"recursively counts artifacts in subdirectories","duration":1.026301999999987,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts returns empty array when stream directory does not exist","status":"passed","title":"returns empty array when stream directory does not exist","duration":1.404019000000062,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts collects .md and .json files sorted by relative path","status":"passed","title":"collects .md and .json files sorted by relative path","duration":9.07146499999999,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts collects artifacts from nested subdirectories","status":"passed","title":"collects artifacts from nested subdirectories","duration":1.137880999999993,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectStreamArtifacts"],"fullName":"political-intelligence/daily-streams.ts — collectStreamArtifacts ignores files with unsupported extensions","status":"passed","title":"ignores files with unsupported extensions","duration":0.9814770000000408,"failureMessages":[],"location":{"line":333,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["political-intelligence/daily-streams.ts — collectDailyDays"],"fullName":"political-intelligence/daily-streams.ts — collectDailyDays returns empty array when analysis/daily directory does not exist","status":"passed","title":"returns empty array when analysis/daily directory does not exist","duration":1.0614470000000438,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]}],"startTime":1787953788985,"endTime":1787953789038.0615,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/political-intelligence-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch extracts a polling wave from provider HTML and computes aggregate means","status":"passed","title":"extracts a polling wave from provider HTML and computes aggregate means","duration":5.407564999999977,"failureMessages":[],"location":{"line":18,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch persists schema-valid polling context output","status":"passed","title":"persists schema-valid polling context output","duration":70.26870199999996,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch validates the committed _fixture placeholder against the schema","status":"passed","title":"validates the committed _fixture placeholder against the schema","duration":28.765860999999973,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["polling-fetch"],"fullName":"polling-fetch prefers discovered follow-up article before extracting from archive roots","status":"passed","title":"prefers discovered follow-up article before extracting from archive roots","duration":2.4534830000000056,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]}],"startTime":1787953902497,"endTime":1787953902604.4534,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/polling-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for October (start of new session)","status":"passed","title":"should return current session for October (start of new session)","duration":3.797079999999994,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for November","status":"passed","title":"should return current session for November","duration":0.6914239999999836,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return current session for December","status":"passed","title":"should return current session for December","duration":0.4888559999999984,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for January","status":"passed","title":"should return previous session for January","duration":0.4944449999999847,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for March","status":"passed","title":"should return previous session for March","duration":0.5882510000000138,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["riksMoteFromDate"],"fullName":"riksMoteFromDate should return previous session for September (end of session)","status":"passed","title":"should return previous session for September (end of session)","duration":0.553937000000019,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistDownloadedData for full population"],"fullName":"populate-analysis-data integration persistDownloadedData for full population should persist all document types with correct directory structure","status":"passed","title":"should persist all document types with correct directory structure","duration":3.9895799999999895,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistDownloadedData for full population"],"fullName":"populate-analysis-data integration persistDownloadedData for full population should create date-stamped vote directory","status":"passed","title":"should create date-stamped vote directory","duration":1.443983000000003,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistEvents for calendar population"],"fullName":"populate-analysis-data integration persistEvents for calendar population should persist events to date-stamped directories","status":"passed","title":"should persist events to date-stamped directories","duration":1.5345729999999662,"failureMessages":[],"location":{"line":137,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistEvents for calendar population"],"fullName":"populate-analysis-data integration persistEvents for calendar population should handle events with \"from\" field instead of \"datum\"","status":"passed","title":"should handle events with \"from\" field instead of \"datum\"","duration":0.9003960000000006,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMPs for MP population"],"fullName":"populate-analysis-data integration persistMPs for MP population should persist MP profiles using intressent_id","status":"passed","title":"should persist MP profiles using intressent_id","duration":1.3158140000000458,"failureMessages":[],"location":{"line":165,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMPs for MP population"],"fullName":"populate-analysis-data integration persistMPs for MP population should handle large batch of MPs","status":"passed","title":"should handle large batch of MPs","duration":5.530866000000003,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","end-to-end population flow"],"fullName":"populate-analysis-data integration end-to-end population flow should persist all data types to the same root","status":"passed","title":"should persist all data types to the same root","duration":1.4347569999999905,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMCPResponse for government documents"],"fullName":"populate-analysis-data integration persistMCPResponse for government documents should persist government document to mcp-responses/riksdag-regering/search_regering/","status":"passed","title":"should persist government document to mcp-responses/riksdag-regering/search_regering/","duration":1.3687730000000329,"failureMessages":[],"location":{"line":235,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistMCPResponse for government documents"],"fullName":"populate-analysis-data integration persistMCPResponse for government documents should persist voting groups to mcp-responses/riksdag-regering/get_voting_group/","status":"passed","title":"should persist voting groups to mcp-responses/riksdag-regering/get_voting_group/","duration":1.1467869999999607,"failureMessages":[],"location":{"line":256,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistWorldBankData for economic indicators"],"fullName":"populate-analysis-data integration persistWorldBankData for economic indicators should persist World Bank data under worldbank/{indicator}/","status":"passed","title":"should persist World Bank data under worldbank/{indicator}/","duration":2.0197520000000395,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistWorldBankData for economic indicators"],"fullName":"populate-analysis-data integration persistWorldBankData for economic indicators should handle multiple indicators for Sweden","status":"passed","title":"should handle multiple indicators for Sweden","duration":1.240222000000017,"failureMessages":[],"location":{"line":307,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistSCBData for Swedish statistics"],"fullName":"populate-analysis-data integration persistSCBData for Swedish statistics should persist SCB table data under scb/","status":"passed","title":"should persist SCB table data under scb/","duration":1.2035440000000222,"failureMessages":[],"location":{"line":323,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","persistSCBData for Swedish statistics"],"fullName":"populate-analysis-data integration persistSCBData for Swedish statistics should persist without query parameter","status":"passed","title":"should persist without query parameter","duration":0.8656710000000203,"failureMessages":[],"location":{"line":352,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["populate-analysis-data integration","full end-to-end with all data types"],"fullName":"populate-analysis-data integration full end-to-end with all data types should populate all data type directories from a single root","status":"passed","title":"should populate all data type directories from a single root","duration":1.9969690000000355,"failureMessages":[],"location":{"line":363,"column":5},"meta":{},"tags":[]}],"startTime":1787953785775,"endTime":1787953785807.997,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/populate-analysis-data.test.ts"},{"assertionResults":[{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath parses canonical analysis/daily/<date>/<sub>/executive-brief_<lang>.md","status":"passed","title":"parses canonical analysis/daily/<date>/<sub>/executive-brief_<lang>.md","duration":4.505525000000034,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath handles nested subfolders","status":"passed","title":"handles nested subfolders","duration":0.6513790000000199,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for the English source file (no _lang suffix)","status":"passed","title":"returns null for the English source file (no _lang suffix)","duration":0.5455910000000017,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for unrelated paths","status":"passed","title":"returns null for unrelated paths","duration":0.45824800000002597,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBriefPath"],"fullName":"parseBriefPath returns null for an unknown language code","status":"passed","title":"returns null for an unknown language code","duration":0.4789469999999483,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips a translated Executive-Brief prefix from the H1","status":"passed","title":"strips a translated Executive-Brief prefix from the H1","duration":5.103895000000023,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips trailing date suffix from the H1","status":"passed","title":"strips trailing date suffix from the H1","duration":1.5844660000000204,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown does not rewrite an already-clean H1","status":"passed","title":"does not rewrite an already-clean H1","duration":2.215857999999969,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown preserves YAML frontmatter and locates the body H1","status":"passed","title":"preserves YAML frontmatter and locates the body H1","duration":1.063791999999978,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown preserves the H1 when the cleaned form would be too short","status":"passed","title":"preserves the H1 when the cleaned form would be too short","duration":0.7038679999999999,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown does nothing when there is no body H1","status":"passed","title":"does nothing when there is no body H1","duration":0.9917059999999651,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips translated boilerplate for DE briefs","status":"passed","title":"strips translated boilerplate for DE briefs","duration":0.8458740000000375,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (ar)","status":"passed","title":"skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (ar)","duration":1.003308000000004,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (he)","status":"passed","title":"skips leading <div dir=\"rtl\"> wrapper and rewrites the inner H1 (he)","duration":0.7460770000000139,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown rewrites an inline HTML <h1> as the title form","status":"passed","title":"rewrites an inline HTML <h1> as the title form","duration":0.862715000000037,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown rewrites a multi-line HTML <h1> block","status":"passed","title":"rewrites a multi-line HTML <h1> block","duration":0.7344550000000254,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips a leading hero image before the H1","status":"passed","title":"skips a leading hero image before the H1","duration":0.7798890000000256,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown skips leading <center> wrapper and rewrites the inner H1","status":"passed","title":"skips leading <center> wrapper and rewrites the inner H1","duration":0.685794000000044,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown strips nested HTML tags from the heading text","status":"passed","title":"strips nested HTML tags from the heading text","duration":0.6938789999999813,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefMarkdown"],"fullName":"postprocessBriefMarkdown returns no H1 when leading content is plain prose (no wrapper or heading)","status":"passed","title":"returns no H1 when leading content is plain prose (no wrapper or heading)","duration":0.5301130000000285,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) rewrites a brief on disk when the H1 changes","status":"passed","title":"rewrites a brief on disk when the H1 changes","duration":1.4268410000000245,"failureMessages":[],"location":{"line":269,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) reports \"unchanged\" when the H1 is already clean","status":"passed","title":"reports \"unchanged\" when the H1 is already clean","duration":0.9515010000000075,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) returns \"skipped\" for a non-canonical path","status":"passed","title":"returns \"skipped\" for a non-canonical path","duration":0.7260600000000181,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["postprocessBriefFile (integration)"],"fullName":"postprocessBriefFile (integration) returns \"error\" for a missing file","status":"passed","title":"returns \"error\" for a missing file","duration":0.5741350000000125,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]}],"startTime":1787953823827,"endTime":1787953823856.5742,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/postprocess-translated-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement download limit in 03-data-download.md keeps total under 100 files","status":"passed","title":"download limit in 03-data-download.md keeps total under 100 files","duration":4.334827000000018,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement 07-commit-and-pr.md contains mandatory 100-file guard","status":"passed","title":"07-commit-and-pr.md contains mandatory 100-file guard","duration":0.9375360000000228,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement all 14 news workflows have max-patch-files in safe-outputs block and ≤ 100","status":"passed","title":"all 14 news workflows have max-patch-files in safe-outputs block and ≤ 100","duration":2.527512999999999,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["PR file-budget enforcement"],"fullName":"PR file-budget enforcement existing analysis folders stay under file budget","status":"passed","title":"existing analysis folders stay under file budget","duration":14.095331999999985,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]}],"startTime":1787953855412,"endTime":1787953855434.0952,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pr-file-budget.test.ts"},{"assertionResults":[{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md derives <title> from brief H1 even when article.md frontmatter carries a different title","status":"passed","title":"derives <title> from brief H1 even when article.md frontmatter carries a different title","duration":105.15473099999997,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md works on body-only article.md (post-refactor shape) — no title/description in frontmatter","status":"passed","title":"works on body-only article.md (post-refactor shape) — no title/description in frontmatter","duration":7.09680800000001,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderArticleHtml — SEO derived from executive-brief.md"],"fullName":"renderArticleHtml — SEO derived from executive-brief.md gracefully falls back to article.md frontmatter when no brief markdown is supplied (legacy regenerator path)","status":"passed","title":"gracefully falls back to article.md frontmatter when no brief markdown is supplied (legacy regenerator path)","duration":4.722892999999999,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]}],"startTime":1787953889365,"endTime":1787953889481.723,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-from-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from aggregator.ts","status":"passed","title":"barrel re-exports every public symbol from aggregator.ts","duration":4.0839750000000095,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from markdown.ts","status":"passed","title":"barrel re-exports every public symbol from markdown.ts","duration":0.7063630000000103,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from chrome.ts","status":"passed","title":"barrel re-exports every public symbol from chrome.ts","duration":0.5931910000000471,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from article.ts","status":"passed","title":"barrel re-exports every public symbol from article.ts","duration":0.46386900000004516,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from url-helpers.ts","status":"passed","title":"barrel re-exports every public symbol from url-helpers.ts","duration":0.5223379999999906,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib architecture — barrel ↔ leaf parity"],"fullName":"render-lib architecture — barrel ↔ leaf parity barrel re-exports every public symbol from constants.ts","status":"passed","title":"barrel re-exports every public symbol from constants.ts","duration":0.539621000000011,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubBlobUrl strips any number of leading slashes","status":"passed","title":"buildGithubBlobUrl strips any number of leading slashes","duration":0.558685999999966,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubTreeUrl preserves embedded slashes and strips leading slashes","status":"passed","title":"buildGithubTreeUrl preserves embedded slashes and strips leading slashes","duration":0.41106999999999516,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["url-helpers.ts (leaf)"],"fullName":"url-helpers.ts (leaf) buildGithubBlobUrl handles the empty segment case gracefully","status":"passed","title":"buildGithubBlobUrl handles the empty segment case gracefully","duration":1.334969000000001,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) exposes the full __test__ escape hatch with all expected helpers","status":"passed","title":"exposes the full __test__ escape hatch with all expected helpers","duration":0.6323229999999285,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) AGGREGATION_ORDER reflects the journalist-optimal narrative arc","status":"passed","title":"AGGREGATION_ORDER reflects the journalist-optimal narrative arc","duration":0.697035000000028,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) titleForArtifact never returns an empty string for any known artifact","status":"passed","title":"titleForArtifact never returns an empty string for any known artifact","duration":1.6737840000000688,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator.ts (leaf, isolated from markdown/chrome)"],"fullName":"aggregator.ts (leaf, isolated from markdown/chrome) aggregateAnalysis produces a proper AggregationResult shape","status":"passed","title":"aggregateAnalysis produces a proper AggregationResult shape","duration":24.42297499999995,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) sanitizeSchema allowlists mermaid className on <pre>","status":"passed","title":"sanitizeSchema allowlists mermaid className on <pre>","duration":0.6412399999999252,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) sanitizeSchema allowlists id on h1..h6 (rehype-slug output)","status":"passed","title":"sanitizeSchema allowlists id on h1..h6 (rehype-slug output)","duration":0.9103450000000066,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml is async and returns HTML for a trivial paragraph","status":"passed","title":"renderMarkdownToHtml is async and returns HTML for a trivial paragraph","duration":19.32242599999995,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml strips <style> tags (not in allowlist)","status":"passed","title":"renderMarkdownToHtml strips <style> tags (not in allowlist)","duration":4.9496259999999666,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown.ts (leaf, standalone pipeline)"],"fullName":"markdown.ts (leaf, standalone pipeline) renderMarkdownToHtml escapes raw text inside mermaid fences","status":"passed","title":"renderMarkdownToHtml escapes raw text inside mermaid fences","duration":9.106299000000035,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) renderChromeHead is a synchronous string builder","status":"passed","title":"renderChromeHead is a synchronous string builder","duration":1.5015809999999874,"failureMessages":[],"location":{"line":284,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome returns head/headerHtml/footerHtml as non-empty strings","status":"passed","title":"buildChrome returns head/headerHtml/footerHtml as non-empty strings","duration":2.21396500000003,"failureMessages":[],"location":{"line":292,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome is deterministic for identical inputs within the same second","status":"passed","title":"buildChrome is deterministic for identical inputs within the same second","duration":1.2562920000000304,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["chrome.ts (leaf, pure builder)"],"fullName":"chrome.ts (leaf, pure builder) buildChrome preserves all 14 LANGUAGES reference in the switcher (13 in dropdown + current)","status":"passed","title":"buildChrome preserves all 14 LANGUAGES reference in the switcher (13 in dropdown + current)","duration":1.5811610000000655,"failureMessages":[],"location":{"line":311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml composes head + header + body + sources + footer","status":"passed","title":"renderArticleHtml composes head + header + body + sources + footer","duration":29.258736999999996,"failureMessages":[],"location":{"line":344,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml omits the sources block when artifactsUsed is empty","status":"passed","title":"renderArticleHtml omits the sources block when artifactsUsed is empty","duration":5.359874999999988,"failureMessages":[],"location":{"line":364,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml emits Schema.org NewsArticle JSON-LD with correct language","status":"passed","title":"renderArticleHtml emits Schema.org NewsArticle JSON-LD with correct language","duration":4.082432999999924,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml uses the dedicated News banner image and news-article body class","status":"passed","title":"renderArticleHtml uses the dedicated News banner image and news-article body class","duration":3.1046029999999973,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article.ts (orchestrator)"],"fullName":"article.ts (orchestrator) renderArticleHtml emits reader guide BETWEEN executive brief and the rest of the body","status":"passed","title":"renderArticleHtml emits reader guide BETWEEN executive brief and the rest of the body","duration":44.82121299999994,"failureMessages":[],"location":{"line":391,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 splits at the second <h2 boundary","status":"passed","title":"splits at the second <h2 boundary","duration":0.8815000000000737,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 returns the entire body as lead when only one <h2 exists","status":"passed","title":"returns the entire body as lead when only one <h2 exists","duration":0.6145910000000185,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["splitBodyAtSecondH2"],"fullName":"splitBodyAtSecondH2 returns the entire body as lead when no <h2 exists","status":"passed","title":"returns the entire body as lead when no <h2 exists","duration":0.5693870000000061,"failureMessages":[],"location":{"line":442,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib boundary (no CLI side-effect imports)"],"fullName":"render-lib boundary (no CLI side-effect imports) no file under scripts/render-lib/ imports from scripts/generate-sitemap-html","status":"passed","title":"no file under scripts/render-lib/ imports from scripts/generate-sitemap-html","duration":14.647834000000103,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for a Date instance","status":"passed","title":"returns YYYY-MM-DD for a Date instance","duration":0.6035610000000133,"failureMessages":[],"location":{"line":491,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for an ISO-8601 string","status":"passed","title":"returns YYYY-MM-DD for an ISO-8601 string","duration":0.5206150000000207,"failureMessages":[],"location":{"line":495,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate returns YYYY-MM-DD for a bare YYYY-MM-DD string","status":"passed","title":"returns YYYY-MM-DD for a bare YYYY-MM-DD string","duration":0.4623659999999745,"failureMessages":[],"location":{"line":499,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when the value is undefined / null / wrong shape","status":"passed","title":"falls back to \"now\" when the value is undefined / null / wrong shape","duration":0.6282160000000658,"failureMessages":[],"location":{"line":503,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when the string does not start with YYYY-MM-DD","status":"passed","title":"falls back to \"now\" when the string does not start with YYYY-MM-DD","duration":0.44107599999995273,"failureMessages":[],"location":{"line":510,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate falls back to \"now\" when given an Invalid Date instance","status":"passed","title":"falls back to \"now\" when given an Invalid Date instance","duration":0.4513050000000476,"failureMessages":[],"location":{"line":515,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseFrontMatterDate"],"fullName":"parseFrontMatterDate uses the live clock when no `now` is supplied","status":"passed","title":"uses the live clock when no `now` is supplied","duration":2.412465999999995,"failureMessages":[],"location":{"line":519,"column":3},"meta":{},"tags":[]}],"startTime":1787953678955,"endTime":1787953679143.4124,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-architecture.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib/article-types helper","loadArticleTypesRegistry"],"fullName":"render-lib/article-types helper loadArticleTypesRegistry loads and returns a registry with types array","status":"passed","title":"loads and returns a registry with types array","duration":4.4312269999999785,"failureMessages":[],"location":{"line":26,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","loadArticleTypesRegistry"],"fullName":"render-lib/article-types helper loadArticleTypesRegistry caches on second call","status":"passed","title":"caches on second call","duration":0.6868160000000216,"failureMessages":[],"location":{"line":33,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns entry for known id","status":"passed","title":"returns entry for known id","duration":0.7115119999999706,"failureMessages":[],"location":{"line":41,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns undefined for unknown id","status":"passed","title":"returns undefined for unknown id","duration":0.49588799999997946,"failureMessages":[],"location":{"line":48,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getById"],"fullName":"render-lib/article-types helper getById returns correct label for week-ahead","status":"passed","title":"returns correct label for week-ahead","duration":0.5751670000000217,"failureMessages":[],"location":{"line":52,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getBySubfolder"],"fullName":"render-lib/article-types helper getBySubfolder returns entry for known subfolder","status":"passed","title":"returns entry for known subfolder","duration":0.7171030000000087,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","getBySubfolder"],"fullName":"render-lib/article-types helper getBySubfolder returns undefined for unknown subfolder","status":"passed","title":"returns undefined for unknown subfolder","duration":0.4960879999999861,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only single-type entries for single-type family","status":"passed","title":"returns only single-type entries for single-type family","duration":0.6822769999999991,"failureMessages":[],"location":{"line":72,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only long-horizon entries for long-horizon-forecast family","status":"passed","title":"returns only long-horizon entries for long-horizon-forecast family","duration":0.8020419999999717,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","listByFamily"],"fullName":"render-lib/article-types helper listByFamily returns only tier-c entries for tier-c-aggregation family","status":"passed","title":"returns only tier-c entries for tier-c-aggregation family","duration":0.8007789999999773,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","allTypesSortedByHorizon"],"fullName":"render-lib/article-types helper allTypesSortedByHorizon returns all types sorted by horizonDays ascending","status":"passed","title":"returns all types sorted by horizonDays ascending","duration":1.161925999999994,"failureMessages":[],"location":{"line":98,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","forwardLookTypes"],"fullName":"render-lib/article-types helper forwardLookTypes returns long-horizon types sorted by horizonDays ascending","status":"passed","title":"returns long-horizon types sorted by horizonDays ascending","duration":1.6269660000000385,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","forwardLookTypes"],"fullName":"render-lib/article-types helper forwardLookTypes all entries have family long-horizon-forecast","status":"passed","title":"all entries have family long-horizon-forecast","duration":0.6902919999999995,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","round-trip: type → getById → fields"],"fullName":"render-lib/article-types helper round-trip: type → getById → fields every registry type is accessible via getById","status":"passed","title":"every registry type is accessible via getById","duration":1.4026969999999892,"failureMessages":[],"location":{"line":130,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","round-trip: type → getById → fields"],"fullName":"render-lib/article-types helper round-trip: type → getById → fields every registry type is accessible via getBySubfolder","status":"passed","title":"every registry type is accessible via getBySubfolder","duration":1.1094269999999824,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","registry-driven band counts (horizonBands)"],"fullName":"render-lib/article-types helper registry-driven band counts (horizonBands) registry contains expected horizon bands","status":"passed","title":"registry contains expected horizon bands","duration":1.2313860000000432,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","registry-driven band counts (horizonBands)"],"fullName":"render-lib/article-types helper registry-driven band counts (horizonBands) band days are strictly increasing","status":"passed","title":"band days are strictly increasing","duration":0.7456659999999715,"failureMessages":[],"location":{"line":164,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","SEO labels match registry"],"fullName":"render-lib/article-types helper SEO labels match registry every type has a non-empty label","status":"passed","title":"every type has a non-empty label","duration":0.8723630000000071,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","SEO labels match registry"],"fullName":"render-lib/article-types helper SEO labels match registry every type has a non-empty icon","status":"passed","title":"every type has a non-empty icon","duration":0.9126090000000318,"failureMessages":[],"location":{"line":183,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib/article-types helper","hypothetical new type integration"],"fullName":"render-lib/article-types helper hypothetical new type integration adding a type to registry would make it discoverable (simulation)","status":"passed","title":"adding a type to registry would make it discoverable (simulation)","duration":0.6724290000000224,"failureMessages":[],"location":{"line":192,"column":5},"meta":{},"tags":[]}],"startTime":1787953853958,"endTime":1787953853979.6724,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order AGGREGATION_ORDER opens with the executive brief","status":"passed","title":"AGGREGATION_ORDER opens with the executive brief","duration":3.821553999999992,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order AGGREGATION_ORDER closes with the audit-appendix manifest","status":"passed","title":"AGGREGATION_ORDER closes with the audit-appendix manifest","duration":0.5223480000000791,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order titleForArtifact maps known files to curated titles","status":"passed","title":"titleForArtifact maps known files to curated titles","duration":0.5246220000000221,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order titleForArtifact falls back to prettifyFallbackTitle for unknown files","status":"passed","title":"titleForArtifact falls back to prettifyFallbackTitle for unknown files","duration":0.5921789999999874,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/order — canonical narrative order"],"fullName":"aggregator/order — canonical narrative order prettifyFallbackTitle is idempotent on already-prettified input","status":"passed","title":"prettifyFallbackTitle is idempotent on already-prettified input","duration":0.48209299999996347,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper exports a non-empty admin-field whitelist","status":"passed","title":"exports a non-empty admin-field whitelist","duration":1.3246599999999944,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches structured admin fragments only","status":"passed","title":"ADMIN_FIELD_RE matches structured admin fragments only","duration":6.236195000000066,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FRAGMENT_SPLITTER does not split on em-dash","status":"passed","title":"ADMIN_FRAGMENT_SPLITTER does not split on em-dash","duration":0.9629830000000084,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes pure-admin paragraphs anywhere","status":"passed","title":"stripLeadingAdminBylines removes pure-admin paragraphs anywhere","duration":0.8593079999999418,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches Round 7 leak fields (DIW Composite, WEP, Audience)","status":"passed","title":"ADMIN_FIELD_RE matches Round 7 leak fields (DIW Composite, WEP, Audience)","duration":0.5825210000000425,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes the realtime-pulse Audience admin block","status":"passed","title":"stripLeadingAdminBylines removes the realtime-pulse Audience admin block","duration":6.395502999999962,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines removes the propositions DIW Composite admin block","status":"passed","title":"stripLeadingAdminBylines removes the propositions DIW Composite admin block","duration":0.46390899999994417,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines accepts pipe-separated value continuations on admin lines","status":"passed","title":"stripLeadingAdminBylines accepts pipe-separated value continuations on admin lines","duration":0.49845299999992676,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper stripLeadingAdminBylines preserves prose containing pipes that are NOT admin","status":"passed","title":"stripLeadingAdminBylines preserves prose containing pipes that are NOT admin","duration":0.41889400000002297,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/admin-bylines — paragraph-level admin stripper"],"fullName":"aggregator/cleaning/admin-bylines — paragraph-level admin stripper ADMIN_FIELD_RE matches Round 8 leak fields (Horizon / Workflow / Election Proximity / IMF vintage)","status":"passed","title":"ADMIN_FIELD_RE matches Round 8 leak fields (Horizon / Workflow / Election Proximity / IMF vintage)","duration":0.6172960000000103,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/pass-two — Pass 2 self-audit stripper"],"fullName":"aggregator/cleaning/pass-two — Pass 2 self-audit stripper exports a regex matching `## Pass 2 …` and emoji variants","status":"passed","title":"exports a regex matching `## Pass 2 …` and emoji variants","duration":0.6786099999999351,"failureMessages":[],"location":{"line":250,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/pass-two — Pass 2 self-audit stripper"],"fullName":"aggregator/cleaning/pass-two — Pass 2 self-audit stripper strips Pass 2 section through end-of-file","status":"passed","title":"strips Pass 2 section through end-of-file","duration":0.5610400000000482,"failureMessages":[],"location":{"line":256,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper exports a non-empty process-metadata whitelist","status":"passed","title":"exports a non-empty process-metadata whitelist","duration":0.46896800000001804,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper strips individual `**Confidence**: …` lines but preserves prose","status":"passed","title":"strips individual `**Confidence**: …` lines but preserves prose","duration":2.6730549999999766,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/process-meta — line-level metadata stripper"],"fullName":"aggregator/cleaning/process-meta — line-level metadata stripper PROCESS_META_LINE_RE has the global flag (multi-line replacement)","status":"passed","title":"PROCESS_META_LINE_RE has the global flag (multi-line replacement)","duration":0.3686800000000403,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter cleanArtifactBody strips front-matter, first H1, admin bylines, Pass 2","status":"passed","title":"cleanArtifactBody strips front-matter, first H1, admin bylines, Pass 2","duration":5.35269100000005,"failureMessages":[],"location":{"line":288,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter demoteHeadings demotes inner H2 → H3, caps at H6","status":"passed","title":"demoteHeadings demotes inner H2 → H3, caps at H6","duration":0.44824900000003254,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter demoteHeadings does not affect headings inside fenced code","status":"passed","title":"demoteHeadings does not affect headings inside fenced code","duration":0.4206370000000561,"failureMessages":[],"location":{"line":318,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter stripSourcePreamble removes `_Source: file.md_` italic lines","status":"passed","title":"stripSourcePreamble removes `_Source: file.md_` italic lines","duration":0.41588899999999285,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter rewriteRelativeLinks rewrites .md links to absolute GitHub blob URLs","status":"passed","title":"rewriteRelativeLinks rewrites .md links to absolute GitHub blob URLs","duration":0.6380239999999731,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — body cleaner & link rewriter"],"fullName":"aggregator/cleaning/structural — body cleaner & link rewriter rewriteRelativeLinks leaves absolute URLs untouched","status":"passed","title":"rewriteRelativeLinks leaves absolute URLs untouched","duration":0.5075500000000375,"failureMessages":[],"location":{"line":342,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers SENTENCE_END_RE matches Latin / CJK / Devanagari terminators","status":"passed","title":"SENTENCE_END_RE matches Latin / CJK / Devanagari terminators","duration":0.659144000000083,"failureMessages":[],"location":{"line":349,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers markdownInlineToText strips emphasis + links to plain text","status":"passed","title":"markdownInlineToText strips emphasis + links to plain text","duration":0.5631449999999631,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary returns input unchanged when within window","status":"passed","title":"truncateToSentenceBoundary returns input unchanged when within window","duration":0.5539570000000822,"failureMessages":[],"location":{"line":365,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary cuts at sentence end inside window","status":"passed","title":"truncateToSentenceBoundary cuts at sentence end inside window","duration":0.6253009999999222,"failureMessages":[],"location":{"line":369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary handles single-token pathological input","status":"passed","title":"truncateToSentenceBoundary handles single-token pathological input","duration":1.223540000000071,"failureMessages":[],"location":{"line":377,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut mid-sentence at \"prop.\" abbreviation","status":"passed","title":"truncateToSentenceBoundary does not cut mid-sentence at \"prop.\" abbreviation","duration":0.5186609999999519,"failureMessages":[],"location":{"line":388,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut at \"art.\" / \"Mr.\" / \"etc.\" abbreviations","status":"passed","title":"truncateToSentenceBoundary does not cut at \"art.\" / \"Mr.\" / \"etc.\" abbreviations","duration":0.6082880000000159,"failureMessages":[],"location":{"line":397,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary still cuts at real sentence ends after abbreviations","status":"passed","title":"truncateToSentenceBoundary still cuts at real sentence ends after abbreviations","duration":0.4566449999999804,"failureMessages":[],"location":{"line":406,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot recognises simple abbreviations (prop., Mr., etc.)","status":"passed","title":"isAbbreviationDot recognises simple abbreviations (prop., Mr., etc.)","duration":0.6166649999998981,"failureMessages":[],"location":{"line":419,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot recognises multi-dot abbreviations e.g., i.e., bl.a., d.v.s.","status":"passed","title":"isAbbreviationDot recognises multi-dot abbreviations e.g., i.e., bl.a., d.v.s.","duration":0.6662579999999707,"failureMessages":[],"location":{"line":428,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers isAbbreviationDot does not false-positive on non-abbreviation prefix before known suffix","status":"passed","title":"isAbbreviationDot does not false-positive on non-abbreviation prefix before known suffix","duration":0.5190719999999374,"failureMessages":[],"location":{"line":443,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary handles multiple consecutive abbreviations","status":"passed","title":"truncateToSentenceBoundary handles multiple consecutive abbreviations","duration":0.5887129999999843,"failureMessages":[],"location":{"line":450,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers truncateToSentenceBoundary does not cut at e.g. / i.e. / bl.a.","status":"passed","title":"truncateToSentenceBoundary does not cut at e.g. / i.e. / bl.a.","duration":0.7452749999999924,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph returns null when no BLUF heading exists","status":"passed","title":"readBlufParagraph returns null when no BLUF heading exists","duration":1.7505270000000337,"failureMessages":[],"location":{"line":473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph returns the prose paragraph after `## 🎯 BLUF`","status":"passed","title":"readBlufParagraph returns the prose paragraph after `## 🎯 BLUF`","duration":5.424385000000029,"failureMessages":[],"location":{"line":477,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readFirstParagraph skips admin paragraphs","status":"passed","title":"readFirstParagraph skips admin paragraphs","duration":1.183887000000027,"failureMessages":[],"location":{"line":482,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers stripBlufLabel removes leading BLUF: / TL;DR: / Bottom Line: prefixes and list markers","status":"passed","title":"stripBlufLabel removes leading BLUF: / TL;DR: / Bottom Line: prefixes and list markers","duration":0.9952430000000732,"failureMessages":[],"location":{"line":496,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers stripBlufLabel preserves prose without a BLUF prefix","status":"passed","title":"stripBlufLabel preserves prose without a BLUF prefix","duration":0.6250900000000001,"failureMessages":[],"location":{"line":509,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph strips BLUF: inline-label from the returned paragraph","status":"passed","title":"readBlufParagraph strips BLUF: inline-label from the returned paragraph","duration":1.0476409999999987,"failureMessages":[],"location":{"line":513,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## 📌 Sammanfattning\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## 📌 Sammanfattning\"","duration":6.367841999999996,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## 🎯 Slutsats\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## 🎯 Slutsats\"","duration":1.2852659999999787,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## 🎯 Konklusion\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## 🎯 Konklusion\"","duration":6.226917999999955,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## 📌 Sammenfatning\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## 📌 Sammenfatning\"","duration":1.399099000000092,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 🎯 Konklusjon\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 🎯 Konklusjon\"","duration":5.40041999999994,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 📌 Sammendrag\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 📌 Sammendrag\"","duration":1.3083299999999554,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## 🎯 Yhteenveto\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## 🎯 Yhteenveto\"","duration":6.015090999999984,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## 📌 Tiivistelmä\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## 📌 Tiivistelmä\"","duration":1.3027789999999868,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## 🎯 Zusammenfassung\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## 🎯 Zusammenfassung\"","duration":7.731664000000023,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## 📌 Fazit\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## 📌 Fazit\"","duration":1.9979999999999336,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## 🎯 Conclusion\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## 🎯 Conclusion\"","duration":5.5808680000000095,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## 📌 Résumé\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## 📌 Résumé\"","duration":1.8070529999999962,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## 🎯 Conclusión\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## 🎯 Conclusión\"","duration":7.303132000000005,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## 📌 Resumen ejecutivo\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## 📌 Resumen ejecutivo\"","duration":1.9217179999999416,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## 🎯 Conclusie\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## 🎯 Conclusie\"","duration":8.396849999999972,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## 📌 Samenvatting\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## 📌 Samenvatting\"","duration":1.8661130000000412,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 🎯 الملخص التنفيذي\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 🎯 الملخص التنفيذي\"","duration":5.086211999999932,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 📌 الخلاصة التنفيذية\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 📌 الخلاصة التنفيذية\"","duration":1.3257129999999506,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## 🎯 תמצית מנהלים\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## 🎯 תמצית מנהלים\"","duration":4.041557000000012,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## 📌 תקציר מנהלים\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## 📌 תקציר מנהלים\"","duration":1.3278060000000096,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 🎯 要約\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 🎯 要約\"","duration":3.506083999999987,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 📌 要旨\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 📌 要旨\"","duration":1.4051210000000083,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 🎯 핵심 요약\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 🎯 핵심 요약\"","duration":2.8821159999999963,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 📌 요약\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 📌 요약\"","duration":1.3308210000000145,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 🎯 执行摘要\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 🎯 执行摘要\"","duration":2.850586999999905,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 📌 核心摘要\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 📌 核心摘要\"","duration":1.3056950000000143,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## Övergripande bedömning\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## Övergripande bedömning\"","duration":2.5941459999999097,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [sv] readBlufParagraph matches localised heading \"## Underrättelsesummering\"","status":"passed","title":"[sv] readBlufParagraph matches localised heading \"## Underrättelsesummering\"","duration":1.3551969999999756,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [no] readBlufParagraph matches localised heading \"## 60-sekunders lesing (8 punkter)\"","status":"passed","title":"[no] readBlufParagraph matches localised heading \"## 60-sekunders lesing (8 punkter)\"","duration":2.4461690000000544,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fi] readBlufParagraph matches localised heading \"## ⚡ Huippotason tiedustelu\"","status":"passed","title":"[fi] readBlufParagraph matches localised heading \"## ⚡ Huippotason tiedustelu\"","duration":1.1901889999999185,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [da] readBlufParagraph matches localised heading \"## Beslutninger der kræves straks\"","status":"passed","title":"[da] readBlufParagraph matches localised heading \"## Beslutninger der kræves straks\"","duration":2.800622999999973,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [de] readBlufParagraph matches localised heading \"## Sofort erforderliche Entscheidungen\"","status":"passed","title":"[de] readBlufParagraph matches localised heading \"## Sofort erforderliche Entscheidungen\"","duration":3.1956930000000057,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] readBlufParagraph matches localised heading \"## Décisions immédiates requises\"","status":"passed","title":"[fr] readBlufParagraph matches localised heading \"## Décisions immédiates requises\"","duration":2.9630670000000237,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] readBlufParagraph matches localised heading \"## Decisiones inmediatas requeridas\"","status":"passed","title":"[es] readBlufParagraph matches localised heading \"## Decisiones inmediatas requeridas\"","duration":2.871216000000004,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [nl] readBlufParagraph matches localised heading \"## Onmiddellijk vereiste beslissingen\"","status":"passed","title":"[nl] readBlufParagraph matches localised heading \"## Onmiddellijk vereiste beslissingen\"","duration":2.8311499999999796,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ar] readBlufParagraph matches localised heading \"## 🎯 ملخص\"","status":"passed","title":"[ar] readBlufParagraph matches localised heading \"## 🎯 ملخص\"","duration":1.4190770000000157,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [he] readBlufParagraph matches localised heading \"## כותרת ראשית\"","status":"passed","title":"[he] readBlufParagraph matches localised heading \"## כותרת ראשית\"","duration":1.3583129999999528,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## エグゼクティブサマリー\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## エグゼクティブサマリー\"","duration":1.6973470000000361,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ja] readBlufParagraph matches localised heading \"## 5点エグゼクティブサマリー\"","status":"passed","title":"[ja] readBlufParagraph matches localised heading \"## 5点エグゼクティブサマリー\"","duration":1.6984300000000303,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 종합 평가\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 종합 평가\"","duration":1.3842820000000984,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [ko] readBlufParagraph matches localised heading \"## 즉각적인 결정 사항\"","status":"passed","title":"[ko] readBlufParagraph matches localised heading \"## 즉각적인 결정 사항\"","duration":1.3992499999999382,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 即刻所需决策\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 即刻所需决策\"","duration":1.4184150000000955,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] readBlufParagraph matches localised heading \"## 60秒阅读\"","status":"passed","title":"[zh] readBlufParagraph matches localised heading \"## 60秒阅读\"","duration":1.4350469999999405,"failureMessages":[],"location":{"line":579,"column":14},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph(md, \"en\") still matches the literal `BLUF` token for translated briefs that preserve the English acronym","status":"passed","title":"readBlufParagraph(md, \"en\") still matches the literal `BLUF` token for translated briefs that preserve the English acronym","duration":1.8361670000000458,"failureMessages":[],"location":{"line":584,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph(md) without a lang preserves legacy English-only behaviour","status":"passed","title":"readBlufParagraph(md) without a lang preserves legacy English-only behaviour","duration":1.48146399999996,"failureMessages":[],"location":{"line":594,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers readBlufParagraph accepts a blockquote-formatted BLUF body","status":"passed","title":"readBlufParagraph accepts a blockquote-formatted BLUF body","duration":1.6627630000000408,"failureMessages":[],"location":{"line":605,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers buildBlufHeadingRegex matches a parenthesised \"(BLUF)\" suffix variant","status":"passed","title":"buildBlufHeadingRegex matches a parenthesised \"(BLUF)\" suffix variant","duration":7.359598000000005,"failureMessages":[],"location":{"line":616,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers buildBlufHeadingRegex matches a CJK-script prefix before the keyword","status":"passed","title":"buildBlufHeadingRegex matches a CJK-script prefix before the keyword","duration":1.3548570000000382,"failureMessages":[],"location":{"line":628,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers cleanArtifactBody strips a leading Unicode bidi mark from RTL headings","status":"passed","title":"cleanArtifactBody strips a leading Unicode bidi mark from RTL headings","duration":1.4914230000000543,"failureMessages":[],"location":{"line":640,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [fr] évaluation de situation synthétique is matched as BLUF (prevents fallthrough to Synthèse des risques)","status":"passed","title":"[fr] évaluation de situation synthétique is matched as BLUF (prevents fallthrough to Synthèse des risques)","duration":1.4729170000000522,"failureMessages":[],"location":{"line":663,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [es] síntesis de situación is matched as BLUF","status":"passed","title":"[es] síntesis de situación is matched as BLUF","duration":1.33147299999996,"failureMessages":[],"location":{"line":689,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/description — BLUF / first-paragraph readers"],"fullName":"aggregator/seo/description — BLUF / first-paragraph readers [zh] 态势简要评估 is matched as BLUF (prevents fallthrough to 风险摘要)","status":"passed","title":"[zh] 态势简要评估 is matched as BLUF (prevents fallthrough to 风险摘要)","duration":1.8426299999999856,"failureMessages":[],"location":{"line":709,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis readFirstHeading returns the H1 text without the leading `# `","status":"passed","title":"readFirstHeading returns the H1 text without the leading `# `","duration":2.43625099999997,"failureMessages":[],"location":{"line":737,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips `Executive Brief — ` prefix and trailing date","status":"passed","title":"cleanArticleTitle strips `Executive Brief — ` prefix and trailing date","duration":3.3730450000000474,"failureMessages":[],"location":{"line":742,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips Swedish brief prefix `Exekutiv sammanfattning —`","status":"passed","title":"cleanArticleTitle strips Swedish brief prefix `Exekutiv sammanfattning —`","duration":1.9314050000000407,"failureMessages":[],"location":{"line":761,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips German brief prefix `Zusammenfassung —`","status":"passed","title":"cleanArticleTitle strips German brief prefix `Zusammenfassung —`","duration":1.8206179999999677,"failureMessages":[],"location":{"line":771,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips French brief prefix `Résumé exécutif —`","status":"passed","title":"cleanArticleTitle strips French brief prefix `Résumé exécutif —`","duration":1.7945700000000215,"failureMessages":[],"location":{"line":781,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips Arabic brief prefix `ملخص تنفيذي —` (RTL)","status":"passed","title":"cleanArticleTitle strips Arabic brief prefix `ملخص تنفيذي —` (RTL)","duration":2.1750319999999874,"failureMessages":[],"location":{"line":791,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle without lang param falls back to EN strip only (legacy callers)","status":"passed","title":"cleanArticleTitle without lang param falls back to EN strip only (legacy callers)","duration":1.573515000000043,"failureMessages":[],"location":{"line":803,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle returns null when too short","status":"passed","title":"cleanArticleTitle returns null when too short","duration":2.0415719999999737,"failureMessages":[],"location":{"line":817,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf truncates at word boundary when first sentence too long","status":"passed","title":"titleFromBluf truncates at word boundary when first sentence too long","duration":2.9047580000000153,"failureMessages":[],"location":{"line":821,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf returns null on empty/null input","status":"passed","title":"titleFromBluf returns null on empty/null input","duration":1.4064329999999927,"failureMessages":[],"location":{"line":828,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle returns null when title equals prettified subfolder (boilerplate guard)","status":"passed","title":"cleanArticleTitle returns null when title equals prettified subfolder (boilerplate guard)","duration":2.9730959999999413,"failureMessages":[],"location":{"line":838,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle preserves a real story title even when subfolder is supplied","status":"passed","title":"cleanArticleTitle preserves a real story title even when subfolder is supplied","duration":1.4720350000000053,"failureMessages":[],"location":{"line":859,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading \"On <date>, \" prefix (no literal date in title)","status":"passed","title":"titleFromBluf strips a leading \"On <date>, \" prefix (no literal date in title)","duration":1.9483779999999342,"failureMessages":[],"location":{"line":868,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading weekday + date prefix when result remains grammatical","status":"passed","title":"titleFromBluf strips a leading weekday + date prefix when result remains grammatical","duration":1.6783120000000054,"failureMessages":[],"location":{"line":878,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS the date prefix when stripping would leave a verb-leading subjectless fragment","status":"passed","title":"titleFromBluf KEEPS the date prefix when stripping would leave a verb-leading subjectless fragment","duration":1.52991499999996,"failureMessages":[],"location":{"line":888,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading \"The week of <range>\" prefix","status":"passed","title":"titleFromBluf strips a leading \"The week of <range>\" prefix","duration":3.801205999999979,"failureMessages":[],"location":{"line":899,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not end on a trailing comma or coordinating connector","status":"passed","title":"titleFromBluf does not end on a trailing comma or coordinating connector","duration":1.8755210000000488,"failureMessages":[],"location":{"line":907,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf still returns null on empty input after date strip","status":"passed","title":"titleFromBluf still returns null on empty input after date strip","duration":1.6482150000000502,"failureMessages":[],"location":{"line":918,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading ordered-list marker (1. / 2) / -)","status":"passed","title":"titleFromBluf strips a leading ordered-list marker (1. / 2) / -)","duration":2.779182999999989,"failureMessages":[],"location":{"line":927,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle preserves a bare trailing uppercase `A` (live: `Tax Class A`, `Plan A`)","status":"passed","title":"cleanArticleTitle preserves a bare trailing uppercase `A` (live: `Tax Class A`, `Plan A`)","duration":1.6633640000000014,"failureMessages":[],"location":{"line":945,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips a bare trailing comma (live: `Sweden Evening Analysis,`)","status":"passed","title":"cleanArticleTitle strips a bare trailing comma (live: `Sweden Evening Analysis,`)","duration":1.6636040000000776,"failureMessages":[],"location":{"line":964,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis cleanArticleTitle strips a bare trailing semicolon or colon","status":"passed","title":"cleanArticleTitle strips a bare trailing semicolon or colon","duration":1.6976980000000594,"failureMessages":[],"location":{"line":973,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not truncate to end on a ≤ 3-char tail word (live: `… on the Tidö`)","status":"passed","title":"titleFromBluf does not truncate to end on a ≤ 3-char tail word (live: `… on the Tidö`)","duration":1.7855829999999742,"failureMessages":[],"location":{"line":982,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf does not truncate to end on `two`, `has` or other ≤ 3-char filler","status":"passed","title":"titleFromBluf does not truncate to end on `two`, `has` or other ≤ 3-char filler","duration":1.8239750000000186,"failureMessages":[],"location":{"line":995,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf preserves 4+ char tail words like `bill`, `cuts`, `vote`","status":"passed","title":"titleFromBluf preserves 4+ char tail words like `bill`, `cuts`, `vote`","duration":1.84078599999998,"failureMessages":[],"location":{"line":1004,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS a leading Swedish date prefix when stripping would leave a V2 verb-leading fragment","status":"passed","title":"titleFromBluf KEEPS a leading Swedish date prefix when stripping would leave a V2 verb-leading fragment","duration":1.7690020000000004,"failureMessages":[],"location":{"line":1014,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading Swedish date prefix when result is NOT verb-leading","status":"passed","title":"titleFromBluf strips a leading Swedish date prefix when result is NOT verb-leading","duration":1.7936580000000504,"failureMessages":[],"location":{"line":1028,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf KEEPS a leading German date prefix when stripping would leave a V2 verb-leading fragment","status":"passed","title":"titleFromBluf KEEPS a leading German date prefix when stripping would leave a V2 verb-leading fragment","duration":1.8267100000000482,"failureMessages":[],"location":{"line":1040,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/seo/title — title cleanup & BLUF synthesis"],"fullName":"aggregator/seo/title — title cleanup & BLUF synthesis titleFromBluf strips a leading German date prefix when result is NOT verb-leading","status":"passed","title":"titleFromBluf strips a leading German date prefix when result is NOT verb-leading","duration":1.891841999999997,"failureMessages":[],"location":{"line":1051,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly escapeYaml escapes quotes, backslashes and newlines","status":"passed","title":"escapeYaml escapes quotes, backslashes and newlines","duration":1.8666839999999638,"failureMessages":[],"location":{"line":1062,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly escapeInlineMd escapes markdown metacharacters","status":"passed","title":"escapeInlineMd escapes markdown metacharacters","duration":1.8393330000000105,"failureMessages":[],"location":{"line":1068,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/frontmatter — YAML escape + assembly"],"fullName":"aggregator/frontmatter — YAML escape + assembly buildFrontMatter assembles a body-only block with auto slug and omits SEO fields","status":"passed","title":"buildFrontMatter assembles a body-only block with auto slug and omits SEO fields","duration":2.005814999999984,"failureMessages":[],"location":{"line":1073,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity anchorForTitle prefixes the slug with HEADING_ID_PREFIX","status":"passed","title":"anchorForTitle prefixes the slug with HEADING_ID_PREFIX","duration":3.861799000000019,"failureMessages":[],"location":{"line":1094,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity anchorForTitle strips leading emoji before slugging","status":"passed","title":"anchorForTitle strips leading emoji before slugging","duration":2.1314200000000483,"failureMessages":[],"location":{"line":1100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide emits only rows whose artifact is available","status":"passed","title":"buildReaderGuide emits only rows whose artifact is available","duration":3.153513999999973,"failureMessages":[],"location":{"line":1104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide emits the per-document row when hasDocuments=true","status":"passed","title":"buildReaderGuide emits the per-document row when hasDocuments=true","duration":1.9478970000000118,"failureMessages":[],"location":{"line":1122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — anchor slug parity"],"fullName":"aggregator/reader-guide — anchor slug parity buildReaderGuide audit row targets political-classification when classification-results is absent","status":"passed","title":"buildReaderGuide audit row targets political-classification when classification-results is absent","duration":2.4215239999999767,"failureMessages":[],"location":{"line":1127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix returns null when no artifacts were used","status":"passed","title":"returns null when no artifacts were used","duration":2.0072170000000824,"failureMessages":[],"location":{"line":1140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix emits one bullet per artifact with absolute GitHub URLs","status":"passed","title":"emits one bullet per artifact with absolute GitHub URLs","duration":2.137260999999853,"failureMessages":[],"location":{"line":1144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix links supporting JSON data artifacts without expanding them inline","status":"passed","title":"links supporting JSON data artifacts without expanding them inline","duration":2.8210209999999734,"failureMessages":[],"location":{"line":1155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix emits a supporting-data-only preamble when used is empty but supporting data exists","status":"passed","title":"emits a supporting-data-only preamble when used is empty but supporting data exists","duration":2.547117999999955,"failureMessages":[],"location":{"line":1168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport summarizes emitted, data and absent artifacts","status":"passed","title":"buildArtifactCoverageReport summarizes emitted, data and absent artifacts","duration":2.2196559999999863,"failureMessages":[],"location":{"line":1182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport surfaces alias-de-duped and present-but-empty buckets on their own lines","status":"passed","title":"buildArtifactCoverageReport surfaces alias-de-duped and present-but-empty buckets on their own lines","duration":2.1120140000000447,"failureMessages":[],"location":{"line":1196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/sources-appendix"],"fullName":"aggregator/sources-appendix buildArtifactCoverageReport annotates the supporting-data count when truncation occurred","status":"passed","title":"buildArtifactCoverageReport annotates the supporting-data count when truncation occurred","duration":2.013680000000022,"failureMessages":[],"location":{"line":1213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences swaps fences for <pre class=\"mermaid\">","status":"passed","title":"preprocessMermaidFences swaps fences for <pre class=\"mermaid\">","duration":2.654549000000088,"failureMessages":[],"location":{"line":1226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences escapes HTML inside diagram source","status":"passed","title":"preprocessMermaidFences escapes HTML inside diagram source","duration":2.1642819999999574,"failureMessages":[],"location":{"line":1233,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences injects the canonical %%{init …}%% block when the diagram is unthemed","status":"passed","title":"preprocessMermaidFences injects the canonical %%{init …}%% block when the diagram is unthemed","duration":2.719101000000137,"failureMessages":[],"location":{"line":1239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preprocessMermaidFences leaves an already-themed diagram untouched (no double prologue)","status":"passed","title":"preprocessMermaidFences leaves an already-themed diagram untouched (no double prologue)","duration":2.79166599999985,"failureMessages":[],"location":{"line":1248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation returns body unchanged when there are no mermaid fences","status":"passed","title":"returns body unchanged when there are no mermaid fences","duration":2.1078359999999066,"failureMessages":[],"location":{"line":1260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation recovers from an unclosed mermaid fence by terminating at the next opening fence","status":"passed","title":"recovers from an unclosed mermaid fence by terminating at the next opening fence","duration":2.2073720000000776,"failureMessages":[],"location":{"line":1265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation recovers from an unclosed mermaid fence at end-of-input","status":"passed","title":"recovers from an unclosed mermaid fence at end-of-input","duration":2.1558469999999943,"failureMessages":[],"location":{"line":1294,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation preserves the open/close pairing for back-to-back well-formed mermaid blocks","status":"passed","title":"preserves the open/close pairing for back-to-back well-formed mermaid blocks","duration":2.2521959999999126,"failureMessages":[],"location":{"line":1303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation hasMermaidTheme detects every Check-5 theme signal","status":"passed","title":"hasMermaidTheme detects every Check-5 theme signal","duration":2.4830289999999877,"failureMessages":[],"location":{"line":1320,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation ensureMermaidTheme is a pure function and idempotent","status":"passed","title":"ensureMermaidTheme is a pure function and idempotent","duration":2.2078030000000126,"failureMessages":[],"location":{"line":1329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation CANONICAL_MERMAID_INIT mirrors the cyberpunk dark theme baked into mermaid-init.mjs","status":"passed","title":"CANONICAL_MERMAID_INIT mirrors the cyberpunk dark theme baked into mermaid-init.mjs","duration":2.231608000000051,"failureMessages":[],"location":{"line":1337,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation CANONICAL_MERMAID_INIT satisfies Check 5 of .github/prompts/05-analysis-gate.md","status":"passed","title":"CANONICAL_MERMAID_INIT satisfies Check 5 of .github/prompts/05-analysis-gate.md","duration":2.2583380000000943,"failureMessages":[],"location":{"line":1348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation rehypeSlugWithPrefix exports a plugin function","status":"passed","title":"rehypeSlugWithPrefix exports a plugin function","duration":2.447642000000087,"failureMessages":[],"location":{"line":1358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation rehypeWrapTables exports a plugin function","status":"passed","title":"rehypeWrapTables exports a plugin function","duration":2.310224999999946,"failureMessages":[],"location":{"line":1363,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation HEADING_ID_PREFIX is the canonical `rm-` site prefix","status":"passed","title":"HEADING_ID_PREFIX is the canonical `rm-` site prefix","duration":2.4809940000000097,"failureMessages":[],"location":{"line":1368,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["markdown/* — leaf module isolation"],"fullName":"markdown/* — leaf module isolation sanitizeSchema preserves the `rm-` clobberPrefix","status":"passed","title":"sanitizeSchema preserves the `rm-` clobberPrefix","duration":2.811253000000079,"failureMessages":[],"location":{"line":1372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel re-exports the same `aggregateAnalysis` identity","status":"passed","title":"aggregator barrel re-exports the same `aggregateAnalysis` identity","duration":4.146363000000065,"failureMessages":[],"location":{"line":1381,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel `__test__` exposes the same regex identity as the leaf","status":"passed","title":"aggregator barrel `__test__` exposes the same regex identity as the leaf","duration":2.52776300000005,"failureMessages":[],"location":{"line":1385,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export aggregator barrel `__test__` is frozen (no accidental mutation)","status":"passed","title":"aggregator barrel `__test__` is frozen (no accidental mutation)","duration":2.3286699999998746,"failureMessages":[],"location":{"line":1399,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["barrel parity — leaf identity matches barrel re-export"],"fullName":"barrel parity — leaf identity matches barrel re-export markdown barrel re-exports the same `sanitizeSchema` identity","status":"passed","title":"markdown barrel re-exports the same `sanitizeSchema` identity","duration":2.395735000000059,"failureMessages":[],"location":{"line":1403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage READER_GUIDE_I18N has an entry for all 14 supported languages","status":"passed","title":"READER_GUIDE_I18N has an entry for all 14 supported languages","duration":3.330504000000019,"failureMessages":[],"location":{"line":1415,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage non-English languages have localised (non-English) heading","status":"passed","title":"non-English languages have localised (non-English) heading","duration":3.0579649999999674,"failureMessages":[],"location":{"line":1425,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage non-English languages have localised audit appendix label","status":"passed","title":"non-English languages have localised audit appendix label","duration":2.7388879999998608,"failureMessages":[],"location":{"line":1433,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage every language bundle has entries for all READER_GUIDE_ENTRIES files","status":"passed","title":"every language bundle has entries for all READER_GUIDE_ENTRIES files","duration":5.734545999999909,"failureMessages":[],"location":{"line":1441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide-i18n — 14-language coverage"],"fullName":"aggregator/reader-guide-i18n — 14-language coverage readerGuideI18n() returns English for unknown language","status":"passed","title":"readerGuideI18n() returns English for unknown language","duration":3.445219000000179,"failureMessages":[],"location":{"line":1452,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide with lang=sv produces Swedish heading","status":"passed","title":"buildReaderGuide with lang=sv produces Swedish heading","duration":2.597813999999971,"failureMessages":[],"location":{"line":1460,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide with lang=ja produces Japanese heading","status":"passed","title":"buildReaderGuide with lang=ja produces Japanese heading","duration":2.532079999999951,"failureMessages":[],"location":{"line":1473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide without lang defaults to English","status":"passed","title":"buildReaderGuide without lang defaults to English","duration":2.543190999999979,"failureMessages":[],"location":{"line":1482,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide slug-parity: every anchor starts with HEADING_ID_PREFIX","status":"passed","title":"buildReaderGuide slug-parity: every anchor starts with HEADING_ID_PREFIX","duration":2.9921620000000075,"failureMessages":[],"location":{"line":1490,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/reader-guide — i18n integration"],"fullName":"aggregator/reader-guide — i18n integration buildReaderGuide completeness: row count matches available artifact count + special rows","status":"passed","title":"buildReaderGuide completeness: row count matches available artifact count + special rows","duration":2.7878890000001775,"failureMessages":[],"location":{"line":1501,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide strips an inline Reader Intelligence Guide block from artifact body","status":"passed","title":"strips an inline Reader Intelligence Guide block from artifact body","duration":2.6414149999998244,"failureMessages":[],"location":{"line":1515,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide preserves a paragraph that follows the table without intervening heading","status":"passed","title":"preserves a paragraph that follows the table without intervening heading","duration":2.5956089999999676,"failureMessages":[],"location":{"line":1539,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide returns body unchanged when no Reader Intelligence Guide is present","status":"passed","title":"returns body unchanged when no Reader Intelligence Guide is present","duration":2.555184000000054,"failureMessages":[],"location":{"line":1559,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — stripInlineReaderGuide"],"fullName":"aggregator/cleaning/structural — stripInlineReaderGuide cleanArtifactBody invokes stripInlineReaderGuide (integration)","status":"passed","title":"cleanArtifactBody invokes stripInlineReaderGuide (integration)","duration":2.936828000000105,"failureMessages":[],"location":{"line":1564,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology rewrites BLUF heading and annotates first confidence/doc-id mention","status":"passed","title":"normalizeNarrativeTerminology rewrites BLUF heading and annotates first confidence/doc-id mention","duration":3.3007299999999304,"failureMessages":[],"location":{"line":1589,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology threads first-use state across artifact bodies (once per article)","status":"passed","title":"normalizeNarrativeTerminology threads first-use state across artifact bodies (once per article)","duration":3.0588560000001053,"failureMessages":[],"location":{"line":1610,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines normalizeNarrativeTerminology leaves non-English bodies untouched","status":"passed","title":"normalizeNarrativeTerminology leaves non-English bodies untouched","duration":2.7807150000001,"failureMessages":[],"location":{"line":1624,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines collapses two identical adjacent classification rows","status":"passed","title":"collapses two identical adjacent classification rows","duration":2.717398000000003,"failureMessages":[],"location":{"line":1637,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines keeps non-adjacent duplicate lines intact","status":"passed","title":"keeps non-adjacent duplicate lines intact","duration":2.980641000000105,"failureMessages":[],"location":{"line":1651,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines preserves duplicates inside a fenced code block","status":"passed","title":"preserves duplicates inside a fenced code block","duration":3.0808680000000095,"failureMessages":[],"location":{"line":1656,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — dedupeAdjacentDuplicateLines"],"fullName":"aggregator/cleaning/structural — dedupeAdjacentDuplicateLines is idempotent (applying twice equals applying once)","status":"passed","title":"is idempotent (applying twice equals applying once)","duration":2.698180999999977,"failureMessages":[],"location":{"line":1664,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks collapses repeated **ISMS** footer lines to the first occurrence","status":"passed","title":"collapses repeated **ISMS** footer lines to the first occurrence","duration":2.8069550000000163,"failureMessages":[],"location":{"line":1672,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks collapses repeated `**Classified under …**` markers","status":"passed","title":"collapses repeated `**Classified under …**` markers","duration":2.779442999999901,"failureMessages":[],"location":{"line":1688,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks leaves a single occurrence untouched","status":"passed","title":"leaves a single occurrence untouched","duration":2.7739329999999427,"failureMessages":[],"location":{"line":1698,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks does not strip legitimate content that mentions ISMS in prose","status":"passed","title":"does not strip legitimate content that mentions ISMS in prose","duration":2.8244680000000244,"failureMessages":[],"location":{"line":1703,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["aggregator/cleaning/structural — collapseRepeatedFooterBlocks"],"fullName":"aggregator/cleaning/structural — collapseRepeatedFooterBlocks cleanArtifactBody invokes the new cleaning steps (integration)","status":"passed","title":"cleanArtifactBody invokes the new cleaning steps (integration)","duration":2.982974000000013,"failureMessages":[],"location":{"line":1710,"column":3},"meta":{},"tags":[]}],"startTime":1787953659445,"endTime":1787953659869.983,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips a trailing \"## Pass 2 refinements\" section","status":"passed","title":"strips a trailing \"## Pass 2 refinements\" section","duration":15.679284999999936,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips variants: \"Pass 2 addendum\", \"🔁 Pass 2\", \"### Pass 2 review note\"","status":"passed","title":"strips variants: \"Pass 2 addendum\", \"🔁 Pass 2\", \"### Pass 2 review note\"","duration":11.589388000000099,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips leading admin-byline paragraph (Author / Run ID / Classification / Confidence)","status":"passed","title":"strips leading admin-byline paragraph (Author / Run ID / Classification / Confidence)","duration":0.7464780000000246,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody strips admin byline with · separators","status":"passed","title":"strips admin byline with · separators","duration":0.6456889999999476,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody keeps a paragraph that starts with a bold label but contains real prose","status":"passed","title":"keeps a paragraph that starts with a bold label but contains real prose","duration":0.5131410000001324,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArtifactBody"],"fullName":"render-lib — cleanArtifactBody still strips the first H1, YAML front-matter, Document control, and Run ID: single-line","status":"passed","title":"still strips the first H1, YAML front-matter, Document control, and Run ID: single-line","duration":3.537554,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripPassTwoSection preserves content before and removes content after","status":"passed","title":"stripPassTwoSection preserves content before and removes content after","duration":0.6022580000001199,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines walks multiple admin paragraphs","status":"passed","title":"stripLeadingAdminBylines walks multiple admin paragraphs","duration":0.3973840000001019,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines drops admin blocks anywhere in body, not just leading","status":"passed","title":"stripLeadingAdminBylines drops admin blocks anywhere in body, not just leading","duration":0.7277830000000449,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — helpers"],"fullName":"render-lib — helpers stripLeadingAdminBylines preserves mixed paragraphs (1 admin + analytical fragments)","status":"passed","title":"stripLeadingAdminBylines preserves mixed paragraphs (1 admin + analytical fragments)","duration":0.5270870000001651,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips workflow-process lines while preserving journalist-fact lines in the same paragraph","status":"passed","title":"strips workflow-process lines while preserving journalist-fact lines in the same paragraph","duration":0.6107140000001436,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips Admiralty Code typo \"Admiration Code\" used in some artifacts","status":"passed","title":"strips Admiralty Code typo \"Admiration Code\" used in some artifacts","duration":0.34529700000007324,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) strips ICD 203 / Standard / Self-audit cycle / Framework","status":"passed","title":"strips ICD 203 / Standard / Self-audit cycle / Framework","duration":0.48300499999982094,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip \"Election date\" (a journalism fact) but does strip bare \"Election\"","status":"passed","title":"does NOT strip \"Election date\" (a journalism fact) but does strip bare \"Election\"","duration":0.3581500000000233,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip per-document journalist facts (Beteckning, Minister, Response deadline, Effective date)","status":"passed","title":"does NOT strip per-document journalist facts (Beteckning, Minister, Response deadline, Effective date)","duration":0.39778499999988526,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripProcessMetaLines (per-document journalist-card preservation)"],"fullName":"render-lib — stripProcessMetaLines (per-document journalist-card preservation) does NOT strip analytical callouts (ACH Score, ALARP, Mitigation, Evidence)","status":"passed","title":"does NOT strip analytical callouts (ACH Score, ALARP, Mitigation, Evidence)","duration":0.39707399999997506,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — AGGREGATION_ORDER"],"fullName":"render-lib — AGGREGATION_ORDER puts journalist-optimal narrative arc before technical and audit appendices","status":"passed","title":"puts journalist-optimal narrative arc before technical and audit appendices","duration":0.868987000000061,"failureMessages":[],"location":{"line":289,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — AGGREGATION_ORDER"],"fullName":"render-lib — AGGREGATION_ORDER still keeps the appendix group at the very end","status":"passed","title":"still keeps the appendix group at the very end","duration":1.0353480000001127,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings demotes every ATX heading by one level so artifact bodies nest under wrapper H2","status":"passed","title":"demotes every ATX heading by one level so artifact bodies nest under wrapper H2","duration":0.39093199999979333,"failureMessages":[],"location":{"line":356,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings caps demotion at H6 — already-deep headings are left alone","status":"passed","title":"caps demotion at H6 — already-deep headings are left alone","duration":0.37380000000007385,"failureMessages":[],"location":{"line":383,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings does not touch ATX-looking lines inside fenced code blocks","status":"passed","title":"does not touch ATX-looking lines inside fenced code blocks","duration":0.5001159999999345,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings leaves H1 alone (defensive — already stripped by upstream H1 regex)","status":"passed","title":"leaves H1 alone (defensive — already stripped by upstream H1 regex)","duration":0.5134319999999661,"failureMessages":[],"location":{"line":407,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","demoteHeadings"],"fullName":"render-lib — reader-facing HTML quality projections demoteHeadings ignores `#` characters that are not the start of an ATX heading","status":"passed","title":"ignores `#` characters that are not the start of an ATX heading","duration":0.37299799999982497,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble strips a `_Source: \\`file.md\\`_` italic preamble line at the top of an artifact body","status":"passed","title":"strips a `_Source: \\`file.md\\`_` italic preamble line at the top of an artifact body","duration":0.5474850000000515,"failureMessages":[],"location":{"line":422,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble strips a bare `_Source: file.md_` italic preamble (no link)","status":"passed","title":"strips a bare `_Source: file.md_` italic preamble (no link)","duration":0.3684800000000905,"failureMessages":[],"location":{"line":435,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","stripSourcePreamble"],"fullName":"render-lib — reader-facing HTML quality projections stripSourcePreamble leaves inline `Source:` mentions inside prose untouched","status":"passed","title":"leaves inline `Source:` mentions inside prose untouched","duration":0.4142050000000381,"failureMessages":[],"location":{"line":440,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","anchorForTitle"],"fullName":"render-lib — reader-facing HTML quality projections anchorForTitle produces stable rm-prefixed slugs for ASCII titles","status":"passed","title":"produces stable rm-prefixed slugs for ASCII titles","duration":1.1828149999998914,"failureMessages":[],"location":{"line":447,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — reader-facing HTML quality projections","anchorForTitle"],"fullName":"render-lib — reader-facing HTML quality projections anchorForTitle trims leading hyphens that github-slugger emits when a title starts with a stripped character","status":"passed","title":"trims leading hyphens that github-slugger emits when a title starts with a stripped character","duration":2.0977680000000873,"failureMessages":[],"location":{"line":451,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) aggregates a minimal subfolder, strips Pass-2 and admin bylines, and picks a real description","status":"passed","title":"aggregates a minimal subfolder, strips Pass-2 and admin bylines, and picks a real description","duration":28.181482000000187,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) does NOT re-embed article.md or article.<lang>.md when re-running aggregation","status":"passed","title":"does NOT re-embed article.md or article.<lang>.md when re-running aggregation","duration":5.141636000000062,"failureMessages":[],"location":{"line":558,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) normalizes BLUF framing and adds first-use confidence/doc-id context in aggregated output","status":"passed","title":"normalizes BLUF framing and adds first-use confidence/doc-id context in aggregated output","duration":5.484328000000005,"failureMessages":[],"location":{"line":582,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis (integration)"],"fullName":"render-lib — aggregateAnalysis (integration) Reader Guide is built from emitted artifacts — a file cleaned to empty is NOT linked","status":"passed","title":"Reader Guide is built from emitted artifacts — a file cleaned to empty is NOT linked","duration":2.1642320000000836,"failureMessages":[],"location":{"line":617,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata uses the brief H1 and BLUF without fixed description suffixes","status":"passed","title":"uses the brief H1 and BLUF without fixed description suffixes","duration":2.687702000000172,"failureMessages":[],"location":{"line":656,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata cleans malformed HTML fragments and falls back to the story title instead of an empty meta description","status":"passed","title":"cleans malformed HTML fragments and falls back to the story title instead of an empty meta description","duration":0.7966409999999087,"failureMessages":[],"location":{"line":728,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — article SEO metadata"],"fullName":"render-lib — article SEO metadata keeps identical-H1 EN/DE titles identical (brand suffix when budget allows) — canonical URL disambiguates per-language pages","status":"passed","title":"keeps identical-H1 EN/DE titles identical (brand suffix when budget allows) — canonical URL disambiguates per-language pages","duration":0.8054079999999431,"failureMessages":[],"location":{"line":753,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers exports stable BASE_URL / GITHUB_BLOB / GITHUB_TREE","status":"passed","title":"exports stable BASE_URL / GITHUB_BLOB / GITHUB_TREE","duration":0.7153000000000702,"failureMessages":[],"location":{"line":799,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers LANGUAGES contains all 14 supported languages with en as x-default first","status":"passed","title":"LANGUAGES contains all 14 supported languages with en as x-default first","duration":1.5210680000000139,"failureMessages":[],"location":{"line":805,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers buildGithubBlobUrl strips leading slashes and joins to GITHUB_BLOB","status":"passed","title":"buildGithubBlobUrl strips leading slashes and joins to GITHUB_BLOB","duration":0.8175400000000081,"failureMessages":[],"location":{"line":814,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — constants + URL helpers"],"fullName":"render-lib — constants + URL helpers buildGithubTreeUrl strips leading slashes and joins to GITHUB_TREE","status":"passed","title":"buildGithubTreeUrl strips leading slashes and joins to GITHUB_TREE","duration":0.8200460000000476,"failureMessages":[],"location":{"line":826,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact returns the curated title for every known canonical artifact","status":"passed","title":"returns the curated title for every known canonical artifact","duration":1.0733490000000074,"failureMessages":[],"location":{"line":839,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact falls back to prettified title for unknown supplementary artifacts","status":"passed","title":"falls back to prettified title for unknown supplementary artifacts","duration":1.0148900000001504,"failureMessages":[],"location":{"line":854,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleForArtifact"],"fullName":"render-lib — titleForArtifact handles a bare filename without path","status":"passed","title":"handles a bare filename without path","duration":1.0977250000000822,"failureMessages":[],"location":{"line":862,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks rewrites `./foo.md` to an absolute GitHub blob URL","status":"passed","title":"rewrites `./foo.md` to an absolute GitHub blob URL","duration":0.7589510000000246,"failureMessages":[],"location":{"line":874,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks preserves anchor on a relative link","status":"passed","title":"preserves anchor on a relative link","duration":0.6793219999999565,"failureMessages":[],"location":{"line":879,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks normalises `../` path traversal","status":"passed","title":"normalises `../` path traversal","duration":0.7053100000000541,"failureMessages":[],"location":{"line":884,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves absolute http/https URLs untouched","status":"passed","title":"leaves absolute http/https URLs untouched","duration":0.7561050000001615,"failureMessages":[],"location":{"line":891,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves pure anchor links untouched","status":"passed","title":"leaves pure anchor links untouched","duration":0.6998309999999037,"failureMessages":[],"location":{"line":900,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — rewriteRelativeLinks"],"fullName":"render-lib — rewriteRelativeLinks leaves mailto: links untouched","status":"passed","title":"leaves mailto: links untouched","duration":0.6713569999999436,"failureMessages":[],"location":{"line":904,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph reads the first H1 verbatim from markdown","status":"passed","title":"reads the first H1 verbatim from markdown","duration":1.0767459999999573,"failureMessages":[],"location":{"line":914,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph skips H1, admin bylines, tables, code fences, blockquotes","status":"passed","title":"readFirstParagraph skips H1, admin bylines, tables, code fences, blockquotes","duration":0.9813870000000406,"failureMessages":[],"location":{"line":920,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph returns prose without truncation (truncation is delegated to truncateToSentenceBoundary)","status":"passed","title":"readFirstParagraph returns prose without truncation (truncation is delegated to truncateToSentenceBoundary)","duration":0.8314270000000761,"failureMessages":[],"location":{"line":940,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph readFirstParagraph converts inline markdown links to plain text for article metadata","status":"passed","title":"readFirstParagraph converts inline markdown links to plain text for article metadata","duration":0.8375080000000708,"failureMessages":[],"location":{"line":948,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstHeading / readFirstParagraph"],"fullName":"render-lib — readFirstHeading / readFirstParagraph returns null when markdown has no suitable paragraph","status":"passed","title":"returns null when markdown has no suitable paragraph","duration":0.8400019999999131,"failureMessages":[],"location":{"line":953,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — escape helpers"],"fullName":"render-lib — escape helpers escapeYaml escapes quotes, backslashes, and newlines","status":"passed","title":"escapeYaml escapes quotes, backslashes, and newlines","duration":0.866591999999855,"failureMessages":[],"location":{"line":963,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — escape helpers"],"fullName":"render-lib — escape helpers escapeInlineMd escapes every markdown metachar","status":"passed","title":"escapeInlineMd escapes every markdown metachar","duration":0.8876310000000558,"failureMessages":[],"location":{"line":969,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml renders GFM tables to <table>","status":"passed","title":"renders GFM tables to <table>","duration":22.401660999999876,"failureMessages":[],"location":{"line":983,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml preserves ```mermaid fences as <pre class=\"mermaid\"> blocks verbatim","status":"passed","title":"preserves ```mermaid fences as <pre class=\"mermaid\"> blocks verbatim","duration":11.081306999999924,"failureMessages":[],"location":{"line":990,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml adds id + anchor link to every heading (rehype-slug + autolink-headings)","status":"passed","title":"adds id + anchor link to every heading (rehype-slug + autolink-headings)","duration":4.170008000000053,"failureMessages":[],"location":{"line":1001,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises <script> tags out of the rendered HTML","status":"passed","title":"sanitises <script> tags out of the rendered HTML","duration":4.423281999999972,"failureMessages":[],"location":{"line":1011,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises javascript: URLs out of links","status":"passed","title":"sanitises javascript: URLs out of links","duration":5.3824469999999565,"failureMessages":[],"location":{"line":1021,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml sanitises <iframe> injections","status":"passed","title":"sanitises <iframe> injections","duration":3.0512519999999768,"failureMessages":[],"location":{"line":1026,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml produces unique heading IDs even when an emoji-prefixed heading shares a base slug with a plain heading (HTMLHint id-unique guard)","status":"passed","title":"produces unique heading IDs even when an emoji-prefixed heading shares a base slug with a plain heading (HTMLHint id-unique guard)","duration":4.46860700000002,"failureMessages":[],"location":{"line":1033,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderMarkdownToHtml"],"fullName":"render-lib — renderMarkdownToHtml produces unique heading IDs across an emoji-prefixed and non-prefixed heading with mixed casing (defensive)","status":"passed","title":"produces unique heading IDs across an emoji-prefixed and non-prefixed heading with mixed casing (defensive)","duration":2.9964599999998427,"failureMessages":[],"location":{"line":1060,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead emits <title>, description, canonical, and hreflang × every supplied locale","status":"passed","title":"emits <title>, description, canonical, and hreflang × every supplied locale","duration":2.137732000000142,"failureMessages":[],"location":{"line":1073,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead sets dir=\"rtl\" for Arabic","status":"passed","title":"sets dir=\"rtl\" for Arabic","duration":1.143139999999903,"failureMessages":[],"location":{"line":1092,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead sets dir=\"ltr\" for English","status":"passed","title":"sets dir=\"ltr\" for English","duration":1.0865440000000035,"failureMessages":[],"location":{"line":1102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead embeds provided JSON-LD blobs into <head>","status":"passed","title":"embeds provided JSON-LD blobs into <head>","duration":1.145764999999983,"failureMessages":[],"location":{"line":1112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead"],"fullName":"render-lib — renderChromeHead HTML-escapes title and description","status":"passed","title":"HTML-escapes title and description","duration":1.251704000000018,"failureMessages":[],"location":{"line":1125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits skip-link, site header, nav, and footer","status":"passed","title":"emits skip-link, site header, nav, and footer","duration":2.8481219999998757,"failureMessages":[],"location":{"line":1139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome language switcher lists every language EXCEPT the current one","status":"passed","title":"language switcher lists every language EXCEPT the current one","duration":1.5598809999999048,"failureMessages":[],"location":{"line":1155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome appends bodyClass to the <body> class list","status":"passed","title":"appends bodyClass to the <body> class list","duration":1.425809000000072,"failureMessages":[],"location":{"line":1177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome omits bodyClass when not supplied (only base class on <body>)","status":"passed","title":"omits bodyClass when not supplied (only base class on <body>)","duration":1.6720310000000609,"failureMessages":[],"location":{"line":1189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders the always-visible horizontal language bar by default","status":"passed","title":"renders the always-visible horizontal language bar by default","duration":1.4980749999999716,"failureMessages":[],"location":{"line":1200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome suppresses the horizontal language bar when languageBar is false","status":"passed","title":"suppresses the horizontal language bar when languageBar is false","duration":7.125778999999966,"failureMessages":[],"location":{"line":1213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders the hero banner immediately after the site header by default","status":"passed","title":"renders the hero banner immediately after the site header by default","duration":1.412072999999964,"failureMessages":[],"location":{"line":1227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses the depth-aware prefix for the hero banner image src","status":"passed","title":"uses the depth-aware prefix for the hero banner image src","duration":1.2060080000001108,"failureMessages":[],"location":{"line":1247,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome suppresses the hero banner when heroBanner is false","status":"passed","title":"suppresses the hero banner when heroBanner is false","duration":1.2196630000000823,"failureMessages":[],"location":{"line":1259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome computes the depth-prefix ../ correctly for nested canonical paths","status":"passed","title":"computes the depth-prefix ../ correctly for nested canonical paths","duration":1.740398000000141,"failureMessages":[],"location":{"line":1271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a tagline under the logo on wider viewports","status":"passed","title":"renders a tagline under the logo on wider viewports","duration":1.962242999999944,"failureMessages":[],"location":{"line":1286,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a breadcrumb row in the sub-navigation and a published-date indicator","status":"passed","title":"renders a breadcrumb row in the sub-navigation and a published-date indicator","duration":2.331965999999966,"failureMessages":[],"location":{"line":1296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a 3-column footer with brand, navigate and trust sections plus RSS link","status":"passed","title":"renders a 3-column footer with brand, navigate and trust sections plus RSS link","duration":2.290657999999894,"failureMessages":[],"location":{"line":1311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses a language-specific RSS feed for non-English articles","status":"passed","title":"uses a language-specific RSS feed for non-English articles","duration":1.9685249999999996,"failureMessages":[],"location":{"line":1335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a secondary always-visible language row in the footer","status":"passed","title":"renders a secondary always-visible language row in the footer","duration":2.3379180000001725,"failureMessages":[],"location":{"line":1343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits a header dark/light theme toggle button (id=\"theme-toggle\")","status":"passed","title":"emits a header dark/light theme toggle button (id=\"theme-toggle\")","duration":1.8372600000000148,"failureMessages":[],"location":{"line":1356,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome emits the anti-flash theme bootstrap inline script in <head>","status":"passed","title":"emits the anti-flash theme bootstrap inline script in <head>","duration":1.2057179999999335,"failureMessages":[],"location":{"line":1370,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome bootstraps mermaid + back-to-top + theme-toggle via inline DOM injection (Vite-bypass)","status":"passed","title":"bootstraps mermaid + back-to-top + theme-toggle via inline DOM injection (Vite-bypass)","duration":1.4281740000001264,"failureMessages":[],"location":{"line":1381,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome renders a custom breadcrumb when `breadcrumb` is supplied (skips the legacy 3-tier default)","status":"passed","title":"renders a custom breadcrumb when `breadcrumb` is supplied (skips the legacy 3-tier default)","duration":1.4013240000001588,"failureMessages":[],"location":{"line":1396,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — buildChrome"],"fullName":"render-lib — buildChrome uses `defaultAlternateBase` for the lang-switcher fallback hrefs","status":"passed","title":"uses `defaultAlternateBase` for the lang-switcher fallback hrefs","duration":1.342253000000028,"failureMessages":[],"location":{"line":1417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead `ogType`"],"fullName":"render-lib — renderChromeHead `ogType` defaults to og:type=\"article\" and emits the article:* meta block","status":"passed","title":"defaults to og:type=\"article\" and emits the article:* meta block","duration":1.2398109999999178,"failureMessages":[],"location":{"line":1435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderChromeHead `ogType`"],"fullName":"render-lib — renderChromeHead `ogType` switches to og:type=\"website\" and suppresses the article:* meta block when `ogType: \"website\"`","status":"passed","title":"switches to og:type=\"website\" and suppresses the article:* meta block when `ogType: \"website\"`","duration":1.2646879999999783,"failureMessages":[],"location":{"line":1449,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) produces a complete chrome-wrapped article with rm-article wrapper + sources block","status":"passed","title":"produces a complete chrome-wrapped article with rm-article wrapper + sources block","duration":25.428805999999895,"failureMessages":[],"location":{"line":1488,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) strips <script> injected via aggregated markdown source","status":"passed","title":"strips <script> injected via aggregated markdown source","duration":4.321860999999899,"failureMessages":[],"location":{"line":1550,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) respects hreflang alternates when provided","status":"passed","title":"respects hreflang alternates when provided","duration":4.69420799999989,"failureMessages":[],"location":{"line":1576,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) renders Reader Intelligence Guide in Swedish for lang=sv","status":"passed","title":"renders Reader Intelligence Guide in Swedish for lang=sv","duration":4.47812399999998,"failureMessages":[],"location":{"line":1593,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — renderArticleHtml (end-to-end)"],"fullName":"render-lib — renderArticleHtml (end-to-end) rewrites embedded HTML .md links to canonical GitHub blob URLs","status":"passed","title":"rewrites embedded HTML .md links to canonical GitHub blob URLs","duration":7.404342000000042,"failureMessages":[],"location":{"line":1608,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases throws a helpful error when executive-brief.md is missing","status":"passed","title":"throws a helpful error when executive-brief.md is missing","duration":2.4727589999999964,"failureMessages":[],"location":{"line":1651,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases throws when subfolder does not exist at all","status":"passed","title":"throws when subfolder does not exist at all","duration":1.5152160000000094,"failureMessages":[],"location":{"line":1666,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases expands documents/*.md inline as \"Per-document intelligence\" subsections","status":"passed","title":"expands documents/*.md inline as \"Per-document intelligence\" subsections","duration":2.99277300000017,"failureMessages":[],"location":{"line":1677,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases classifies a sibling that exists on disk + alias-suppressed as alias-de-duped (not present-but-empty) in the coverage report","status":"passed","title":"classifies a sibling that exists on disk + alias-suppressed as alias-de-duped (not present-but-empty) in the coverage report","duration":2.563950999999861,"failureMessages":[],"location":{"line":1705,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis edge cases"],"fullName":"render-lib — aggregateAnalysis edge cases appends unknown supplementary *.md after the core order alphabetically","status":"passed","title":"appends unknown supplementary *.md after the core order alphabetically","duration":2.6473359999999957,"failureMessages":[],"location":{"line":1733,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches the legacy admin fields","status":"passed","title":"matches the legacy admin fields","duration":1.6809180000000197,"failureMessages":[],"location":{"line":1771,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches the new contract fields that previously leaked into descriptions","status":"passed","title":"matches the new contract fields that previously leaked into descriptions","duration":1.8147369999999228,"failureMessages":[],"location":{"line":1791,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches preamble-leak fields observed 2026-04-27 (Analysis period / Pass 2 / AI-FIRST iterations / ARTICLE_TYPE)","status":"passed","title":"matches preamble-leak fields observed 2026-04-27 (Analysis period / Pass 2 / AI-FIRST iterations / ARTICLE_TYPE)","duration":3.388723999999911,"failureMessages":[],"location":{"line":1813,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) matches unbolded admin fields (leak case — description read back from rendered HTML)","status":"passed","title":"matches unbolded admin fields (leak case — description read back from rendered HTML)","duration":1.635962999999947,"failureMessages":[],"location":{"line":1907,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FIELD_RE (SEO contract §3a)"],"fullName":"render-lib — ADMIN_FIELD_RE (SEO contract §3a) does not match real prose that happens to start with similar words","status":"passed","title":"does not match real prose that happens to start with similar words","duration":1.4077559999998357,"failureMessages":[],"location":{"line":1913,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) splits on structural delimiters (pipe, fullwidth pipe, newline, double-space)","status":"passed","title":"splits on structural delimiters (pipe, fullwidth pipe, newline, double-space)","duration":1.5968000000000302,"failureMessages":[],"location":{"line":1920,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) does NOT split on em-dash / middle-dot (value-internal punctuation)","status":"passed","title":"does NOT split on em-dash / middle-dot (value-internal punctuation)","duration":1.5034149999999045,"failureMessages":[],"location":{"line":1928,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b)"],"fullName":"render-lib — ADMIN_FRAGMENT_SPLITTER (SEO contract §3b) handles |-separated admin blocks — whole block is admin, every fragment matches","status":"passed","title":"handles |-separated admin blocks — whole block is admin, every fragment matches","duration":1.51237100000003,"failureMessages":[],"location":{"line":1938,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b)"],"fullName":"render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b) skips a paragraph whose fragments are all admin fields, even when joined by `|`","status":"passed","title":"skips a paragraph whose fragments are all admin fields, even when joined by `|`","duration":1.6220670000000155,"failureMessages":[],"location":{"line":1949,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b)"],"fullName":"render-lib — readFirstParagraph skips |-separated admin blocks (SEO contract §3b) skips a multi-line admin block led by an unbolded `Brief ID`","status":"passed","title":"skips a multi-line admin block led by an unbolded `Brief ID`","duration":2.129216000000042,"failureMessages":[],"location":{"line":1962,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) returns the input unchanged when it is already within the window","status":"passed","title":"returns the input unchanged when it is already within the window","duration":1.7501360000001114,"failureMessages":[],"location":{"line":1985,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) truncates at the last sentence boundary within hardMax, not mid-word","status":"passed","title":"truncates at the last sentence boundary within hardMax, not mid-word","duration":2.6914989999997943,"failureMessages":[],"location":{"line":1990,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) never cuts mid-word when no sentence boundary is reachable","status":"passed","title":"never cuts mid-word when no sentence boundary is reachable","duration":2.7455199999999422,"failureMessages":[],"location":{"line":2003,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) respects custom windows (e.g. CJK 70-120)","status":"passed","title":"respects custom windows (e.g. CJK 70-120)","duration":1.844733000000133,"failureMessages":[],"location":{"line":2013,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — truncateToSentenceBoundary (SEO contract §3c)"],"fullName":"render-lib — truncateToSentenceBoundary (SEO contract §3c) supports CJK full stop `。` as a sentence terminator","status":"passed","title":"supports CJK full stop `。` as a sentence terminator","duration":2.240885000000162,"failureMessages":[],"location":{"line":2021,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) returns the first prose paragraph after a `## 🎯 BLUF` heading","status":"passed","title":"returns the first prose paragraph after a `## 🎯 BLUF` heading","duration":1.7903120000000854,"failureMessages":[],"location":{"line":2032,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) returns null when the brief has no BLUF heading","status":"passed","title":"returns null when the brief has no BLUF heading","duration":1.6915169999999762,"failureMessages":[],"location":{"line":2050,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — readBlufParagraph (SEO contract §3d)"],"fullName":"render-lib — readBlufParagraph (SEO contract §3d) skips admin paragraphs between the BLUF heading and the first prose","status":"passed","title":"skips admin paragraphs between the BLUF heading and the first prose","duration":1.7450370000001385,"failureMessages":[],"location":{"line":2055,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips `Executive Brief — ` prefix and trailing ISO date","status":"passed","title":"strips `Executive Brief — ` prefix and trailing ISO date","duration":1.9407139999998435,"failureMessages":[],"location":{"line":2070,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) returns null when the cleaned title is too short to be a real headline","status":"passed","title":"returns null when the cleaned title is too short to be a real headline","duration":1.7351679999999305,"failureMessages":[],"location":{"line":2077,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) preserves a real editorial headline that already has no boilerplate","status":"passed","title":"preserves a real editorial headline that already has no boilerplate","duration":1.6599069999999756,"failureMessages":[],"location":{"line":2086,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips trailing realtime-cycle timestamps like ` 2026-04-22 23:38`","status":"passed","title":"strips trailing realtime-cycle timestamps like ` 2026-04-22 23:38`","duration":1.671980000000076,"failureMessages":[],"location":{"line":2091,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) handles the `Realtime Monitor — ` boilerplate prefix too","status":"passed","title":"handles the `Realtime Monitor — ` boilerplate prefix too","duration":1.9069700000000012,"failureMessages":[],"location":{"line":2098,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips leading pictographs / emoji prefixes like `📋 Executive Brief — …`","status":"passed","title":"strips leading pictographs / emoji prefixes like `📋 Executive Brief — …`","duration":2.0078289999999015,"failureMessages":[],"location":{"line":2103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — cleanArticleTitle (SEO contract §3e)"],"fullName":"render-lib — cleanArticleTitle (SEO contract §3e) strips mid-title ISO date ranges and dangling connectors","status":"passed","title":"strips mid-title ISO date ranges and dangling connectors","duration":2.1135069999997995,"failureMessages":[],"location":{"line":2113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) synthesises a title from the first BLUF sentence","status":"passed","title":"synthesises a title from the first BLUF sentence","duration":2.1896489999999176,"failureMessages":[],"location":{"line":2131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) returns null when there is no usable BLUF","status":"passed","title":"returns null when there is no usable BLUF","duration":2.236987999999883,"failureMessages":[],"location":{"line":2139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — titleFromBluf (SEO contract §3e fallback)"],"fullName":"render-lib — titleFromBluf (SEO contract §3e fallback) truncates at word boundary when the first sentence exceeds maxLen","status":"passed","title":"truncates at word boundary when the first sentence exceeds maxLen","duration":2.151787999999897,"failureMessages":[],"location":{"line":2145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis end-to-end contract"],"fullName":"render-lib — aggregateAnalysis end-to-end contract produces a clean title + description for a realistic executive-brief with boilerplate H1","status":"passed","title":"produces a clean title + description for a realistic executive-brief with boilerplate H1","duration":8.217964999999822,"failureMessages":[],"location":{"line":2159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — aggregateAnalysis end-to-end contract"],"fullName":"render-lib — aggregateAnalysis end-to-end contract synthesises a BLUF-based title when the H1 collapses to nothing useful","status":"passed","title":"synthesises a BLUF-based title when the H1 collapses to nothing useful","duration":3.775378000000046,"failureMessages":[],"location":{"line":2203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips the ## Reader Intelligence Guide section from article body","status":"passed","title":"strips the ## Reader Intelligence Guide section from article body","duration":2.2191550000000007,"failureMessages":[],"location":{"line":2235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips the ## Article Sources section from article body","status":"passed","title":"strips the ## Article Sources section from article body","duration":2.0097030000001723,"failureMessages":[],"location":{"line":2261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections strips both sections when present together","status":"passed","title":"strips both sections when present together","duration":2.0007359999999608,"failureMessages":[],"location":{"line":2281,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections returns body unchanged when neither section is present","status":"passed","title":"returns body unchanged when neither section is present","duration":2.0246199999999135,"failureMessages":[],"location":{"line":2311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections renders no inline Reader Guide or Article Sources in final HTML (integration)","status":"passed","title":"renders no inline Reader Guide or Article Sources in final HTML (integration)","duration":4.866269999999986,"failureMessages":[],"location":{"line":2316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections renders fully localized Reader Intelligence Guide table for all 14 languages","status":"passed","title":"renders fully localized Reader Intelligence Guide table for all 14 languages","duration":24.570138999999926,"failureMessages":[],"location":{"line":2369,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["render-lib — stripBodyDuplicateSections"],"fullName":"render-lib — stripBodyDuplicateSections styles Reader Intelligence Guide table outside the article body","status":"passed","title":"styles Reader Intelligence Guide table outside the article body","duration":3.9773560000001,"failureMessages":[],"location":{"line":2423,"column":3},"meta":{},"tags":[]}],"startTime":1787953658260,"endTime":1787953658645.9773,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/render-lib.test.ts"},{"assertionResults":[{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers parses commands and artifact kinds","status":"passed","title":"parses commands and artifact kinds","duration":3.997064000000023,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers rejects unsafe or non-Riksbank URLs","status":"passed","title":"rejects unsafe or non-Riksbank URLs","duration":1.9847659999999792,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers builds provenance for HTML responses","status":"passed","title":"builds provenance for HTML responses","duration":6.062652000000014,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers builds provenance for JSON responses","status":"passed","title":"builds provenance for JSON responses","duration":1.6506309999999758,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers encodes PDF responses as base64 with a byte-length cap","status":"passed","title":"encodes PDF responses as base64 with a byte-length cap","duration":0.9449799999999868,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs to a no-data payload on network outage","status":"passed","title":"fail-softs to a no-data payload on network outage","duration":0.961640999999986,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs to a no-data payload on non-2xx HTTP status","status":"passed","title":"fail-softs to a no-data payload on non-2xx HTTP status","duration":0.8150170000000116,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers fail-softs when Content-Length exceeds the PDF cap before downloading","status":"passed","title":"fail-softs when Content-Length exceeds the PDF cap before downloading","duration":0.6212229999999863,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers follows redirects manually and validates each Location host","status":"passed","title":"follows redirects manually and validates each Location host","duration":0.8154670000000124,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Riksbank fetch CLI helpers"],"fullName":"Riksbank fetch CLI helpers rejects redirects to off-allowlist hosts","status":"passed","title":"rejects redirects to off-allowlist hosts","duration":0.6937490000000253,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]}],"startTime":1787953871086,"endTime":1787953871104.6938,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/riksbank-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["constants"],"fullName":"constants CONSTITUTIONAL_DEADLINE_MONTHS is 4","status":"passed","title":"CONSTITUTIONAL_DEADLINE_MONTHS is 4","duration":3.812628000000018,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["constants"],"fullName":"constants RIR_SKRIVELSE_DOKTYP is \"skr\"","status":"passed","title":"RIR_SKRIVELSE_DOKTYP is \"skr\"","duration":0.6548560000000521,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["constants"],"fullName":"constants RIR_SKRIVELSE_SUBTYP is \"rsk\"","status":"passed","title":"RIR_SKRIVELSE_SUBTYP is \"rsk\"","duration":0.5822800000000257,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline adds 4 months to a mid-month date","status":"passed","title":"adds 4 months to a mid-month date","duration":0.6427629999999454,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline adds 4 months crossing a year boundary","status":"passed","title":"adds 4 months crossing a year boundary","duration":0.5119789999999966,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline clamps to last day when target month is shorter","status":"passed","title":"clamps to last day when target month is shorter","duration":0.5676530000000071,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline handles leap year correctly","status":"passed","title":"handles leap year correctly","duration":0.598199999999963,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline uses custom month override","status":"passed","title":"uses custom month override","duration":0.4977819999999724,"failureMessages":[],"location":{"line":160,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline throws RangeError on invalid date","status":"passed","title":"throws RangeError on invalid date","duration":0.827619000000027,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateSkrivelseDeadline"],"fullName":"calculateSkrivelseDeadline handles end of year wrapping correctly","status":"passed","title":"handles end of year wrapping correctly","duration":0.5528040000000374,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns 0 when not yet overdue","status":"passed","title":"returns 0 when not yet overdue","duration":0.6057739999999967,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns positive integer when overdue","status":"passed","title":"returns positive integer when overdue","duration":0.38965899999999465,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue returns 0 exactly on the deadline day","status":"passed","title":"returns 0 exactly on the deadline day","duration":0.4524870000000192,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue throws RangeError on invalid deadlineDate","status":"passed","title":"throws RangeError on invalid deadlineDate","duration":0.44118600000001607,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["daysOverdue"],"fullName":"daysOverdue throws RangeError on invalid asOf string","status":"passed","title":"throws RangeError on invalid asOf string","duration":0.46497099999999136,"failureMessages":[],"location":{"line":194,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns RESPONDED when skrivelse_id set and status RESPONDED","status":"passed","title":"returns RESPONDED when skrivelse_id set and status RESPONDED","duration":0.4770229999999742,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PARTIAL when status PARTIAL and skrivelse_id set","status":"passed","title":"returns PARTIAL when status PARTIAL and skrivelse_id set","duration":0.513089999999977,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns OVERDUE when deadline elapsed and no response","status":"passed","title":"returns OVERDUE when deadline elapsed and no response","duration":0.4037859999999682,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PENDING when deadline not yet elapsed","status":"passed","title":"returns PENDING when deadline not yet elapsed","duration":0.504413999999997,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PENDING when no deadline set","status":"passed","title":"returns PENDING when no deadline set","duration":0.6024780000000192,"failureMessages":[],"location":{"line":222,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus uses current date by default","status":"passed","title":"uses current date by default","duration":1.51108899999997,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns RESPONDED when stored status is PENDING but response_skrivelse_id is set (rule 1)","status":"passed","title":"returns RESPONDED when stored status is PENDING but response_skrivelse_id is set (rule 1)","duration":0.4885449999999878,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveResponseStatus"],"fullName":"deriveResponseStatus returns PARTIAL when response_skrivelse_id is set but open_recommendations > 0","status":"passed","title":"returns PARTIAL when response_skrivelse_id is set but open_recommendations > 0","duration":0.5259549999999535,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts returns alerts for OVERDUE records only","status":"passed","title":"returns alerts for OVERDUE records only","duration":1.3141009999999937,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts alert has correct days_overdue","status":"passed","title":"alert has correct days_overdue","duration":0.5347210000000473,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts returns empty array when no records are overdue","status":"passed","title":"returns empty array when no records are overdue","duration":0.5999029999999834,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts sorts alerts by days_overdue descending","status":"passed","title":"sorts alerts by days_overdue descending","duration":0.6211019999999507,"failureMessages":[],"location":{"line":278,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts skips records with no skrivelse_deadline","status":"passed","title":"skips records with no skrivelse_deadline","duration":0.6091199999999617,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectOverdueAlerts"],"fullName":"detectOverdueAlerts skips records that already have a response_skrivelse_id","status":"passed","title":"skips records that already have a response_skrivelse_id","duration":0.6282559999999648,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable renders a header row and record rows","status":"passed","title":"renders a header row and record rows","duration":0.8802180000000135,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable shows overdue emoji for overdue records","status":"passed","title":"shows overdue emoji for overdue records","duration":0.7348850000000198,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable shows pending emoji for pending records","status":"passed","title":"shows pending emoji for pending records","duration":3.1180269999999837,"failureMessages":[],"location":{"line":329,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable uses riksdag_url for title link when available","status":"passed","title":"uses riksdag_url for title link when available","duration":0.5015390000000366,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["renderRirFollowUpTable"],"fullName":"renderRirFollowUpTable renders empty table gracefully","status":"passed","title":"renders empty table gracefully","duration":0.6177959999999985,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument appends a table block to a document without existing markers","status":"passed","title":"appends a table block to a document without existing markers","duration":0.6421320000000037,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument replaces an existing table block","status":"passed","title":"replaces an existing table block","duration":0.5057369999999537,"failureMessages":[],"location":{"line":364,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["injectRirTableIntoDocument"],"fullName":"injectRirTableIntoDocument preserves content before and after the markers","status":"passed","title":"preserves content before and after the markers","duration":0.5274480000000494,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee filters records by committee code","status":"passed","title":"filters records by committee code","duration":0.5934910000000286,"failureMessages":[],"location":{"line":402,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee is case-insensitive","status":"passed","title":"is case-insensitive","duration":1.3386059999999702,"failureMessages":[],"location":{"line":408,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee returns empty array if no match","status":"passed","title":"returns empty array if no match","duration":0.5005770000000211,"failureMessages":[],"location":{"line":414,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByCommittee"],"fullName":"filterByCommittee handles records without committees field","status":"passed","title":"handles records without committees field","duration":0.6027290000000107,"failureMessages":[],"location":{"line":418,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters PENDING records","status":"passed","title":"filters PENDING records","duration":0.716951999999992,"failureMessages":[],"location":{"line":429,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters OVERDUE records","status":"passed","title":"filters OVERDUE records","duration":0.575347000000022,"failureMessages":[],"location":{"line":435,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters RESPONDED records","status":"passed","title":"filters RESPONDED records","duration":0.5709190000000035,"failureMessages":[],"location":{"line":441,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByStatus"],"fullName":"filterByStatus filters PARTIAL records","status":"passed","title":"filters PARTIAL records","duration":0.5175789999999552,"failureMessages":[],"location":{"line":447,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel returns all records at or above LOW","status":"passed","title":"returns all records at or above LOW","duration":0.7876739999999813,"failureMessages":[],"location":{"line":459,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel filters to MEDIUM and above","status":"passed","title":"filters to MEDIUM and above","duration":0.9978780000000143,"failureMessages":[],"location":{"line":464,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel filters to HIGH and above","status":"passed","title":"filters to HIGH and above","duration":0.7941870000000222,"failureMessages":[],"location":{"line":473,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["filterByMinRiskLevel"],"fullName":"filterByMinRiskLevel defaults missing risk_level to MEDIUM (shared default)","status":"passed","title":"defaults missing risk_level to MEDIUM (shared default)","duration":0.8828229999999735,"failureMessages":[],"location":{"line":479,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord passes a fully valid record","status":"passed","title":"passes a fully valid record","duration":1.079842000000042,"failureMessages":[],"location":{"line":492,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports missing rir_report_id","status":"passed","title":"reports missing rir_report_id","duration":0.7862119999999777,"failureMessages":[],"location":{"line":496,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid rir_number format","status":"passed","title":"reports invalid rir_number format","duration":0.7677569999999605,"failureMessages":[],"location":{"line":502,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid publish_date","status":"passed","title":"reports invalid publish_date","duration":0.7353469999999902,"failureMessages":[],"location":{"line":508,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports invalid gov_response_status","status":"passed","title":"reports invalid gov_response_status","duration":0.8251750000000015,"failureMessages":[],"location":{"line":514,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports RESPONDED without response_skrivelse_id","status":"passed","title":"reports RESPONDED without response_skrivelse_id","duration":0.9906750000000102,"failureMessages":[],"location":{"line":520,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord accepts null skrivelse_deadline","status":"passed","title":"accepts null skrivelse_deadline","duration":0.8483289999999784,"failureMessages":[],"location":{"line":529,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string response_skrivelse_id","status":"passed","title":"reports non-string response_skrivelse_id","duration":0.7984149999999772,"failureMessages":[],"location":{"line":535,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string item in parliamentary_followup_doc_ids","status":"passed","title":"reports non-string item in parliamentary_followup_doc_ids","duration":1.192352000000028,"failureMessages":[],"location":{"line":541,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirRecord"],"fullName":"validateRirRecord reports non-string item in committees","status":"passed","title":"reports non-string item in committees","duration":1.072829000000013,"failureMessages":[],"location":{"line":550,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirDataset"],"fullName":"validateRirDataset returns empty map for valid dataset","status":"passed","title":"returns empty map for valid dataset","duration":0.9257129999999734,"failureMessages":[],"location":{"line":562,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateRirDataset"],"fullName":"validateRirDataset returns entries for each invalid record","status":"passed","title":"returns entries for each invalid record","duration":0.902259000000015,"failureMessages":[],"location":{"line":567,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadRirDataset"],"fullName":"loadRirDataset parses a JSON string via injectable reader","status":"passed","title":"parses a JSON string via injectable reader","duration":1.1187249999999835,"failureMessages":[],"location":{"line":585,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadRirDataset"],"fullName":"loadRirDataset throws on malformed JSON","status":"passed","title":"throws on malformed JSON","duration":1.0023069999999734,"failureMessages":[],"location":{"line":593,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["saveRirDataset"],"fullName":"saveRirDataset calls writeFileFn with pretty JSON","status":"passed","title":"calls writeFileFn with pretty JSON","duration":1.3059259999999995,"failureMessages":[],"location":{"line":600,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["saveRirDataset"],"fullName":"saveRirDataset updates last_updated using injected clock (deterministic)","status":"passed","title":"updates last_updated using injected clock (deterministic)","duration":1.277131000000054,"failureMessages":[],"location":{"line":611,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/rir-followups.json integrity"],"fullName":"data/rir-followups.json integrity loads and validates the real dataset file","status":"passed","title":"loads and validates the real dataset file","duration":1.3352499999999736,"failureMessages":[],"location":{"line":629,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/rir-followups.json integrity"],"fullName":"data/rir-followups.json integrity all records in data/rir-followups.json have required fields","status":"passed","title":"all records in data/rir-followups.json have required fields","duration":1.8258189999999672,"failureMessages":[],"location":{"line":647,"column":3},"meta":{},"tags":[]}],"startTime":1787953668364,"endTime":1787953668421.826,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rir-followups-client.test.ts"},{"assertionResults":[{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should define all four risk levels","status":"passed","title":"should define all four risk levels","duration":13.573290999999983,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have non-overlapping score ranges","status":"passed","title":"should have non-overlapping score ranges","duration":4.195425,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have valid hex color codes","status":"passed","title":"should have valid hex color codes","duration":3.788742999999954,"failureMessages":[],"location":{"line":118,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should have human-readable labels","status":"passed","title":"should have human-readable labels","duration":3.586213999999984,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Level Configuration"],"fullName":"Risk Dashboard Risk Level Configuration should cover full 0-10 score range","status":"passed","title":"should cover full 0-10 score range","duration":4.030776000000003,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should define colors for all 8 Swedish parties","status":"passed","title":"should define colors for all 8 Swedish parties","duration":3.7004479999999944,"failureMessages":[],"location":{"line":149,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should include all expected party abbreviations","status":"passed","title":"should include all expected party abbreviations","duration":2.74230399999999,"failureMessages":[],"location":{"line":153,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should have valid hex color codes","status":"passed","title":"should have valid hex color codes","duration":2.8481720000000337,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Party Colors Configuration"],"fullName":"Risk Dashboard Party Colors Configuration should have distinct colors for each party","status":"passed","title":"should have distinct colors for each party","duration":2.797187000000008,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should define 8 data source URLs","status":"passed","title":"should define 8 data source URLs","duration":2.8813639999999623,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should point to GitHub raw content","status":"passed","title":"should point to GitHub raw content","duration":3.100524000000007,"failureMessages":[],"location":{"line":189,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should reference CSV files","status":"passed","title":"should reference CSV files","duration":8.402560999999935,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should reference sample-data directory","status":"passed","title":"should reference sample-data directory","duration":2.307811000000015,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include risk-related datasets","status":"passed","title":"should include risk-related datasets","duration":1.8606529999999566,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include anomaly datasets","status":"passed","title":"should include anomaly datasets","duration":1.7546950000000834,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data URLs Configuration"],"fullName":"Risk Dashboard CIA Data URLs Configuration should include top-10 datasets","status":"passed","title":"should include top-10 datasets","duration":1.5724129999999832,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 8.0-10.0 as CRITICAL","status":"passed","title":"should classify scores 8.0-10.0 as CRITICAL","duration":1.7658050000000003,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 6.0-7.99 as HIGH","status":"passed","title":"should classify scores 6.0-7.99 as HIGH","duration":1.784511000000066,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 4.0-5.99 as MEDIUM","status":"passed","title":"should classify scores 4.0-5.99 as MEDIUM","duration":1.5596289999999726,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should classify scores 0.0-3.99 as LOW","status":"passed","title":"should classify scores 0.0-3.99 as LOW","duration":2.1252789999999777,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Classification"],"fullName":"Risk Dashboard Risk Classification should handle boundary values correctly","status":"passed","title":"should handle boundary values correctly","duration":1.708148000000051,"failureMessages":[],"location":{"line":260,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return red for critical scores","status":"passed","title":"should return red for critical scores","duration":1.5613429999999653,"failureMessages":[],"location":{"line":285,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return orange for high scores","status":"passed","title":"should return orange for high scores","duration":1.6180990000000293,"failureMessages":[],"location":{"line":289,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return yellow for medium scores","status":"passed","title":"should return yellow for medium scores","duration":1.975958999999989,"failureMessages":[],"location":{"line":293,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Risk Color Mapping"],"fullName":"Risk Dashboard Risk Color Mapping should return green for low scores","status":"passed","title":"should return green for low scores","duration":2.0781299999999874,"failureMessages":[],"location":{"line":297,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 15,705 data points (349 MPs × 45 rules)","status":"passed","title":"should generate 15,705 data points (349 MPs × 45 rules)","duration":6.591660000000047,"failureMessages":[],"location":{"line":337,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should assign all 8 parties to MPs","status":"passed","title":"should assign all 8 parties to MPs","duration":6.72394799999995,"failureMessages":[],"location":{"line":342,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 349 unique politicians","status":"passed","title":"should generate 349 unique politicians","duration":7.207263000000012,"failureMessages":[],"location":{"line":348,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate 45 unique rules","status":"passed","title":"should generate 45 unique rules","duration":17.428058000000078,"failureMessages":[],"location":{"line":354,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate scores within 0-10 range","status":"passed","title":"should generate scores within 0-10 range","duration":301.5770520000001,"failureMessages":[],"location":{"line":360,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should have proper data structure for each entry","status":"passed","title":"should have proper data structure for each entry","duration":5.975947000000019,"failureMessages":[],"location":{"line":368,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should generate realistic risk distribution (majority low)","status":"passed","title":"should generate realistic risk distribution (majority low)","duration":5.819063999999912,"failureMessages":[],"location":{"line":379,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should assign consistent level labels","status":"passed","title":"should assign consistent level labels","duration":308.1676000000001,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should format politician names with zero-padded index","status":"passed","title":"should format politician names with zero-padded index","duration":6.023807000000033,"failureMessages":[],"location":{"line":394,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Mock Risk Data Generation"],"fullName":"Risk Dashboard Mock Risk Data Generation should format rule IDs with zero-padded index","status":"passed","title":"should format rule IDs with zero-padded index","duration":5.4936649999999645,"failureMessages":[],"location":{"line":400,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P50 (median) correctly","status":"passed","title":"should calculate P50 (median) correctly","duration":1.9201540000001387,"failureMessages":[],"location":{"line":418,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P90 correctly","status":"passed","title":"should calculate P90 correctly","duration":1.717335999999932,"failureMessages":[],"location":{"line":424,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should calculate P99 correctly","status":"passed","title":"should calculate P99 correctly","duration":8.160845999999992,"failureMessages":[],"location":{"line":430,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should handle single-element arrays","status":"passed","title":"should handle single-element arrays","duration":1.826189000000113,"failureMessages":[],"location":{"line":436,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should handle unsorted input","status":"passed","title":"should handle unsorted input","duration":1.8020939999998973,"failureMessages":[],"location":{"line":441,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Percentile Calculation"],"fullName":"Risk Dashboard Percentile Calculation should not mutate original array","status":"passed","title":"should not mutate original array","duration":2.638879999999972,"failureMessages":[],"location":{"line":447,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have risk dashboard section","status":"passed","title":"should have risk dashboard section","duration":1.962003999999979,"failureMessages":[],"location":{"line":460,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have dashboard-container class","status":"passed","title":"should have dashboard-container class","duration":2.208554000000049,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have early warnings banner with ARIA attributes","status":"passed","title":"should have early warnings banner with ARIA attributes","duration":1.7955520000000433,"failureMessages":[],"location":{"line":469,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have risk heat map container","status":"passed","title":"should have risk heat map container","duration":1.8263389999999617,"failureMessages":[],"location":{"line":477,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have heat map legend","status":"passed","title":"should have heat map legend","duration":1.8038369999999304,"failureMessages":[],"location":{"line":483,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have all chart canvases","status":"passed","title":"should have all chart canvases","duration":1.8630880000000616,"failureMessages":[],"location":{"line":489,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have top 10 lists","status":"passed","title":"should have top 10 lists","duration":1.862547000000177,"failureMessages":[],"location":{"line":496,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have last updated span","status":"passed","title":"should have last updated span","duration":2.035219999999981,"failureMessages":[],"location":{"line":505,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have filter controls","status":"passed","title":"should have filter controls","duration":1.8822339999999258,"failureMessages":[],"location":{"line":511,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have accessible chart canvases with role=img","status":"passed","title":"should have accessible chart canvases with role=img","duration":2.524756000000025,"failureMessages":[],"location":{"line":517,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have aria-labels on chart canvases","status":"passed","title":"should have aria-labels on chart canvases","duration":2.443373999999949,"failureMessages":[],"location":{"line":522,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","DOM Structure"],"fullName":"Risk Dashboard DOM Structure should have accessible top 10 lists with aria-labels","status":"passed","title":"should have accessible top 10 lists with aria-labels","duration":2.128024000000096,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have high-risk filter checkbox","status":"passed","title":"should have high-risk filter checkbox","duration":1.9943640000001324,"failureMessages":[],"location":{"line":542,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have risk rule filter dropdown","status":"passed","title":"should have risk rule filter dropdown","duration":2.023889000000054,"failureMessages":[],"location":{"line":549,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have \"All Rules\" default option","status":"passed","title":"should have \"All Rules\" default option","duration":3.201663999999937,"failureMessages":[],"location":{"line":556,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Filter Controls"],"fullName":"Risk Dashboard Filter Controls should have reset zoom button","status":"passed","title":"should have reset zoom button","duration":2.076456999999891,"failureMessages":[],"location":{"line":562,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display critical alert when critical MPs exist","status":"passed","title":"should display critical alert when critical MPs exist","duration":2.590750000000071,"failureMessages":[],"location":{"line":574,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display high alert for elevated risk","status":"passed","title":"should display high alert for elevated risk","duration":2.529444999999896,"failureMessages":[],"location":{"line":587,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should display normal status when risks are acceptable","status":"passed","title":"should display normal status when risks are acceptable","duration":2.3505599999998594,"failureMessages":[],"location":{"line":596,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should set assertive aria-live for critical alerts","status":"passed","title":"should set assertive aria-live for critical alerts","duration":2.3353819999999814,"failureMessages":[],"location":{"line":605,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Early Warning System"],"fullName":"Risk Dashboard Early Warning System should set polite aria-live for non-critical alerts","status":"passed","title":"should set polite aria-live for non-critical alerts","duration":2.203866000000062,"failureMessages":[],"location":{"line":611,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle successful CSV fetch","status":"passed","title":"should handle successful CSV fetch","duration":2.6842659999999796,"failureMessages":[],"location":{"line":623,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle failed CSV fetch gracefully","status":"passed","title":"should handle failed CSV fetch gracefully","duration":2.496544999999969,"failureMessages":[],"location":{"line":638,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should handle network errors gracefully","status":"passed","title":"should handle network errors gracefully","duration":4.25550700000008,"failureMessages":[],"location":{"line":647,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should parse risk_level CSV columns","status":"passed","title":"should parse risk_level CSV columns","duration":13.38082200000008,"failureMessages":[],"location":{"line":655,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should parse politician_count as integer","status":"passed","title":"should parse politician_count as integer","duration":7.624414000000115,"failureMessages":[],"location":{"line":664,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","CIA Data Loading"],"fullName":"Risk Dashboard CIA Data Loading should transform risk data into matrix format","status":"passed","title":"should transform risk data into matrix format","duration":5.404647999999952,"failureMessages":[],"location":{"line":675,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for risk distribution chart","status":"passed","title":"should have canvas context for risk distribution chart","duration":4.88417400000003,"failureMessages":[],"location":{"line":710,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for anomaly detection chart","status":"passed","title":"should have canvas context for anomaly detection chart","duration":4.54430699999989,"failureMessages":[],"location":{"line":716,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for crisis resilience chart","status":"passed","title":"should have canvas context for crisis resilience chart","duration":13.959614999999985,"failureMessages":[],"location":{"line":721,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should have canvas context for risk evolution chart","status":"passed","title":"should have canvas context for risk evolution chart","duration":3.9477999999999156,"failureMessages":[],"location":{"line":726,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create risk distribution chart with bar type","status":"passed","title":"should create risk distribution chart with bar type","duration":2.570261000000073,"failureMessages":[],"location":{"line":731,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create anomaly detection chart with scatter type","status":"passed","title":"should create anomaly detection chart with scatter type","duration":2.396266000000196,"failureMessages":[],"location":{"line":745,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create crisis resilience chart with radar type","status":"passed","title":"should create crisis resilience chart with radar type","duration":2.4960430000000997,"failureMessages":[],"location":{"line":761,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Chart.js Visualizations"],"fullName":"Risk Dashboard Chart.js Visualizations should create risk evolution chart with line type","status":"passed","title":"should create risk evolution chart with line type","duration":2.5554839999999786,"failureMessages":[],"location":{"line":774,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should populate ethics concerns list with OL items","status":"passed","title":"should populate ethics concerns list with OL items","duration":3.0763590000001386,"failureMessages":[],"location":{"line":797,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should populate electoral risk list with OL items","status":"passed","title":"should populate electoral risk list with OL items","duration":2.951436000000058,"failureMessages":[],"location":{"line":812,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Top 10 Lists"],"fullName":"Risk Dashboard Top 10 Lists should sort ethics concerns by descending score","status":"passed","title":"should sort ethics concerns by descending score","duration":2.9760909999999967,"failureMessages":[],"location":{"line":825,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Heat Map Legend"],"fullName":"Risk Dashboard Heat Map Legend should render 4 legend items","status":"passed","title":"should render 4 legend items","duration":5.286736999999903,"failureMessages":[],"location":{"line":838,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should have data source link to CIA Platform","status":"passed","title":"should have data source link to CIA Platform","duration":3.235928000000058,"failureMessages":[],"location":{"line":869,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should have external link safety attributes","status":"passed","title":"should have external link safety attributes","duration":3.2236159999999927,"failureMessages":[],"location":{"line":875,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should display last updated timestamp placeholder","status":"passed","title":"should display last updated timestamp placeholder","duration":3.2278929999999946,"failureMessages":[],"location":{"line":880,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Risk Dashboard","Data Attribution"],"fullName":"Risk Dashboard Data Attribution should update timestamp with locale format","status":"passed","title":"should update timestamp with locale format","duration":17.853844999999865,"failureMessages":[],"location":{"line":885,"column":5},"meta":{},"tags":[]}],"startTime":1787953660371,"endTime":1787953661301.8538,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/risk-dashboard.test.js"},{"assertionResults":[{"ancestorTitles":["addDays"],"fullName":"addDays adds days to a date string","status":"passed","title":"adds days to a date string","duration":4.0711540000000355,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["addDays"],"fullName":"addDays handles year boundary","status":"passed","title":"handles year boundary","duration":0.5034329999999727,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["addDays"],"fullName":"addDays adds 0 days returns same date","status":"passed","title":"adds 0 days returns same date","duration":0.5055259999999748,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for quarter-ahead","status":"passed","title":"returns true for quarter-ahead","duration":0.3987070000000017,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for year-ahead","status":"passed","title":"returns true for year-ahead","duration":0.41139100000003737,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns true for election-cycle","status":"passed","title":"returns true for election-cycle","duration":0.49675999999999476,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for month-ahead","status":"passed","title":"returns false for month-ahead","duration":0.46575200000000905,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for week-ahead","status":"passed","title":"returns false for week-ahead","duration":0.35643699999997125,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isLongHorizon"],"fullName":"isLongHorizon returns false for morning cycles","status":"passed","title":"returns false for morning cycles","duration":0.5650789999999688,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd produces Markdown with correct header","status":"passed","title":"produces Markdown with correct header","duration":1.3592550000000188,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes predecessor manifest with days-since","status":"passed","title":"includes predecessor manifest with days-since","duration":0.7719050000000038,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes PIR genealogy table with correct columns","status":"passed","title":"includes PIR genealogy table with correct columns","duration":0.5851260000000025,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd stamps open PIRs with obsolescence date = targetDate + horizonDays","status":"passed","title":"stamps open PIRs with obsolescence date = targetDate + horizonDays","duration":0.6492959999999925,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks non-open PIRs with \"—\" for obsolescence date","status":"passed","title":"marks non-open PIRs with \"—\" for obsolescence date","duration":0.5653490000000261,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes section 3 with active PIR details","status":"passed","title":"includes section 3 with active PIR details","duration":0.7672059999999874,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd includes section 4 with archived PIRs","status":"passed","title":"includes section 4 with archived PIRs","duration":0.6361009999999965,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd uses 365 days for year-ahead cycle","status":"passed","title":"uses 365 days for year-ahead cycle","duration":0.5418249999999603,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd derives predecessor from output.inherited_from (not path.relative)","status":"passed","title":"derives predecessor from output.inherited_from (not path.relative)","duration":0.7046900000000278,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks all PIRs as inherited when sourcePirIds contains them","status":"passed","title":"marks all PIRs as inherited when sourcePirIds contains them","duration":0.7232339999999908,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["emitRollforwardMd"],"fullName":"emitRollforwardMd marks new PIRs as \"this run\" when not in sourcePirIds","status":"passed","title":"marks new PIRs as \"this run\" when not in sourcePirIds","duration":0.6599659999999972,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration auto-emits horizon-pir-rollforward.md for quarter-ahead cycle","status":"passed","title":"auto-emits horizon-pir-rollforward.md for quarter-ahead cycle","duration":2.8912650000000326,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration does NOT auto-emit for month-ahead cycle (horizonDays < 90)","status":"passed","title":"does NOT auto-emit for month-ahead cycle (horizonDays < 90)","duration":1.2447810000000459,"failureMessages":[],"location":{"line":362,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration emits when --emit-rollforward-md flag is used even for non-long-horizon","status":"passed","title":"emits when --emit-rollforward-md flag is used even for non-long-horizon","duration":1.265260000000012,"failureMessages":[],"location":{"line":382,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration idempotency — re-running produces identical output","status":"passed","title":"idempotency — re-running produces identical output","duration":1.4808729999999741,"failureMessages":[],"location":{"line":402,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain — rollforward-md integration"],"fullName":"runMain — rollforward-md integration auto-emits for election-cycle","status":"passed","title":"auto-emits for election-cycle","duration":1.4236569999999915,"failureMessages":[],"location":{"line":433,"column":3},"meta":{},"tags":[]}],"startTime":1787953784750,"endTime":1787953784774.4236,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/roll-forward-pirs.rollforward-md.test.ts"},{"assertionResults":[{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml escapes the five XML metacharacters","status":"passed","title":"escapes the five XML metacharacters","duration":3.662286999999992,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml preserves valid pre-encoded numeric, hex, and named entities","status":"passed","title":"preserves valid pre-encoded numeric, hex, and named entities","duration":0.5732230000000413,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml escapes a stray ampersand in plain prose like \"R&D\"","status":"passed","title":"escapes a stray ampersand in plain prose like \"R&D\"","duration":0.439803999999981,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/escape.ts — escapeXml"],"fullName":"rss/escape.ts — escapeXml uses XML-canonical ' for apostrophes (NOT HTML ')","status":"passed","title":"uses XML-canonical ' for apostrophes (NOT HTML ')","duration":0.41192100000000664,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode maps `no` → `nb`","status":"passed","title":"maps `no` → `nb`","duration":0.43432300000000623,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes en through unchanged","status":"passed","title":"passes en through unchanged","duration":0.41178100000001905,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes sv through unchanged","status":"passed","title":"passes sv through unchanged","duration":0.31771500000002106,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes de through unchanged","status":"passed","title":"passes de through unchanged","duration":0.37176600000003646,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes ja through unchanged","status":"passed","title":"passes ja through unchanged","duration":0.35324100000002545,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/hreflang.ts — hreflangCode"],"fullName":"rss/hreflang.ts — hreflangCode passes zh through unchanged","status":"passed","title":"passes zh through unchanged","duration":0.2769079999999917,"failureMessages":[],"location":{"line":54,"column":42},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate parses a YYYY-MM-DD prefix as 12:00 UTC for determinism","status":"passed","title":"parses a YYYY-MM-DD prefix as 12:00 UTC for determinism","duration":0.6914449999999874,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate does not consult the filesystem when the filename has a date prefix","status":"passed","title":"does not consult the filesystem when the filename has a date prefix","duration":0.351257999999973,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate falls back to the fixed sentinel when stat fails AND no date prefix","status":"passed","title":"falls back to the fixed sentinel when stat fails AND no date prefix","duration":0.3999579999999696,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/pub-date.ts — stablePubDate"],"fullName":"rss/pub-date.ts — stablePubDate uses filesystem mtime when no date prefix but the file exists","status":"passed","title":"uses filesystem mtime when no date prefix but the file exists","duration":1.2015989999999874,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta returns sentinel defaults when the article file does not exist","status":"passed","title":"returns sentinel defaults when the article file does not exist","duration":0.7407969999999864,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta uses path.basename so the title falls back to the bare filename without .html","status":"passed","title":"uses path.basename so the title falls back to the bare filename without .html","duration":0.45067299999999477,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/article-meta.ts — extractArticleMeta"],"fullName":"rss/article-meta.ts — extractArticleMeta uses the absolute basename of a relative path too","status":"passed","title":"uses the absolute basename of a relative path too","duration":0.4999870000000328,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss returns true on a structurally valid feed","status":"passed","title":"returns true on a structurally valid feed","duration":0.7407870000000116,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the XML declaration is missing","status":"passed","title":"throws when the XML declaration is missing","duration":1.2310849999999505,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the RSS version is wrong or missing","status":"passed","title":"throws when the RSS version is wrong or missing","duration":0.46060200000005125,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when the channel envelope is missing","status":"passed","title":"throws when the channel envelope is missing","duration":0.5325970000000098,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when there are no items","status":"passed","title":"throws when there are no items","duration":0.4505829999999946,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss/validator.ts — validateRss"],"fullName":"rss/validator.ts — validateRss throws when item count and required-tag count diverge","status":"passed","title":"throws when item count and required-tag count diverge","duration":0.62120299999998,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]}],"startTime":1787953870631,"endTime":1787953870646.621,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rss-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["rss-watch"],"fullName":"rss-watch parses RSS items and builds PIR match signals","status":"passed","title":"parses RSS items and builds PIR match signals","duration":6.5081160000000295,"failureMessages":[],"location":{"line":6,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss-watch"],"fullName":"rss-watch returns PIR integration note in watch output","status":"passed","title":"returns PIR integration note in watch output","duration":2.074122999999986,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rss-watch"],"fullName":"rss-watch does not match dok_id prefixes against longer dok_ids","status":"passed","title":"does not match dok_id prefixes against longer dok_ids","duration":0.5937309999999911,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953934152,"endTime":1787953934161.5938,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/rss-watch.test.ts"},{"assertionResults":[{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem returns true on a successful write","status":"passed","title":"returns true on a successful write","duration":4.165168999999992,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem evicts oldest same-prefix entries on quota and retries","status":"passed","title":"evicts oldest same-prefix entries on quota and retries","duration":1.0819359999999847,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem returns false (silently) when payload still exceeds quota after eviction","status":"passed","title":"returns false (silently) when payload still exceeds quota after eviction","duration":0.6754839999999831,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["safeSetItem"],"fullName":"safeSetItem does NOT evict on SecurityError (storage disabled)","status":"passed","title":"does NOT evict on SecurityError (storage disabled)","duration":0.6019370000000208,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]}],"startTime":1787953905404,"endTime":1787953905410.602,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/safe-storage.test.ts"},{"assertionResults":[{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should use default config when no options provided","status":"passed","title":"should use default config when no options provided","duration":3.860638999999992,"failureMessages":[],"location":{"line":32,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should accept custom config","status":"passed","title":"should accept custom config","duration":0.5411129999999957,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","constructor"],"fullName":"SCBClient constructor should use defaults for missing config fields","status":"passed","title":"should use defaults for missing config fields","duration":0.5368249999999648,"failureMessages":[],"location":{"line":51,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should find domain by exact key","status":"passed","title":"should find domain by exact key","duration":1.2194839999999658,"failureMessages":[],"location":{"line":66,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should find domain case-insensitively","status":"passed","title":"should find domain case-insensitively","duration":0.4488309999999842,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","findDomain"],"fullName":"SCBClient findDomain should return undefined for unknown domain","status":"passed","title":"should return undefined for unknown domain","duration":0.5411629999999832,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getDomainsWithTables"],"fullName":"SCBClient getDomainsWithTables should return only domains with non-empty tables arrays","status":"passed","title":"should return only domains with non-empty tables arrays","duration":1.066096000000016,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getDomainsWithTables"],"fullName":"SCBClient getDomainsWithTables should not include domains without tables","status":"passed","title":"should not include domains without tables","duration":0.6795529999999985,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should return null for empty data points","status":"passed","title":"should return null for empty data points","duration":0.6716279999999983,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should build indicator from single data point","status":"passed","title":"should build indicator from single data point","duration":0.6079179999999837,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"up\" trend when latest > previous","status":"passed","title":"should compute \"up\" trend when latest > previous","duration":0.43996399999997493,"failureMessages":[],"location":{"line":132,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"down\" trend when latest < previous","status":"passed","title":"should compute \"down\" trend when latest < previous","duration":0.3473599999999806,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should compute \"stable\" trend when values are essentially equal","status":"passed","title":"should compute \"stable\" trend when values are essentially equal","duration":0.38857699999999795,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","buildIndicator"],"fullName":"SCBClient buildIndicator should use fallback unit when data point has empty unit","status":"passed","title":"should use fallback unit when data point has empty unit","duration":0.33089999999998554,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","searchTables"],"fullName":"SCBClient searchTables should return empty array on network failure","status":"passed","title":"should return empty array on network failure","duration":1.5606319999999982,"failureMessages":[],"location":{"line":174,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCBClient","getTableData"],"fullName":"SCBClient getTableData should return empty array on network failure","status":"passed","title":"should return empty array on network failure","duration":0.6181080000000065,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should contain 15 policy domains","status":"passed","title":"should contain 15 policy domains","duration":0.7947990000000118,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have unique domain names","status":"passed","title":"should have unique domain names","duration":0.46480999999999995,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should cover all expected domains","status":"passed","title":"should cover all expected domains","duration":1.1135150000000067,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have non-empty query for every domain","status":"passed","title":"should have non-empty query for every domain","duration":0.7231249999999818,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS should have at least one indicator per domain","status":"passed","title":"should have at least one indicator per domain","duration":0.8420869999999923,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS labour domain should have TAB5765 and TAB5616","status":"passed","title":"labour domain should have TAB5765 and TAB5616","duration":0.6221560000000181,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_DOMAINS"],"fullName":"SCB_DOMAINS migration domain should have TAB637","status":"passed","title":"migration domain should have TAB637","duration":0.5382469999999557,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getDefaultSCBClient"],"fullName":"getDefaultSCBClient should return an SCBClient instance","status":"passed","title":"should return an SCBClient instance","duration":0.60177699999997,"failureMessages":[],"location":{"line":251,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getDefaultSCBClient"],"fullName":"getDefaultSCBClient should return the same instance on repeated calls","status":"passed","title":"should return the same instance on repeated calls","duration":0.49269300000003113,"failureMessages":[],"location":{"line":256,"column":3},"meta":{},"tags":[]}],"startTime":1787953831435,"endTime":1787953831455.6018,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-client.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have 15 domain contexts","status":"passed","title":"should have 15 domain contexts","duration":4.604409999999973,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have unique domain names","status":"passed","title":"should have unique domain names","duration":0.6977959999999825,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have non-empty name and description for each context","status":"passed","title":"should have non-empty name and description for each context","duration":1.6025599999999827,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have at least one committee for each context","status":"passed","title":"should have at least one committee for each context","duration":0.7078750000000014,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS should have at least one indicator for each context","status":"passed","title":"should have at least one indicator for each context","duration":0.7752519999999663,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS labour domain should map to AU committee","status":"passed","title":"labour domain should map to AU committee","duration":0.8635669999999891,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS fiscal domain should map to FiU committee","status":"passed","title":"fiscal domain should map to FiU committee","duration":0.5787530000000061,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS justice domain should map to JuU committee","status":"passed","title":"justice domain should map to JuU committee","duration":0.5269270000000006,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS taxation domain should map to SkU committee","status":"passed","title":"taxation domain should map to SkU committee","duration":0.5608699999999658,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS culture domain should map to KrU committee","status":"passed","title":"culture domain should map to KrU committee","duration":0.621735000000001,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_INDICATOR_CONTEXTS"],"fullName":"SCB_INDICATOR_CONTEXTS governance domain should map to KU committee","status":"passed","title":"governance domain should map to KU committee","duration":0.49880300000000943,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS should have headings for all 14 languages","status":"passed","title":"should have headings for all 14 languages","duration":0.6535840000000235,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS should have all three section keys for each language","status":"passed","title":"should have all three section keys for each language","duration":1.3252509999999802,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS English headings should be in English","status":"passed","title":"English headings should be in English","duration":0.42629800000003115,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS Swedish headings should be in Swedish","status":"passed","title":"Swedish headings should be in Swedish","duration":0.4846469999999954,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB_SECTION_HEADINGS"],"fullName":"SCB_SECTION_HEADINGS all data source headings should reference SCB","status":"passed","title":"all data source headings should reference SCB","duration":0.6605969999999957,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return English heading for known section","status":"passed","title":"should return English heading for known section","duration":0.47003999999998314,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return Swedish heading","status":"passed","title":"should return Swedish heading","duration":0.4192950000000337,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should fallback to English for unknown language","status":"passed","title":"should fallback to English for unknown language","duration":0.4254669999999692,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBHeading"],"fullName":"getSCBHeading should return data source heading","status":"passed","title":"should return data source heading","duration":0.4357760000000326,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty array for empty query","status":"passed","title":"should return empty array for empty query","duration":1.1991949999999747,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty array for whitespace-only query","status":"passed","title":"should return empty array for whitespace-only query","duration":0.5540380000000482,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find labour domain by domain name","status":"passed","title":"should find labour domain by domain name","duration":0.657039999999995,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find by committee abbreviation (case-insensitive)","status":"passed","title":"should find by committee abbreviation (case-insensitive)","duration":0.5245820000000094,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find by indicator name","status":"passed","title":"should find by indicator name","duration":0.631512999999984,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should find fiscal domain by partial name","status":"passed","title":"should find fiscal domain by partial name","duration":0.692436999999984,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findRelevantSCBIndicators"],"fullName":"findRelevantSCBIndicators should return empty for non-matching query","status":"passed","title":"should return empty for non-matching query","duration":0.6120249999999601,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for FiU committee","status":"passed","title":"should find tables for FiU committee","duration":0.7516779999999699,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for AU committee","status":"passed","title":"should find tables for AU committee","duration":0.5190119999999752,"failureMessages":[],"location":{"line":214,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for SkU (taxation) committee","status":"passed","title":"should find tables for SkU (taxation) committee","duration":0.5840729999999894,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should find tables for KrU (cultural affairs) committee","status":"passed","title":"should find tables for KrU (cultural affairs) committee","duration":0.7545129999999745,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should be case-insensitive","status":"passed","title":"should be case-insensitive","duration":0.6355099999999538,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBTablesForCommittee"],"fullName":"getSCBTablesForCommittee should return empty array for unknown committee","status":"passed","title":"should return empty array for unknown committee","duration":0.59773899999999,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect SCB acronym","status":"passed","title":"should detect SCB acronym","duration":0.7320100000000025,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Statistiska centralbyrån","status":"passed","title":"should detect Statistiska centralbyrån","duration":0.674712999999997,"failureMessages":[],"location":{"line":249,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Statistics Sweden","status":"passed","title":"should detect Statistics Sweden","duration":0.5942420000000084,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect SCB table IDs","status":"passed","title":"should detect SCB table IDs","duration":0.7720549999999662,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect Swedish statistical terms","status":"passed","title":"should detect Swedish statistical terms","duration":0.6417120000000409,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should detect officiell statistik","status":"passed","title":"should detect officiell statistik","duration":0.5618119999999749,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should return false for unrelated content","status":"passed","title":"should return false for unrelated content","duration":0.6399069999999938,"failureMessages":[],"location":{"line":269,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasSCBContext"],"fullName":"hasSCBContext should return false for empty string","status":"passed","title":"should return false for empty string","duration":0.6024479999999812,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should return only domains with table IDs","status":"passed","title":"should return only domains with table IDs","duration":1.0467899999999872,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should include domain and query for each result","status":"passed","title":"should include domain and query for each result","duration":1.112653000000023,"failureMessages":[],"location":{"line":291,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should include labour domain with TAB5765","status":"passed","title":"should include labour domain with TAB5765","duration":0.7807920000000195,"failureMessages":[],"location":{"line":299,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getSCBQueryParams"],"fullName":"getSCBQueryParams should not include domains without tables (defence, healthcare, transport, governance)","status":"passed","title":"should not include domains without tables (defence, healthcare, transport, governance)","duration":0.9669000000000096,"failureMessages":[],"location":{"line":306,"column":3},"meta":{},"tags":[]}],"startTime":1787953824317,"endTime":1787953824353.9668,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-context.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers exposes KPI, AKU, household-economy and fuel-price presets","status":"passed","title":"exposes KPI, AKU, household-economy and fuel-price presets","duration":4.494055000000003,"failureMessages":[],"location":{"line":18,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers parses command flags and JSON value codes","status":"passed","title":"parses command flags and JSON value codes","duration":0.9373760000000289,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers builds a periods fallback value code","status":"passed","title":"builds a periods fallback value code","duration":0.40357599999998683,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers throws for invalid CLI input","status":"passed","title":"throws for invalid CLI input","duration":1.6710390000000075,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB fetch CLI helpers"],"fullName":"SCB fetch CLI helpers emits SCB provenance and fail-soft no-data payload on outage","status":"passed","title":"emits SCB provenance and fail-soft no-data payload on outage","duration":1.4303280000000314,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953925625,"endTime":1787953925634.4304,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration copilot-mcp.json should include scb MCP server","status":"passed","title":"copilot-mcp.json should include scb MCP server","duration":5.054424999999981,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration copilot-mcp.json should include world-bank MCP server","status":"passed","title":"copilot-mcp.json should include world-bank MCP server","duration":0.9845339999999965,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should configure scb MCP server","status":"passed","title":"news-committee-reports.md should configure scb MCP server","duration":0.6835000000000377,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should configure world-bank MCP server","status":"passed","title":"news-committee-reports.md should configure world-bank MCP server","duration":0.6126470000000381,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should allow api.scb.se in network","status":"passed","title":"news-committee-reports.md should allow api.scb.se in network","duration":0.898542999999961,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should allow api.worldbank.org in network","status":"passed","title":"news-committee-reports.md should allow api.worldbank.org in network","duration":0.6779700000000162,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should include api.scb.se in safe-outputs","status":"passed","title":"news-committee-reports.md should include api.scb.se in safe-outputs","duration":0.7586810000000241,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-committee-reports.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-committee-reports.md should include api.worldbank.org in safe-outputs","duration":0.6610680000000002,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should configure scb MCP server","status":"passed","title":"news-evening-analysis.md should configure scb MCP server","duration":0.5999340000000188,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should configure world-bank MCP server","status":"passed","title":"news-evening-analysis.md should configure world-bank MCP server","duration":0.6020979999999554,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should allow api.scb.se in network","status":"passed","title":"news-evening-analysis.md should allow api.scb.se in network","duration":1.0641120000000228,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should allow api.worldbank.org in network","status":"passed","title":"news-evening-analysis.md should allow api.worldbank.org in network","duration":0.6433749999999918,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should include api.scb.se in safe-outputs","status":"passed","title":"news-evening-analysis.md should include api.scb.se in safe-outputs","duration":0.6223960000000375,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-evening-analysis.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-evening-analysis.md should include api.worldbank.org in safe-outputs","duration":0.547676000000024,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should configure scb MCP server","status":"passed","title":"news-month-ahead.md should configure scb MCP server","duration":0.5221480000000156,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should configure world-bank MCP server","status":"passed","title":"news-month-ahead.md should configure world-bank MCP server","duration":0.478336000000013,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should allow api.scb.se in network","status":"passed","title":"news-month-ahead.md should allow api.scb.se in network","duration":0.6055240000000026,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should allow api.worldbank.org in network","status":"passed","title":"news-month-ahead.md should allow api.worldbank.org in network","duration":0.6530329999999935,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should include api.scb.se in safe-outputs","status":"passed","title":"news-month-ahead.md should include api.scb.se in safe-outputs","duration":0.5891829999999914,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-month-ahead.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-month-ahead.md should include api.worldbank.org in safe-outputs","duration":0.627935999999977,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should configure scb MCP server","status":"passed","title":"news-monthly-review.md should configure scb MCP server","duration":0.5508820000000014,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should configure world-bank MCP server","status":"passed","title":"news-monthly-review.md should configure world-bank MCP server","duration":0.512990000000002,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should allow api.scb.se in network","status":"passed","title":"news-monthly-review.md should allow api.scb.se in network","duration":0.6274249999999597,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should allow api.worldbank.org in network","status":"passed","title":"news-monthly-review.md should allow api.worldbank.org in network","duration":0.6252610000000232,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should include api.scb.se in safe-outputs","status":"passed","title":"news-monthly-review.md should include api.scb.se in safe-outputs","duration":0.6400480000000357,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-monthly-review.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-monthly-review.md should include api.worldbank.org in safe-outputs","duration":0.6513089999999693,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should configure scb MCP server","status":"passed","title":"news-motions.md should configure scb MCP server","duration":0.5564519999999789,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should configure world-bank MCP server","status":"passed","title":"news-motions.md should configure world-bank MCP server","duration":0.5985610000000179,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should allow api.scb.se in network","status":"passed","title":"news-motions.md should allow api.scb.se in network","duration":0.6780190000000061,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should allow api.worldbank.org in network","status":"passed","title":"news-motions.md should allow api.worldbank.org in network","duration":0.6964839999999981,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should include api.scb.se in safe-outputs","status":"passed","title":"news-motions.md should include api.scb.se in safe-outputs","duration":0.7004320000000348,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-motions.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-motions.md should include api.worldbank.org in safe-outputs","duration":0.7563159999999698,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should configure scb MCP server","status":"passed","title":"news-propositions.md should configure scb MCP server","duration":0.5636360000000309,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should configure world-bank MCP server","status":"passed","title":"news-propositions.md should configure world-bank MCP server","duration":2.6650300000000016,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should allow api.scb.se in network","status":"passed","title":"news-propositions.md should allow api.scb.se in network","duration":0.5688760000000457,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should allow api.worldbank.org in network","status":"passed","title":"news-propositions.md should allow api.worldbank.org in network","duration":0.5236309999999662,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should include api.scb.se in safe-outputs","status":"passed","title":"news-propositions.md should include api.scb.se in safe-outputs","duration":0.46885800000001154,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-propositions.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-propositions.md should include api.worldbank.org in safe-outputs","duration":0.5217470000000048,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should configure scb MCP server","status":"passed","title":"news-realtime-monitor.md should configure scb MCP server","duration":0.44795900000002575,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should configure world-bank MCP server","status":"passed","title":"news-realtime-monitor.md should configure world-bank MCP server","duration":0.47181399999999485,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should allow api.scb.se in network","status":"passed","title":"news-realtime-monitor.md should allow api.scb.se in network","duration":0.5160469999999577,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should allow api.worldbank.org in network","status":"passed","title":"news-realtime-monitor.md should allow api.worldbank.org in network","duration":0.7479810000000384,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should include api.scb.se in safe-outputs","status":"passed","title":"news-realtime-monitor.md should include api.scb.se in safe-outputs","duration":0.5775520000000256,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-realtime-monitor.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-realtime-monitor.md should include api.worldbank.org in safe-outputs","duration":0.5159360000000106,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should configure scb MCP server","status":"passed","title":"news-week-ahead.md should configure scb MCP server","duration":0.5061269999999922,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should configure world-bank MCP server","status":"passed","title":"news-week-ahead.md should configure world-bank MCP server","duration":0.4914999999999736,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should allow api.scb.se in network","status":"passed","title":"news-week-ahead.md should allow api.scb.se in network","duration":0.5617419999999811,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should allow api.worldbank.org in network","status":"passed","title":"news-week-ahead.md should allow api.worldbank.org in network","duration":0.5533959999999638,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should include api.scb.se in safe-outputs","status":"passed","title":"news-week-ahead.md should include api.scb.se in safe-outputs","duration":0.7169120000000362,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-week-ahead.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-week-ahead.md should include api.worldbank.org in safe-outputs","duration":0.979865000000018,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should configure scb MCP server","status":"passed","title":"news-weekly-review.md should configure scb MCP server","duration":0.749623999999983,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should configure world-bank MCP server","status":"passed","title":"news-weekly-review.md should configure world-bank MCP server","duration":0.7428199999999947,"failureMessages":[],"location":{"line":123,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should allow api.scb.se in network","status":"passed","title":"news-weekly-review.md should allow api.scb.se in network","duration":0.8462649999999599,"failureMessages":[],"location":{"line":131,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should allow api.worldbank.org in network","status":"passed","title":"news-weekly-review.md should allow api.worldbank.org in network","duration":0.838009999999997,"failureMessages":[],"location":{"line":141,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should include api.scb.se in safe-outputs","status":"passed","title":"news-weekly-review.md should include api.scb.se in safe-outputs","duration":0.9100540000000024,"failureMessages":[],"location":{"line":150,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB MCP Server Configuration"],"fullName":"SCB MCP Server Configuration news-weekly-review.md should include api.worldbank.org in safe-outputs","status":"passed","title":"news-weekly-review.md should include api.worldbank.org in safe-outputs","duration":1.0216629999999896,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-evening-analysis.md should document SCB enrichment as optional","status":"passed","title":"news-evening-analysis.md should document SCB enrichment as optional","duration":0.9094430000000102,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-evening-analysis.md should instruct try/catch for SCB calls","status":"passed","title":"news-evening-analysis.md should instruct try/catch for SCB calls","duration":2.523454999999956,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-monthly-review.md should document SCB enrichment as optional","status":"passed","title":"news-monthly-review.md should document SCB enrichment as optional","duration":0.9135110000000282,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-monthly-review.md should instruct try/catch for SCB calls","status":"passed","title":"news-monthly-review.md should instruct try/catch for SCB calls","duration":1.8783169999999814,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-weekly-review.md should document SCB enrichment as optional","status":"passed","title":"news-weekly-review.md should document SCB enrichment as optional","duration":0.8750989999999774,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-weekly-review.md should instruct try/catch for SCB calls","status":"passed","title":"news-weekly-review.md should instruct try/catch for SCB calls","duration":2.069033999999988,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-propositions.md should document SCB enrichment as optional","status":"passed","title":"news-propositions.md should document SCB enrichment as optional","duration":0.9289400000000114,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-propositions.md should instruct try/catch for SCB calls","status":"passed","title":"news-propositions.md should instruct try/catch for SCB calls","duration":1.9241830000000277,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-motions.md should document SCB enrichment as optional","status":"passed","title":"news-motions.md should document SCB enrichment as optional","duration":0.9093720000000189,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Enrichment Instructions in Key Workflows"],"fullName":"SCB Enrichment Instructions in Key Workflows news-motions.md should instruct try/catch for SCB calls","status":"passed","title":"news-motions.md should instruct try/catch for SCB calls","duration":1.8920630000000074,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["SCB Data Types"],"fullName":"SCB Data Types types.ts should export SCBContext and SCBIndicator","status":"passed","title":"types.ts should export SCBContext and SCBIndicator","duration":1.6202639999999633,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SCB Data Types"],"fullName":"SCB Data Types ArticleContentData should include scbContext field","status":"passed","title":"ArticleContentData should include scbContext field","duration":3.5342579999999657,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]}],"startTime":1787953831907,"endTime":1787953831970.5342,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/scb-mcp-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle returns a non-empty localised title for every mapped slug × language","status":"passed","title":"returns a non-empty localised title for every mapped slug × language","duration":40.296100999999965,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle keeps English titles byte-identical to the journalist body headings","status":"passed","title":"keeps English titles byte-identical to the journalist body headings","duration":0.8627549999999928,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle reuses the vetted artifact translation for delegated sections","status":"passed","title":"reuses the vetted artifact translation for delegated sections","duration":0.3844100000000026,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle localises journalist-framed and Deep Dive sections","status":"passed","title":"localises journalist-framed and Deep Dive sections","duration":0.3409189999999853,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle localises recurring journalist topical sections (Korean regression)","status":"passed","title":"localises recurring journalist topical sections (Korean regression)","duration":0.5245519999999715,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle reuses the vetted artifact translation for the stakeholder-map slug","status":"passed","title":"reuses the vetted artifact translation for the stakeholder-map slug","duration":0.38703499999996893,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["localizedSectionTitle"],"fullName":"localizedSectionTitle returns undefined for slugs without a curated localisation","status":"passed","title":"returns undefined for slugs without a curated localisation","duration":0.4612329999999929,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]}],"startTime":1787953856312,"endTime":1787953856355.4612,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/section-title-i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages declares every supported language in LANG_TITLE_WINDOWS","status":"passed","title":"declares every supported language in LANG_TITLE_WINDOWS","duration":4.141754999999989,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages declares every supported language in LANG_DESCRIPTION_WINDOWS","status":"passed","title":"declares every supported language in LANG_DESCRIPTION_WINDOWS","duration":1.0225750000000176,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for en (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for en (55-70 / 140-200)","duration":1.2908459999999877,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for sv (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for sv (55-70 / 140-200)","duration":0.43969300000003386,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for da (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for da (55-70 / 140-200)","duration":0.5302530000000161,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for no (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for no (55-70 / 140-200)","duration":0.49886500000002343,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for fi (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for fi (55-70 / 140-200)","duration":0.6164740000000393,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for de (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for de (55-70 / 140-200)","duration":0.42825099999998884,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for fr (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for fr (55-70 / 140-200)","duration":0.5781419999999571,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for es (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for es (55-70 / 140-200)","duration":0.37767800000000307,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the Latin LTR contract for nl (55-70 / 140-200)","status":"passed","title":"honours the Latin LTR contract for nl (55-70 / 140-200)","duration":0.6572310000000243,"failureMessages":[],"location":{"line":77,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the RTL contract for ar (45-60 / 120-170)","status":"passed","title":"honours the RTL contract for ar (45-60 / 120-170)","duration":0.4393620000000169,"failureMessages":[],"location":{"line":82,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the RTL contract for he (45-60 / 120-170)","status":"passed","title":"honours the RTL contract for he (45-60 / 120-170)","duration":0.4707910000000197,"failureMessages":[],"location":{"line":82,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for ja (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for ja (30-45 / 70-120)","duration":0.5104550000000359,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for ko (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for ko (30-45 / 70-120)","duration":0.47859600000003866,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["serp-budgets — contract parity for all 14 languages"],"fullName":"serp-budgets — contract parity for all 14 languages honours the CJK contract for zh (30-45 / 70-120)","status":"passed","title":"honours the CJK contract for zh (30-45 / 70-120)","duration":0.37637399999999843,"failureMessages":[],"location":{"line":87,"column":15},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises zh-CN → zh","status":"passed","title":"normalises zh-CN → zh","duration":0.6484050000000252,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises zh-Hans-CN → zh","status":"passed","title":"normalises zh-Hans-CN → zh","duration":0.41040900000001557,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises JA → ja","status":"passed","title":"normalises JA → ja","duration":0.3890480000000025,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises Ar → ar","status":"passed","title":"normalises Ar → ar","duration":0.3503160000000207,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises de → de","status":"passed","title":"normalises de → de","duration":0.5541479999999979,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises nb-NO → nb","status":"passed","title":"normalises nb-NO → nb","duration":0.38987000000003036,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag normalises en_US → en","status":"passed","title":"normalises en_US → en","duration":0.6416419999999903,"failureMessages":[],"location":{"line":102,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["normalisePrimaryLangSubtag — BCP-47 → primary subtag"],"fullName":"normalisePrimaryLangSubtag — BCP-47 → primary subtag returns null for null / undefined / whitespace","status":"passed","title":"returns null for null / undefined / whitespace","duration":0.5855169999999816,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["titleWindowForLanguage / descriptionWindowForLanguage — fallback"],"fullName":"titleWindowForLanguage / descriptionWindowForLanguage — fallback falls back to EN window for null / undefined / unknown lang","status":"passed","title":"falls back to EN window for null / undefined / unknown lang","duration":0.726269000000002,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["titleWindowForLanguage / descriptionWindowForLanguage — fallback"],"fullName":"titleWindowForLanguage / descriptionWindowForLanguage — fallback resolves BCP-47 region variants to the primary-subtag window","status":"passed","title":"resolves BCP-47 region variants to the primary-subtag window","duration":0.5144629999999779,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=en","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=en","duration":4.586506999999983,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=sv","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=sv","duration":0.40787400000004936,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=da","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=da","duration":0.3483019999999897,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=no","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=no","duration":0.3704840000000331,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=fi","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=fi","duration":0.3652139999999804,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=de","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=de","duration":0.3462279999999964,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=fr","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=fr","duration":2.2168910000000324,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=es","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=es","duration":0.4017420000000129,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=nl","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=nl","duration":0.3875859999999989,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ar","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ar","duration":0.5333380000000147,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=he","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=he","duration":0.571610000000021,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ja","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ja","duration":0.47690299999999297,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=ko","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=ko","duration":0.5350819999999885,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax clamps a long H1 to ≤ hardMax for lang=zh","status":"passed","title":"clamps a long H1 to ≤ hardMax for lang=zh","duration":0.5381579999999531,"failureMessages":[],"location":{"line":156,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax CJK ja: 50-glyph H1 clamps to ≤ 45 glyphs and drops brand suffix","status":"passed","title":"CJK ja: 50-glyph H1 clamps to ≤ 45 glyphs and drops brand suffix","duration":0.8307050000000231,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax RTL ar: a 100-char Arabic H1 clamps to ≤ 60 chars","status":"passed","title":"RTL ar: a 100-char Arabic H1 clamps to ≤ 60 chars","duration":0.8334900000000403,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoTitle — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoTitle — 14-language matrix never overshoots hardMax Latin LTR: existing 70-char SERP budget unchanged for EN","status":"passed","title":"Latin LTR: existing 70-char SERP budget unchanged for EN","duration":0.5795049999999833,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=en","status":"passed","title":"clamps a long description to ≤ hardMax for lang=en","duration":1.2025409999999965,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=sv","status":"passed","title":"clamps a long description to ≤ hardMax for lang=sv","duration":0.610102999999981,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=da","status":"passed","title":"clamps a long description to ≤ hardMax for lang=da","duration":0.6517299999999864,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=no","status":"passed","title":"clamps a long description to ≤ hardMax for lang=no","duration":0.6581719999999791,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=fi","status":"passed","title":"clamps a long description to ≤ hardMax for lang=fi","duration":0.6295390000000225,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=de","status":"passed","title":"clamps a long description to ≤ hardMax for lang=de","duration":0.7165620000000104,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=fr","status":"passed","title":"clamps a long description to ≤ hardMax for lang=fr","duration":0.6889400000000023,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=es","status":"passed","title":"clamps a long description to ≤ hardMax for lang=es","duration":0.654184999999984,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=nl","status":"passed","title":"clamps a long description to ≤ hardMax for lang=nl","duration":0.7277529999999501,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ar","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ar","duration":1.2853769999999827,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=he","status":"passed","title":"clamps a long description to ≤ hardMax for lang=he","duration":0.8011599999999817,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ja","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ja","duration":0.7965829999999983,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=ko","status":"passed","title":"clamps a long description to ≤ hardMax for lang=ko","duration":0.7921729999999911,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax clamps a long description to ≤ hardMax for lang=zh","status":"passed","title":"clamps a long description to ≤ hardMax for lang=zh","duration":0.7901089999999726,"failureMessages":[],"location":{"line":238,"column":27},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax falls back to EN 200-char budget when lang is omitted","status":"passed","title":"falls back to EN 200-char budget when lang is omitted","duration":0.9889120000000275,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax synthesises a non-empty description from the title when description is empty","status":"passed","title":"synthesises a non-empty description from the title when description is empty","duration":1.0737600000000498,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildSeoDescription — 14-language matrix never overshoots hardMax"],"fullName":"buildSeoDescription — 14-language matrix never overshoots hardMax synthesises from the localized article-type label when both description and title are empty","status":"passed","title":"synthesises from the localized article-type label when both description and title are empty","duration":0.896959000000038,"failureMessages":[],"location":{"line":285,"column":3},"meta":{},"tags":[]}],"startTime":1787953736137,"endTime":1787953736184.897,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/seo-budget-windows.test.ts"},{"assertionResults":[{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 9 Latin LTR languages with 140-200 windows","status":"passed","title":"declares the 9 Latin LTR languages with 140-200 windows","duration":4.814464999999984,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 2 RTL languages (ar, he) with 120-170 windows","status":"passed","title":"declares the 2 RTL languages (ar, he) with 120-170 windows","duration":0.6239489999999819,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares the 3 CJK languages (ja, ko, zh) with 70-120 windows","status":"passed","title":"declares the 3 CJK languages (ja, ko, zh) with 70-120 windows","duration":0.6020269999999641,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4)"],"fullName":"LANG_DESCRIPTION_WINDOWS — contract parity (seo-metadata-contract.md §4) declares exactly 14 languages (the supported set)","status":"passed","title":"declares exactly 14 languages (the supported set)","duration":0.5598679999999945,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage returns the canonical window for known languages","status":"passed","title":"returns the canonical window for known languages","duration":0.7020650000000046,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage falls back to the EN window for unknown languages","status":"passed","title":"falls back to the EN window for unknown languages","duration":0.699610000000007,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage is case-insensitive — upper / mixed-case BCP-47 codes resolve to the canonical window","status":"passed","title":"is case-insensitive — upper / mixed-case BCP-47 codes resolve to the canonical window","duration":0.7002720000000409,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["descriptionWindowForLanguage"],"fullName":"descriptionWindowForLanguage handles BCP-47 region subtags (zh-CN, zh-TW, nb-NO, …) by collapsing to the primary subtag","status":"passed","title":"handles BCP-47 region subtags (zh-CN, zh-TW, nb-NO, …) by collapsing to the primary subtag","duration":0.5775709999999776,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Aggregator barrel — W2 description-window API is re-exported"],"fullName":"Aggregator barrel — W2 description-window API is re-exported exposes LANG_DESCRIPTION_WINDOWS and descriptionWindowForLanguage from the aggregator barrel","status":"passed","title":"exposes LANG_DESCRIPTION_WINDOWS and descriptionWindowForLanguage from the aggregator barrel","duration":57.99179299999997,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates a CJK description within the 70-120 char window","status":"passed","title":"truncates a CJK description within the 70-120 char window","duration":0.9326159999999959,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates an RTL (Arabic) description within the 120-170 char window","status":"passed","title":"truncates an RTL (Arabic) description within the 120-170 char window","duration":0.883685000000014,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["truncateToSentenceBoundary — per-language window propagation"],"fullName":"truncateToSentenceBoundary — per-language window propagation truncates a Latin LTR description within the 140-200 char window (unchanged)","status":"passed","title":"truncates a Latin LTR description within the 140-200 char window (unchanged)","duration":0.8518649999999752,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the CJK 70-120 window when lang=\"ja\"","status":"passed","title":"honors the CJK 70-120 window when lang=\"ja\"","duration":25.752087999999958,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window falls back to the EN 140-200 window when lang is omitted (back-compat)","status":"passed","title":"falls back to the EN 140-200 window when lang is omitted (back-compat)","duration":10.069023000000016,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the RTL 120-170 window when lang=\"ar\"","status":"passed","title":"honors the RTL 120-170 window when lang=\"ar\"","duration":6.167467999999985,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLocalizedBriefSeo — per-language description window"],"fullName":"extractLocalizedBriefSeo — per-language description window honors the Latin LTR 140-200 window when lang=\"de\" (unchanged behaviour)","status":"passed","title":"honors the Latin LTR 140-200 window when lang=\"de\" (unchanged behaviour)","duration":16.091088000000013,"failureMessages":[],"location":{"line":206,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection flags a 5-name comma-separated MP roster","status":"passed","title":"flags a 5-name comma-separated MP roster","duration":0.9915869999999813,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection flags a roster with parenthetical party suffixes","status":"passed","title":"flags a roster with parenthetical party suffixes","duration":0.4885550000000194,"failureMessages":[],"location":{"line":242,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a prose paragraph with a single comma","status":"passed","title":"does NOT flag a prose paragraph with a single comma","duration":0.4163389999999936,"failureMessages":[],"location":{"line":250,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a list of 2 names (below threshold)","status":"passed","title":"does NOT flag a list of 2 names (below threshold)","duration":0.47111199999994824,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection does NOT flag a list that contains a sentence terminator early","status":"passed","title":"does NOT flag a list that contains a sentence terminator early","duration":0.5893539999999575,"failureMessages":[],"location":{"line":264,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isEntityRosterParagraph — bare name-list detection"],"fullName":"isEntityRosterParagraph — bare name-list detection readFirstParagraph skips an entity-roster lead in favour of the next prose paragraph","status":"passed","title":"readFirstParagraph skips an entity-roster lead in favour of the next prose paragraph","duration":4.030977999999891,"failureMessages":[],"location":{"line":272,"column":3},"meta":{},"tags":[]}],"startTime":1787953792010,"endTime":1787953792146.031,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/seo-description-windows.test.ts"},{"assertionResults":[{"ancestorTitles":["service worker (public/sw.js)","source integrity"],"fullName":"service worker (public/sw.js) source integrity public/sw.js retains the __BUILD_ID__ placeholder for the build plugin","status":"passed","title":"public/sw.js retains the __BUILD_ID__ placeholder for the build plugin","duration":4.969985000000008,"failureMessages":[],"location":{"line":194,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration registers install, activate, fetch, and message handlers","status":"passed","title":"registers install, activate, fetch, and message handlers","duration":1.284604999999999,"failureMessages":[],"location":{"line":200,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration install handler calls skipWaiting (no synchronous pre-cache work)","status":"passed","title":"install handler calls skipWaiting (no synchronous pre-cache work)","duration":1.4624290000000428,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration message handler calls skipWaiting on { type: \"SKIP_WAITING\" }","status":"passed","title":"message handler calls skipWaiting on { type: \"SKIP_WAITING\" }","duration":1.0914129999999886,"failureMessages":[],"location":{"line":214,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","handler registration"],"fullName":"service worker (public/sw.js) handler registration message handler ignores unrelated messages","status":"passed","title":"message handler ignores unrelated messages","duration":1.357531999999992,"failureMessages":[],"location":{"line":220,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation keeps current build HTML cache and cia-data; evicts every other cache","status":"passed","title":"keeps current build HTML cache and cia-data; evicts every other cache","duration":2.3624530000000163,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation different BUILD_ID yields different HTML cache name","status":"passed","title":"different BUILD_ID yields different HTML cache name","duration":3.3548720000000003,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","activate: per-build HTML cache rotation"],"fullName":"service worker (public/sw.js) activate: per-build HTML cache rotation build N activate evicts build N-1 HTML cache","status":"passed","title":"build N activate evicts build N-1 HTML cache","duration":2.9756509999999707,"failureMessages":[],"location":{"line":265,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing non-GET requests are not intercepted","status":"passed","title":"non-GET requests are not intercepted","duration":2.081075999999996,"failureMessages":[],"location":{"line":294,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing CSS requests are NOT intercepted (HTTP cache + must-revalidate handle them)","status":"passed","title":"CSS requests are NOT intercepted (HTTP cache + must-revalidate handle them)","duration":1.2795550000000162,"failureMessages":[],"location":{"line":303,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing script/image/font requests bypass the SW","status":"passed","title":"script/image/font requests bypass the SW","duration":1.3513000000000375,"failureMessages":[],"location":{"line":314,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","fetch routing"],"fullName":"service worker (public/sw.js) fetch routing navigation requests with mode=\"navigate\" are handled even without destination=document","status":"passed","title":"navigation requests with mode=\"navigate\" are handled even without destination=document","duration":2.8194990000000075,"failureMessages":[],"location":{"line":327,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate populates the cache on first fetch","status":"passed","title":"populates the cache on first fetch","duration":4.98414200000002,"failureMessages":[],"location":{"line":341,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate returns cached response immediately on second fetch","status":"passed","title":"returns cached response immediately on second fetch","duration":3.455209000000025,"failureMessages":[],"location":{"line":366,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","CIA data: stale-while-revalidate"],"fullName":"service worker (public/sw.js) CIA data: stale-while-revalidate falls back to cache when network fails","status":"passed","title":"falls back to cache when network fails","duration":2.4089099999999917,"failureMessages":[],"location":{"line":386,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback serves the network response when available and populates the cache","status":"passed","title":"serves the network response when available and populates the cache","duration":6.777169000000015,"failureMessages":[],"location":{"line":414,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback returns latest network response even when a cached copy exists (network-first)","status":"passed","title":"returns latest network response even when a cached copy exists (network-first)","duration":6.741401999999994,"failureMessages":[],"location":{"line":439,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback falls back to the cached response when the network throws (offline)","status":"passed","title":"falls back to the cached response when the network throws (offline)","duration":5.553217000000018,"failureMessages":[],"location":{"line":461,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback returns an inline 503 offline page when both network and cache fail","status":"passed","title":"returns an inline 503 offline page when both network and cache fail","duration":6.847320000000025,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["service worker (public/sw.js)","HTML: network-first with offline fallback"],"fullName":"service worker (public/sw.js) HTML: network-first with offline fallback falls back to cache when the network hangs longer than the timeout","status":"passed","title":"falls back to cache when the network hangs longer than the timeout","duration":5.22218799999996,"failureMessages":[],"location":{"line":504,"column":5},"meta":{},"tags":[]}],"startTime":1787953682823,"endTime":1787953682892.2222,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/service-worker.test.ts"},{"assertionResults":[{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should generate valid XML string","status":"passed","title":"should generate valid XML string","duration":3.6591000000000804,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should be valid XML","status":"passed","title":"should be valid XML","duration":40.48187000000007,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should have URL entries","status":"passed","title":"should have URL entries","duration":3.3404839999999467,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Basic Structure"],"fullName":"Sitemap Generation Basic Structure should have hreflang support","status":"passed","title":"should have hreflang support","duration":0.4955080000000862,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include main index page","status":"passed","title":"should include main index page","duration":0.4598009999999704,"failureMessages":[],"location":{"line":63,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include all 14 language index pages","status":"passed","title":"should include all 14 language index pages","duration":0.9006060000000389,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Main Pages Coverage"],"fullName":"Sitemap Generation Main Pages Coverage should include politician dashboard","status":"passed","title":"should include politician dashboard","duration":0.5919580000000906,"failureMessages":[],"location":{"line":77,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Dashboard Pages Coverage"],"fullName":"Sitemap Generation Dashboard Pages Coverage should include English dashboard","status":"passed","title":"should include English dashboard","duration":0.3462090000000444,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Dashboard Pages Coverage"],"fullName":"Sitemap Generation Dashboard Pages Coverage should include dashboard pages for all languages","status":"passed","title":"should include dashboard pages for all languages","duration":3.2649829999999156,"failureMessages":[],"location":{"line":87,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include news index page","status":"passed","title":"should include news index page","duration":0.39907800000003135,"failureMessages":[],"location":{"line":109,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include news articles","status":"passed","title":"should include news articles","duration":3.2926049999999805,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include articles in multiple languages","status":"passed","title":"should include articles in multiple languages","duration":1.250069999999937,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","News Articles Coverage"],"fullName":"Sitemap Generation News Articles Coverage should include hreflang alternates for news articles","status":"passed","title":"should include hreflang alternates for news articles","duration":0.44541400000002795,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include API index page if api directory exists","status":"passed","title":"should include API index page if api directory exists","duration":0.34913299999993797,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include API documentation files if api directory exists","status":"passed","title":"should include API documentation files if api directory exists","duration":0.39174400000001697,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include module documentation if api directory exists","status":"passed","title":"should include module documentation if api directory exists","duration":0.41329399999995076,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","API Documentation Coverage"],"fullName":"Sitemap Generation API Documentation Coverage should include script documentation if api directory exists","status":"passed","title":"should include script documentation if api directory exists","duration":0.3930960000000141,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Generated Documentation (docs/) Coverage"],"fullName":"Sitemap Generation Generated Documentation (docs/) Coverage should include docs index page if docs directory exists","status":"passed","title":"should include docs index page if docs directory exists","duration":5.182753000000048,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Generated Documentation (docs/) Coverage"],"fullName":"Sitemap Generation Generated Documentation (docs/) Coverage should include docs documentation files if docs directory exists","status":"passed","title":"should include docs documentation files if docs directory exists","duration":2.903756000000044,"failureMessages":[],"location":{"line":205,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Sitemap HTML Pages Coverage"],"fullName":"Sitemap Generation Sitemap HTML Pages Coverage should include sitemap HTML pages","status":"passed","title":"should include sitemap HTML pages","duration":0.40681100000006154,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Sitemap HTML Pages Coverage"],"fullName":"Sitemap Generation Sitemap HTML Pages Coverage should include sitemap pages for multiple languages","status":"passed","title":"should include sitemap pages for multiple languages","duration":0.5757380000000012,"failureMessages":[],"location":{"line":223,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have proper lastmod dates","status":"passed","title":"should have proper lastmod dates","duration":5.714959000000022,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have changefreq values","status":"passed","title":"should have changefreq values","duration":5.393697999999972,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should have priority values","status":"passed","title":"should have priority values","duration":5.358011000000033,"failureMessages":[],"location":{"line":248,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should use proper base URL","status":"passed","title":"should use proper base URL","duration":113.28882699999997,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","URL Quality"],"fullName":"Sitemap Generation URL Quality should not have duplicate URLs","status":"passed","title":"should not have duplicate URLs","duration":13.926934000000074,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","File Size and Performance"],"fullName":"Sitemap Generation File Size and Performance should be under 50MB (sitemap limit)","status":"passed","title":"should be under 50MB (sitemap limit)","duration":2.1938969999999927,"failureMessages":[],"location":{"line":269,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","File Size and Performance"],"fullName":"Sitemap Generation File Size and Performance should have less than 50,000 URLs (sitemap limit)","status":"passed","title":"should have less than 50,000 URLs (sitemap limit)","duration":2.9178929999999355,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates for the main index page covering all 14 languages","status":"passed","title":"should have hreflang alternates for the main index page covering all 14 languages","duration":1.115589,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have individual entries for all 14 language index pages","status":"passed","title":"should have individual entries for all 14 language index pages","duration":0.6437550000000556,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have entries for all 14 dashboard language pages","status":"passed","title":"should have entries for all 14 dashboard language pages","duration":0.8351529999999912,"failureMessages":[],"location":{"line":310,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have sitemap HTML pages for all 14 languages","status":"passed","title":"should have sitemap HTML pages for all 14 languages","duration":0.6848329999999123,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates on sitemap HTML pages","status":"passed","title":"should have hreflang alternates on sitemap HTML pages","duration":0.5077509999999847,"failureMessages":[],"location":{"line":336,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have news articles with matching hreflang alternates for every language variant","status":"passed","title":"should have news articles with matching hreflang alternates for every language variant","duration":7.933652999999936,"failureMessages":[],"location":{"line":349,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have news index pages for available languages","status":"passed","title":"should have news index pages for available languages","duration":0.5746350000000575,"failureMessages":[],"location":{"line":388,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have hreflang alternates in news index entry","status":"passed","title":"should have hreflang alternates in news index entry","duration":0.49148999999999887,"failureMessages":[],"location":{"line":402,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should include politician dashboard","status":"passed","title":"should include politician dashboard","duration":0.45724600000005466,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Sitemap Generation","Comprehensive Locale Validation"],"fullName":"Sitemap Generation Comprehensive Locale Validation should have x-default hreflang pointing to English for main pages","status":"passed","title":"should have x-default hreflang pointing to English for main pages","duration":0.5635950000000776,"failureMessages":[],"location":{"line":419,"column":5},"meta":{},"tags":[]}],"startTime":1787953682133,"endTime":1787953682366.5635,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-generation.test.ts"},{"assertionResults":[{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml escapes the five HTML metacharacters","status":"passed","title":"escapes the five HTML metacharacters","duration":3.7297739999999635,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml preserves valid pre-encoded entities (named, numeric, hex)","status":"passed","title":"preserves valid pre-encoded entities (named, numeric, hex)","duration":0.5123890000000415,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml escapes a stray ampersand in slogans like \"R&D\"","status":"passed","title":"escapes a stray ampersand in slogans like \"R&D\"","duration":0.46937900000000354,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/escape.ts — escapeHtml"],"fullName":"sitemap-html/escape.ts — escapeHtml uses HTML-canonical ' for apostrophes (NOT XML ')","status":"passed","title":"uses HTML-canonical ' for apostrophes (NOT XML ')","duration":0.37441100000000915,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META has an entry for every supported language","status":"passed","title":"has an entry for every supported language","duration":0.7768250000000307,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the en entry has a non-empty native name and flag","status":"passed","title":"the en entry has a non-empty native name and flag","duration":0.5472239999999715,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the sv entry has a non-empty native name and flag","status":"passed","title":"the sv entry has a non-empty native name and flag","duration":0.539289999999994,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the da entry has a non-empty native name and flag","status":"passed","title":"the da entry has a non-empty native name and flag","duration":0.31244499999996833,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the no entry has a non-empty native name and flag","status":"passed","title":"the no entry has a non-empty native name and flag","duration":0.4460849999999823,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the fi entry has a non-empty native name and flag","status":"passed","title":"the fi entry has a non-empty native name and flag","duration":0.4124219999999923,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the de entry has a non-empty native name and flag","status":"passed","title":"the de entry has a non-empty native name and flag","duration":0.36506400000001804,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the fr entry has a non-empty native name and flag","status":"passed","title":"the fr entry has a non-empty native name and flag","duration":0.3303280000000086,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the es entry has a non-empty native name and flag","status":"passed","title":"the es entry has a non-empty native name and flag","duration":0.2906939999999736,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the nl entry has a non-empty native name and flag","status":"passed","title":"the nl entry has a non-empty native name and flag","duration":0.35570599999999786,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ar entry has a non-empty native name and flag","status":"passed","title":"the ar entry has a non-empty native name and flag","duration":0.40788300000002664,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the he entry has a non-empty native name and flag","status":"passed","title":"the he entry has a non-empty native name and flag","duration":0.31885699999997996,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ja entry has a non-empty native name and flag","status":"passed","title":"the ja entry has a non-empty native name and flag","duration":0.30434999999999945,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the ko entry has a non-empty native name and flag","status":"passed","title":"the ko entry has a non-empty native name and flag","duration":0.3360500000000002,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META the zh entry has a non-empty native name and flag","status":"passed","title":"the zh entry has a non-empty native name and flag","duration":0.30708500000002914,"failureMessages":[],"location":{"line":51,"column":21},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META uses BCP-47 hreflang `nb` for the `no` entry (Norwegian Bokmål)","status":"passed","title":"uses BCP-47 hreflang `nb` for the `no` entry (Norwegian Bokmål)","duration":0.3463979999999651,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META uses RTL direction for Arabic and Hebrew, LTR for everything else","status":"passed","title":"uses RTL direction for Arabic and Hebrew, LTR for everything else","duration":0.6473119999999994,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-html/i18n.ts — LANGUAGE_META"],"fullName":"sitemap-html/i18n.ts — LANGUAGE_META every entry exposes the translations bundle used by the renderer","status":"passed","title":"every entry exposes the translations bundle used by the renderer","duration":1.576010999999994,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]}],"startTime":1787953914847,"endTime":1787953914861.576,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-html-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode maps the legacy `no` file-suffix to BCP-47 `nb` (Norwegian Bokmål)","status":"passed","title":"maps the legacy `no` file-suffix to BCP-47 `nb` (Norwegian Bokmål)","duration":4.48357500000003,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes en through unchanged","status":"passed","title":"passes en through unchanged","duration":0.671196000000009,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes sv through unchanged","status":"passed","title":"passes sv through unchanged","duration":0.49871400000000676,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes da through unchanged","status":"passed","title":"passes da through unchanged","duration":0.363851000000011,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes fi through unchanged","status":"passed","title":"passes fi through unchanged","duration":0.4687279999999987,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes de through unchanged","status":"passed","title":"passes de through unchanged","duration":0.4496819999999957,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes fr through unchanged","status":"passed","title":"passes fr through unchanged","duration":0.46205500000002075,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes es through unchanged","status":"passed","title":"passes es through unchanged","duration":0.3291760000000181,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes nl through unchanged","status":"passed","title":"passes nl through unchanged","duration":0.3112930000000347,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ar through unchanged","status":"passed","title":"passes ar through unchanged","duration":0.2870980000000145,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes he through unchanged","status":"passed","title":"passes he through unchanged","duration":0.5403419999999528,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ja through unchanged","status":"passed","title":"passes ja through unchanged","duration":0.2847239999999829,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes ko through unchanged","status":"passed","title":"passes ko through unchanged","duration":0.29939999999999145,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes zh through unchanged","status":"passed","title":"passes zh through unchanged","duration":0.35919300000000476,"failureMessages":[],"location":{"line":31,"column":90},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/hreflang.ts — hreflangCode"],"fullName":"sitemap-xml/hreflang.ts — hreflangCode passes unknown codes through unchanged (does not throw on unexpected input)","status":"passed","title":"passes unknown codes through unchanged (does not throw on unexpected input)","duration":0.36655700000000024,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry emits a minimal `<url>` block without alternates","status":"passed","title":"emits a minimal `<url>` block without alternates","duration":0.8529369999999972,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry emits one `<xhtml:link rel=\"alternate\">` per alternate, normalising `no` → `nb`","status":"passed","title":"emits one `<xhtml:link rel=\"alternate\">` per alternate, normalising `no` → `nb`","duration":0.6712770000000319,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/render/url-entry.ts — generateUrlEntry"],"fullName":"sitemap-xml/render/url-entry.ts — generateUrlEntry always prefixes the canonical absolute base URL","status":"passed","title":"always prefixes the canonical absolute base URL","duration":0.4659520000000157,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/scanners/api.ts — getApiDocs"],"fullName":"sitemap-xml/scanners/api.ts — getApiDocs returns an empty array when the API directory does not exist","status":"passed","title":"returns an empty array when the API directory does not exist","duration":3.931701999999973,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/scanners/api.ts — getApiDocs"],"fullName":"sitemap-xml/scanners/api.ts — getApiDocs scans a mocked directory tree and returns ApiDoc entries","status":"passed","title":"scans a mocked directory tree and returns ApiDoc entries","duration":60.618682999999976,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap returns true on a valid sitemap","status":"passed","title":"returns true on a valid sitemap","duration":0.9285589999999502,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws on missing XML declaration","status":"passed","title":"throws on missing XML declaration","duration":1.5680259999999748,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws on missing or wrong sitemap namespace","status":"passed","title":"throws on missing or wrong sitemap namespace","duration":0.6490949999999884,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws when there are zero URL entries","status":"passed","title":"throws when there are zero URL entries","duration":0.6509990000000698,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sitemap-xml/validator.ts — validateSitemap"],"fullName":"sitemap-xml/validator.ts — validateSitemap throws when `<url>` blocks lack `<loc>` tags","status":"passed","title":"throws when `<url>` blocks lack `<loc>` tags","duration":0.5917180000000144,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]}],"startTime":1787953854899,"endTime":1787953854980.651,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sitemap-xml-leaf-modules.test.ts"},{"assertionResults":[{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=home)","status":"passed","title":"returns a 7-token native keyword string for every language (family=home)","duration":4.256792000000019,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=dashboard)","status":"passed","title":"returns a 7-token native keyword string for every language (family=dashboard)","duration":0.9827300000000037,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns a 7-token native keyword string for every language (family=politician)","status":"passed","title":"returns a 7-token native keyword string for every language (family=politician)","duration":0.5502900000000182,"failureMessages":[],"location":{"line":66,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix returns DISTINCT keyword strings across languages for the same family","status":"passed","title":"returns DISTINCT keyword strings across languages for the same family","duration":0.5195529999999735,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix keeps the platform brand \"Riksdagsmonitor\" in every home-family entry (proper noun)","status":"passed","title":"keeps the platform brand \"Riksdagsmonitor\" in every home-family entry (proper noun)","duration":0.799165999999957,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix keeps the acronym \"OSINT\" in every home-family entry (international term)","status":"passed","title":"keeps the acronym \"OSINT\" in every home-family entry (international term)","duration":0.5799759999999878,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for German (no English leakage)","status":"passed","title":"uses native vocabulary for German (no English leakage)","duration":1.152058000000011,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for Arabic (no English leakage; RTL script)","status":"passed","title":"uses native vocabulary for Arabic (no English leakage; RTL script)","duration":0.4135350000000244,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageKeywords — per family × language matrix"],"fullName":"buildStaticPageKeywords — per family × language matrix uses native vocabulary for Japanese (CJK script)","status":"passed","title":"uses native vocabulary for Japanese (CJK script)","duration":0.5751260000000116,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock emits one og:locale for the page and 13 og:locale:alternate siblings","status":"passed","title":"emits one og:locale for the page and 13 og:locale:alternate siblings","duration":0.40401699999995344,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock uses the canonical territory code for each language","status":"passed","title":"uses the canonical territory code for each language","duration":0.6791719999999941,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageOgLocaleBlock"],"fullName":"buildStaticPageOgLocaleBlock uses nb_NO for Norwegian (BCP-47 convention)","status":"passed","title":"uses nb_NO for Norwegian (BCP-47 convention)","duration":0.4674449999999979,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageTwitterCardBlock"],"fullName":"buildStaticPageTwitterCardBlock emits a complete summary_large_image Twitter Card","status":"passed","title":"emits a complete summary_large_image Twitter Card","duration":0.5548789999999713,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageTwitterCardBlock"],"fullName":"buildStaticPageTwitterCardBlock HTML-escapes special characters in title / description","status":"passed","title":"HTML-escapes special characters in title / description","duration":0.6309510000000387,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a WebSite + Organization + WebPage graph with Speakable for h1","status":"passed","title":"emits a WebSite + Organization + WebPage graph with Speakable for h1","duration":1.9022619999999506,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd uses `nb` for Norwegian inLanguage (BCP-47)","status":"passed","title":"uses `nb` for Norwegian inLanguage (BCP-47)","duration":0.5418439999999691,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a BreadcrumbList node with two items for dashboard / politician families","status":"passed","title":"emits a BreadcrumbList node with two items for dashboard / politician families","duration":1.2216980000000035,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd emits a single-item BreadcrumbList for the home family (EN home URL)","status":"passed","title":"emits a single-item BreadcrumbList for the home family (EN home URL)","duration":0.7923540000000457,"failureMessages":[],"location":{"line":259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildStaticPageJsonLd"],"fullName":"buildStaticPageJsonLd localises BreadcrumbList Home label per language (ar / ja / zh)","status":"passed","title":"localises BreadcrumbList Home label per language (ar / ja / zh)","duration":0.8774540000000002,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) replaces the EN keyword string with native German keywords","status":"passed","title":"replaces the EN keyword string with native German keywords","duration":0.5407030000000077,"failureMessages":[],"location":{"line":306,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits a full og:locale matrix (de_DE primary, 13 alternates)","status":"passed","title":"emits a full og:locale matrix (de_DE primary, 13 alternates)","duration":0.6006249999999795,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) adds the Twitter Card block (was missing on politician-dashboard*)","status":"passed","title":"adds the Twitter Card block (was missing on politician-dashboard*)","duration":0.5157959999999662,"failureMessages":[],"location":{"line":320,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) adds the JSON-LD WebSite + WebPage + Speakable block","status":"passed","title":"adds the JSON-LD WebSite + WebPage + Speakable block","duration":0.6122169999999869,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) preserves the original <title> and <meta name=\"description\"> verbatim","status":"passed","title":"preserves the original <title> and <meta name=\"description\"> verbatim","duration":0.49836399999998093,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) is idempotent — running twice yields the same output as once","status":"passed","title":"is idempotent — running twice yields the same output as once","duration":0.6616290000000049,"failureMessages":[],"location":{"line":339,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly one <meta name=\"keywords\"> tag (no duplication on re-run)","status":"passed","title":"emits exactly one <meta name=\"keywords\"> tag (no duplication on re-run)","duration":0.6043220000000247,"failureMessages":[],"location":{"line":353,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly one og:locale primary tag","status":"passed","title":"emits exactly one og:locale primary tag","duration":0.648144000000002,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — integration (DE politician-dashboard)"],"fullName":"enhanceStaticPageHead — integration (DE politician-dashboard) emits exactly 13 og:locale:alternate tags","status":"passed","title":"emits exactly 13 og:locale:alternate tags","duration":0.5877510000000257,"failureMessages":[],"location":{"line":363,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=home)","status":"passed","title":"rewrites keywords for every language (family=home)","duration":3.5181479999999965,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=dashboard)","status":"passed","title":"rewrites keywords for every language (family=dashboard)","duration":2.501564999999971,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]},{"ancestorTitles":["enhanceStaticPageHead — every family × every language smoke test"],"fullName":"enhanceStaticPageHead — every family × every language smoke test rewrites keywords for every language (family=politician)","status":"passed","title":"rewrites keywords for every language (family=politician)","duration":2.2649810000000343,"failureMessages":[],"location":{"line":370,"column":20},"meta":{},"tags":[]}],"startTime":1787953783499,"endTime":1787953783531.265,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/static-pages-seo.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret link discovery"],"fullName":"Statskontoret link discovery extracts Excel and CSV ZIP GetFile links with provenance parameters","status":"passed","title":"extracts Excel and CSV ZIP GetFile links with provenance parameters","duration":7.917693999999983,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret workbook parsing"],"fullName":"Statskontoret workbook parsing parses XLSX rows and builds department headcount time series","status":"passed","title":"parses XLSX rows and builds department headcount time series","duration":20.54657700000007,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret workbook parsing"],"fullName":"Statskontoret workbook parsing aggregates records with Swedish decimal comma values","status":"passed","title":"aggregates records with Swedish decimal comma values","duration":0.8426069999999299,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CSV ZIP parsing"],"fullName":"Statskontoret CSV ZIP parsing extracts CSV files from ZIP archives","status":"passed","title":"extracts CSV files from ZIP archives","duration":1.7137380000000348,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient uses injected fetch for source discovery","status":"passed","title":"uses injected fetch for source discovery","duration":1.8229230000000598,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient allows custom HTTPS baseURL hosts through the fetch guard","status":"passed","title":"allows custom HTTPS baseURL hosts through the fetch guard","duration":1.5462440000000015,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient wraps network failures in typed http errors with the original cause","status":"passed","title":"wraps network failures in typed http errors with the original cause","duration":1.05126800000005,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient"],"fullName":"StatskontoretClient densifies sparse worksheet rows so column alignment is preserved","status":"passed","title":"densifies sparse worksheet rows so column alignment is preserved","duration":2.751822000000061,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses annual income outturn records (årsutfall Inkomst)","status":"passed","title":"parses annual income outturn records (årsutfall Inkomst)","duration":1.2740250000000515,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses annual expenditure outturn records (årsutfall Utgift)","status":"passed","title":"parses annual expenditure outturn records (årsutfall Utgift)","duration":0.6657559999999876,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows parses monthly outturn records (månadsutfall) with month column","status":"passed","title":"parses monthly outturn records (månadsutfall) with month column","duration":0.6251300000000128,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows uses fallback year when the record has no year column","status":"passed","title":"uses fallback year when the record has no year column","duration":0.5767590000000382,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows skips records missing an outturn value","status":"passed","title":"skips records missing an outturn value","duration":0.6195490000000063,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows"],"fullName":"parseBudgetRows normalises Swedish decimal commas","status":"passed","title":"normalises Swedish decimal commas","duration":0.6994489999999587,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries derives documentType from sheet name and parses all sheets","status":"passed","title":"derives documentType from sheet name and parses all sheets","duration":5.325068999999985,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries sorts output by year then month then documentType","status":"passed","title":"sorts output by year then month then documentType","duration":0.8023520000000417,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildBudgetTimeSeries"],"fullName":"buildBudgetTimeSeries forces documentType when options.documentType overrides sheet-name inference","status":"passed","title":"forces documentType when options.documentType overrides sheet-name inference","duration":0.4501030000000128,"failureMessages":[],"location":{"line":303,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn aggregates rows into per-year/documentType totals with variance","status":"passed","title":"aggregates rows into per-year/documentType totals with variance","duration":0.9362320000000182,"failureMessages":[],"location":{"line":313,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn omits totalBudget and variance when any row lacks a budget value","status":"passed","title":"omits totalBudget and variance when any row lacks a budget value","duration":0.5570920000000115,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn returns results sorted by year then documentType","status":"passed","title":"returns results sorted by year then documentType","duration":0.5669619999999895,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["summarizeBudgetOutturn"],"fullName":"summarizeBudgetOutturn returns empty array for empty input","status":"passed","title":"returns empty array for empty input","duration":0.4891660000000684,"failureMessages":[],"location":{"line":355,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource returns the source definition for a valid key","status":"passed","title":"returns the source definition for a valid key","duration":0.44822899999996935,"failureMessages":[],"location":{"line":361,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource throws a typed StatskontoretError for an unknown key","status":"passed","title":"throws a typed StatskontoretError for an unknown key","duration":0.6976360000001023,"failureMessages":[],"location":{"line":367,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getStatskontoretSource"],"fullName":"getStatskontoretSource exposes StatskontoretError.kind on thrown errors","status":"passed","title":"exposes StatskontoretError.kind on thrown errors","duration":0.42800099999999475,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options uses sheetNamePattern to pick the correct sheet","status":"passed","title":"uses sheetNamePattern to pick the correct sheet","duration":2.2859700000000203,"failureMessages":[],"location":{"line":384,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options returns empty array when sheetNamePattern matches no sheet","status":"passed","title":"returns empty array when sheetNamePattern matches no sheet","duration":1.709840999999983,"failureMessages":[],"location":{"line":390,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildHeadcountTimeSeries advanced options"],"fullName":"buildHeadcountTimeSeries advanced options returns empty array when workbook has no sheets","status":"passed","title":"returns empty array when workbook has no sheets","duration":0.48642099999995025,"failureMessages":[],"location":{"line":396,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options uses explicit headerRowIndex to skip auto-detection","status":"passed","title":"uses explicit headerRowIndex to skip auto-detection","duration":0.5207349999999451,"failureMessages":[],"location":{"line":403,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options returns empty array when rows are empty","status":"passed","title":"returns empty array when rows are empty","duration":0.442297999999937,"failureMessages":[],"location":{"line":413,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rowsToRecords advanced options"],"fullName":"rowsToRecords advanced options uses fallback column names for blank headers","status":"passed","title":"uses fallback column names for blank headers","duration":0.44932200000005196,"failureMessages":[],"location":{"line":417,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows additional paths"],"fullName":"parseBudgetRows additional paths uses fallbackMonth when the record has no month column","status":"passed","title":"uses fallbackMonth when the record has no month column","duration":0.5242620000000215,"failureMessages":[],"location":{"line":426,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseBudgetRows additional paths"],"fullName":"parseBudgetRows additional paths skips records with no year and no fallbackYear","status":"passed","title":"skips records with no year and no fallbackYear","duration":0.5558510000000751,"failureMessages":[],"location":{"line":432,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractStatskontoretDownloadLinks deduplication"],"fullName":"extractStatskontoretDownloadLinks deduplication deduplicates links with identical resolved URLs","status":"passed","title":"deduplicates links with identical resolved URLs","duration":0.5874500000001035,"failureMessages":[],"location":{"line":439,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractStatskontoretDownloadLinks deduplication"],"fullName":"extractStatskontoretDownloadLinks deduplication keeps links with different query parameters","status":"passed","title":"keeps links with different query parameters","duration":0.6656769999999597,"failureMessages":[],"location":{"line":449,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["StatskontoretClient HTTP error path"],"fullName":"StatskontoretClient HTTP error path throws a typed http error when the server returns a non-OK response","status":"passed","title":"throws a typed http error when the server returns a non-OK response","duration":1.137599000000023,"failureMessages":[],"location":{"line":461,"column":3},"meta":{},"tags":[]}],"startTime":1787953675496,"endTime":1787953675560.1377,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-client.test.ts"},{"assertionResults":[{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json declares source as Statskontoret with Public classification","status":"passed","title":"declares source as Statskontoret with Public classification","duration":3.924088999999981,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json specifies a 30-day cache TTL","status":"passed","title":"specifies a 30-day cache TTL","duration":0.5349319999999693,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json contains at least one entry","status":"passed","title":"contains at least one entry","duration":0.5976499999999874,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json each entry has required fields with valid formats","status":"passed","title":"each entry has required fields with valid formats","duration":1.8881259999999997,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json covers known high-priority agencies","status":"passed","title":"covers known high-priority agencies","duration":0.6140399999999886,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data/statskontoret/index.json"],"fullName":"data/statskontoret/index.json entries with named agencies target recognised Swedish authorities","status":"passed","title":"entries with named agencies target recognised Swedish authorities","duration":0.6057240000000093,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md includes a Statskontoret relevance field in the Feasibility Context table","status":"passed","title":"includes a Statskontoret relevance field in the Feasibility Context table","duration":0.7092489999999998,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md includes a Statskontoret overlay instruction in the Administrative section","status":"passed","title":"includes a Statskontoret overlay instruction in the Administrative section","duration":0.465191999999945,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/templates/implementation-feasibility.md"],"fullName":"analysis/templates/implementation-feasibility.md references statskontoret in at least one evidence guidance note","status":"passed","title":"references statskontoret in at least one evidence guidance note","duration":0.7464979999999741,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n returns null when flag is absent","status":"passed","title":"returns null when flag is absent","duration":1.0717970000000037,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses integer value correctly","status":"passed","title":"parses integer value correctly","duration":0.6760869999999954,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses 0 (graceful-degradation: disable enrichment)","status":"passed","title":"parses 0 (graceful-degradation: disable enrichment)","duration":0.41529800000000705,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses larger values","status":"passed","title":"parses larger values","duration":0.47983899999996993,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for non-integer float value","status":"passed","title":"throws for non-integer float value","duration":1.3396589999999833,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for negative value","status":"passed","title":"throws for negative value","duration":0.594664000000023,"failureMessages":[],"location":{"line":167,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n throws for non-numeric string","status":"passed","title":"throws for non-numeric string","duration":0.5206150000000207,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n does not affect other parsed fields","status":"passed","title":"does not affect other parsed fields","duration":0.5514329999999745,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs --auto-full-text-top-n"],"fullName":"parseArgs --auto-full-text-top-n parses --full-text-for-all as an explicit override","status":"passed","title":"parses --full-text-for-all as an explicit override","duration":0.41093000000000757,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["graceful degradation: --auto-full-text-top-n=0"],"fullName":"graceful degradation: --auto-full-text-top-n=0 parseArgs returns autoFullTextTopN=0 which maps to enrichLimit=0 (no enrichment)","status":"passed","title":"parseArgs returns autoFullTextTopN=0 which maps to enrichLimit=0 (no enrichment)","duration":0.4749289999999746,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["graceful degradation: --auto-full-text-top-n=0"],"fullName":"graceful degradation: --auto-full-text-top-n=0 default (no flag) leaves autoFullTextTopN null, meaning downloadAllDocuments uses MAX_ENRICHMENT_PER_TYPE","status":"passed","title":"default (no flag) leaves autoFullTextTopN null, meaning downloadAllDocuments uses MAX_ENRICHMENT_PER_TYPE","duration":0.41267299999998386,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]}],"startTime":1787953847750,"endTime":1787953847767.4126,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-enrichment-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory has myndighetsforteckning dataset for government-body coverage","status":"passed","title":"inventory has myndighetsforteckning dataset for government-body coverage","duration":3.767304000000024,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract myndighetsforteckning is classified A1 (highest data quality)","status":"passed","title":"myndighetsforteckning is classified A1 (highest data quality)","duration":0.6583430000000021,"failureMessages":[],"location":{"line":124,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract at least one implementation-feasibility.md file in the analysis tree mentions a known Swedish agency (otherwise the per-file coverage test is vacuous)","status":"passed","title":"at least one implementation-feasibility.md file in the analysis tree mentions a known Swedish agency (otherwise the per-file coverage test is vacuous)","duration":5.942907999999932,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract every implementation-feasibility.md mentioning a known agency resolves to a Statskontoret dataset that covers it via myndighetsforteckning","status":"passed","title":"every implementation-feasibility.md mentioning a known agency resolves to a Statskontoret dataset that covers it via myndighetsforteckning","duration":7.16565700000001,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory globally covers FiU and KU committees in at least one Statskontoret dataset","status":"passed","title":"inventory globally covers FiU and KU committees in at least one Statskontoret dataset","duration":0.5790840000000799,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract inventory providerDecisionMatrix maps governmentBodiesHeadcount to statskontoret","status":"passed","title":"inventory providerDecisionMatrix maps governmentBodiesHeadcount to statskontoret","duration":0.611964999999941,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret inventory → implementation-feasibility coverage contract"],"fullName":"Statskontoret inventory → implementation-feasibility coverage contract found at least one implementation-feasibility.md file in the analysis tree","status":"passed","title":"found at least one implementation-feasibility.md file in the analysis tree","duration":0.486391000000026,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract exports CACHE_TTL_MS equal to 30 days","status":"passed","title":"exports CACHE_TTL_MS equal to 30 days","duration":0.4948060000000396,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract statskontoretSourceKeys() returns all built-in source keys","status":"passed","title":"statskontoretSourceKeys() returns all built-in source keys","duration":1.4008230000000594,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns false when no cache file exists","status":"passed","title":"isStatskontoretCacheFresh returns false when no cache file exists","duration":0.9672809999999572,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns true when a fresh cache file exists","status":"passed","title":"isStatskontoretCacheFresh returns true when a fresh cache file exists","duration":1.145954999999958,"failureMessages":[],"location":{"line":226,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract isStatskontoretCacheFresh returns false when cache entry is older than TTL","status":"passed","title":"isStatskontoretCacheFresh returns false when cache entry is older than TTL","duration":0.669563999999923,"failureMessages":[],"location":{"line":245,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached returns cached payload from disk without network call","status":"passed","title":"fetchStatskontoretCached returns cached payload from disk without network call","duration":1.3181879999999637,"failureMessages":[],"location":{"line":262,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached falls back to stale cache on network error","status":"passed","title":"fetchStatskontoretCached falls back to stale cache on network error","duration":1.6590569999999616,"failureMessages":[],"location":{"line":301,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetch-statskontoret module — API contract"],"fullName":"fetch-statskontoret module — API contract fetchStatskontoretCached throws StatskontoretError when network fails and no cache exists","status":"passed","title":"fetchStatskontoretCached throws StatskontoretError when network fails and no cache exists","duration":2.177077000000054,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]}],"startTime":1787953792682,"endTime":1787953792712.177,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-feasibility-contract.test.ts"},{"assertionResults":[{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing parses flags and boolean options without executing the CLI","status":"passed","title":"parses flags and boolean options without executing the CLI","duration":4.211945999999955,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing throws typed CLI errors for invalid input","status":"passed","title":"throws typed CLI errors for invalid input","duration":1.8443439999999782,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI parsing"],"fullName":"Statskontoret CLI parsing accepts built-in source keys","status":"passed","title":"accepts built-in source keys","duration":0.5370259999999689,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret parsing primitives"],"fullName":"Statskontoret parsing primitives classifies common downloadable resources","status":"passed","title":"classifies common downloadable resources","duration":0.9440179999999714,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret parsing primitives"],"fullName":"Statskontoret parsing primitives normalises Swedish numeric and integer values defensively","status":"passed","title":"normalises Swedish numeric and integer values defensively","duration":0.8765909999999622,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard accepts the allowlisted Statskontoret HTTPS host","status":"passed","title":"accepts the allowlisted Statskontoret HTTPS host","duration":0.8920199999999454,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects non-HTTPS schemes","status":"passed","title":"rejects non-HTTPS schemes","duration":0.5927099999999541,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects hosts outside the allowlist","status":"passed","title":"rejects hosts outside the allowlist","duration":0.5602289999999925,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard rejects malformed URLs with a typed error","status":"passed","title":"rejects malformed URLs with a typed error","duration":0.8812800000000038,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret fetch target guard"],"fullName":"Statskontoret fetch target guard blocks fetchText calls that target other hosts","status":"passed","title":"blocks fetchText calls that target other hosts","duration":2.101654999999994,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses budget-outturn command with required flags","status":"passed","title":"parses budget-outturn command with required flags","duration":0.6012359999999717,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses optional --doc-type flag","status":"passed","title":"parses optional --doc-type flag","duration":0.4701400000000149,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn command parsing"],"fullName":"Statskontoret CLI budget-outturn command parsing parses --persist boolean alongside budget-outturn","status":"passed","title":"parses --persist boolean alongside budget-outturn","duration":0.4401540000000068,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Statskontoret CLI budget-outturn source guard"],"fullName":"Statskontoret CLI budget-outturn source guard rejects myndighetsforteckning as a source for budget-outturn","status":"passed","title":"rejects myndighetsforteckning as a source for budget-outturn","duration":0.4610630000000242,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]}],"startTime":1787953891845,"endTime":1787953891861.4612,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-fetch.test.ts"},{"assertionResults":[{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json identifies Statskontoret as the public source","status":"passed","title":"identifies Statskontoret as the public source","duration":3.865848000000028,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json covers every built-in TypeScript source definition","status":"passed","title":"covers every built-in TypeScript source definition","duration":0.8597589999999968,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json declares key provider-decision routes","status":"passed","title":"declares key provider-decision routes","duration":0.435937000000024,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/statskontoret/indicators-inventory.json"],"fullName":"analysis/statskontoret/indicators-inventory.json documents the client, CLI, cachedFetch and persistence surfaces","status":"passed","title":"documents the client, CLI, cachedFetch and persistence surfaces","duration":0.6711770000000001,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953923427,"endTime":1787953923432.6711,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/statskontoret-inventory.test.ts"},{"assertionResults":[{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd produces a BreadcrumbList with correct positions and structure","status":"passed","title":"produces a BreadcrumbList with correct positions and structure","duration":6.747594000000049,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd handles a single entry","status":"passed","title":"handles a single entry","duration":0.650047000000086,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd throws when an intermediate entry is missing `item`","status":"passed","title":"throws when an intermediate entry is missing `item`","duration":1.1479290000000901,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildBreadcrumbListLd"],"fullName":"jsonld — buildBreadcrumbListLd throws when entries array is empty","status":"passed","title":"throws when entries array is empty","duration":0.585456000000022,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildNewsArticleLd"],"fullName":"jsonld — buildNewsArticleLd produces a NewsArticle with all required fields","status":"passed","title":"produces a NewsArticle with all required fields","duration":1.2018699999999853,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildNewsArticleLd"],"fullName":"jsonld — buildNewsArticleLd omits isBasedOn when no artifacts are provided","status":"passed","title":"omits isBasedOn when no artifacts are provided","duration":0.5762690000000248,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd produces a WebPage with SpeakableSpecification","status":"passed","title":"produces a WebPage with SpeakableSpecification","duration":0.9441280000000916,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd throws when cssSelectors is empty","status":"passed","title":"throws when cssSelectors is empty","duration":0.4736359999999422,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd throws when all selectors are blank","status":"passed","title":"throws when all selectors are blank","duration":0.6945709999999963,"failureMessages":[],"location":{"line":190,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["jsonld — buildSpeakableWebPageLd"],"fullName":"jsonld — buildSpeakableWebPageLd filters out blank selectors while keeping valid ones","status":"passed","title":"filters out blank selectors while keeping valid ones","duration":0.44130599999994047,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits NewsArticle JSON-LD","status":"passed","title":"emits NewsArticle JSON-LD","duration":48.59561000000008,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits BreadcrumbList JSON-LD","status":"passed","title":"emits BreadcrumbList JSON-LD","duration":3.7306449999999813,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits SpeakableSpecification JSON-LD via WebPage","status":"passed","title":"emits SpeakableSpecification JSON-LD via WebPage","duration":3.4218779999999924,"failureMessages":[],"location":{"line":257,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits correct hreflang set including x-default","status":"passed","title":"emits correct hreflang set including x-default","duration":3.352245999999923,"failureMessages":[],"location":{"line":275,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits Open Graph and Twitter Card meta tags","status":"passed","title":"emits Open Graph and Twitter Card meta tags","duration":3.226590999999985,"failureMessages":[],"location":{"line":293,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration emits correct lang attribute and dir for Arabic RTL","status":"passed","title":"emits correct lang attribute and dir for Arabic RTL","duration":3.5914450000000215,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration uses BCP-47 nb for Norwegian hreflang","status":"passed","title":"uses BCP-47 nb for Norwegian hreflang","duration":2.701738999999975,"failureMessages":[],"location":{"line":322,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["structured-data — renderArticleHtml integration"],"fullName":"structured-data — renderArticleHtml integration truncates BreadcrumbList title with ellipsis when longer than limit","status":"passed","title":"truncates BreadcrumbList title with ellipsis when longer than limit","duration":3.1824589999999944,"failureMessages":[],"location":{"line":340,"column":3},"meta":{},"tags":[]}],"startTime":1787953794244,"endTime":1787953794329.1824,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/structured-data.test.ts"},{"assertionResults":[{"ancestorTitles":["AGENCY_ACRONYM_MAP"],"fullName":"AGENCY_ACRONYM_MAP contains every high-frequency Swedish agency","status":"passed","title":"contains every high-frequency Swedish agency","duration":4.270305999999948,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["AGENCY_ACRONYM_MAP"],"fullName":"AGENCY_ACRONYM_MAP uses non-empty acronyms with sensible length","status":"passed","title":"uses non-empty acronyms with sensible length","duration":1.7050319999999601,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms emits the acronym when the full name is mentioned","status":"passed","title":"emits the acronym when the full name is mentioned","duration":1.1578379999999697,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms emits the full name when the acronym is mentioned","status":"passed","title":"emits the full name when the acronym is mentioned","duration":0.4632880000000341,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms skips unknown agencies","status":"passed","title":"skips unknown agencies","duration":0.4598609999999894,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms does not duplicate when both forms are already in input","status":"passed","title":"does not duplicate when both forms are already in input","duration":0.46288700000002336,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms preserves order of input entities","status":"passed","title":"preserves order of input entities","duration":0.5172279999999887,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandAgencyAcronyms"],"fullName":"expandAgencyAcronyms is case-insensitive on the lookup key","status":"passed","title":"is case-insensitive on the lookup key","duration":0.3780179999999973,"failureMessages":[],"location":{"line":64,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["COMMITTEE_DOMAIN_MAP"],"fullName":"COMMITTEE_DOMAIN_MAP covers every Riksdag committee code","status":"passed","title":"covers every Riksdag committee code","duration":0.8980210000000284,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["COMMITTEE_DOMAIN_MAP"],"fullName":"COMMITTEE_DOMAIN_MAP emits a localized lemma in every supported language","status":"passed","title":"emits a localized lemma in every supported language","duration":0.6410100000000511,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the English domain word for JuU when lang=en","status":"passed","title":"emits the English domain word for JuU when lang=en","duration":0.5823399999999879,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the Swedish lemma when lang=sv","status":"passed","title":"emits the Swedish lemma when lang=sv","duration":0.4074929999999881,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains emits the Japanese lemma for FiU when lang=ja","status":"passed","title":"emits the Japanese lemma for FiU when lang=ja","duration":0.4065909999999917,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains de-duplicates when the same code appears twice","status":"passed","title":"de-duplicates when the same code appears twice","duration":0.36505299999998897,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains preserves input order across distinct codes","status":"passed","title":"preserves input order across distinct codes","duration":0.36760800000001836,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["expandCommitteeDomains"],"fullName":"expandCommitteeDomains silently skips unknown committee codes","status":"passed","title":"silently skips unknown committee codes","duration":0.45706599999999753,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]}],"startTime":1787953904411,"endTime":1787953904425.457,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sv-keyword-mappings.test.ts"},{"assertionResults":[{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization exposes labels for every supported site language","status":"passed","title":"exposes labels for every supported site language","duration":5.809728000000007,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization returns Swedish labels for `sv` (case-insensitive)","status":"passed","title":"returns Swedish labels for `sv` (case-insensitive)","duration":0.7486020000000053,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization returns Arabic labels including a non-empty dismiss aria-label","status":"passed","title":"returns Arabic labels including a non-empty dismiss aria-label","duration":0.43017500000001974,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization matches on the BCP-47 primary subtag (e.g. `en-GB` → en, `zh-Hans` → zh)","status":"passed","title":"matches on the BCP-47 primary subtag (e.g. `en-GB` → en, `zh-Hans` → zh)","duration":0.37430100000000266,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["SW update toast localization"],"fullName":"SW update toast localization falls back to English for unsupported languages and empty input","status":"passed","title":"falls back to English for unsupported languages and empty input","duration":0.5572940000000131,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]}],"startTime":1787953918491,"endTime":1787953918499.5574,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/sw-update-toast-labels.test.ts"},{"assertionResults":[{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) exports a non-empty inline string","status":"passed","title":"exports a non-empty inline string","duration":3.8461110000000076,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) wraps the inline script in a <script> tag","status":"passed","title":"wraps the inline script in a <script> tag","duration":0.770702999999969,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output uses the same storage key as the canonical source","status":"passed","title":"minified output uses the same storage key as the canonical source","duration":0.48280399999998735,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output preserves all semantic tokens from the canonical source","status":"passed","title":"minified output preserves all semantic tokens from the canonical source","duration":0.5118679999999927,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output is syntactically valid JavaScript (IIFE executes)","status":"passed","title":"minified output is syntactically valid JavaScript (IIFE executes)","duration":1.465533999999991,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["shared/theme-init (single source of truth)"],"fullName":"shared/theme-init (single source of truth) minified output is substantially smaller than the canonical source","status":"passed","title":"minified output is substantially smaller than the canonical source","duration":0.489736999999991,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]}],"startTime":1787953912224,"endTime":1787953912231.4897,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/theme-init-ssot.test.ts"},{"assertionResults":[{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns stored \"dark\" from localStorage (overrides light system pref)","status":"passed","title":"returns stored \"dark\" from localStorage (overrides light system pref)","duration":4.626511999999991,"failureMessages":[],"location":{"line":104,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns stored \"light\" from localStorage (overrides dark system pref)","status":"passed","title":"returns stored \"light\" from localStorage (overrides dark system pref)","duration":0.8225699999999847,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() ignores an invalid stored value and uses system preference (dark)","status":"passed","title":"ignores an invalid stored value and uses system preference (dark)","duration":0.8677840000000288,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() ignores an invalid stored value and uses system preference (light)","status":"passed","title":"ignores an invalid stored value and uses system preference (light)","duration":0.6724790000000098,"failureMessages":[],"location":{"line":122,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"dark\" from system preference when localStorage is empty","status":"passed","title":"returns \"dark\" from system preference when localStorage is empty","duration":0.7886970000000133,"failureMessages":[],"location":{"line":128,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"light\" from system preference when localStorage is empty","status":"passed","title":"returns \"light\" from system preference when localStorage is empty","duration":0.6561990000000151,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","resolveTheme()"],"fullName":"Theme Toggle resolveTheme() returns \"light\" when matchMedia is unavailable and no stored value","status":"passed","title":"returns \"light\" when matchMedia is unavailable and no stored value","duration":0.5213360000000193,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() sets data-theme=\"dark\" on <html>","status":"passed","title":"sets data-theme=\"dark\" on <html>","duration":1.66353399999997,"failureMessages":[],"location":{"line":146,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() sets data-theme=\"light\" on <html>","status":"passed","title":"sets data-theme=\"light\" on <html>","duration":0.8865900000000124,"failureMessages":[],"location":{"line":151,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() persists to localStorage when persist flag is true","status":"passed","title":"persists to localStorage when persist flag is true","duration":0.8888940000000503,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() does not persist to localStorage when persist flag is false","status":"passed","title":"does not persist to localStorage when persist flag is false","duration":0.5867380000000253,"failureMessages":[],"location":{"line":161,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","applyTheme()"],"fullName":"Theme Toggle applyTheme() persists by default when persist is omitted","status":"passed","title":"persists by default when persist is omitted","duration":0.5782820000000015,"failureMessages":[],"location":{"line":166,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-pressed=\"true\" for dark theme","status":"passed","title":"sets aria-pressed=\"true\" for dark theme","duration":4.988989999999944,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-pressed=\"false\" for light theme","status":"passed","title":"sets aria-pressed=\"false\" for light theme","duration":1.1143160000000307,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-label to data-label-dark value when theme is dark","status":"passed","title":"sets aria-label to data-label-dark value when theme is dark","duration":0.9133400000000051,"failureMessages":[],"location":{"line":187,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets aria-label to data-label-light value when theme is light","status":"passed","title":"sets aria-label to data-label-light value when theme is light","duration":0.9019589999999766,"failureMessages":[],"location":{"line":193,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets title to match aria-label","status":"passed","title":"sets title to match aria-label","duration":1.0464590000000271,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets icon to ☀️ for dark theme","status":"passed","title":"sets icon to ☀️ for dark theme","duration":1.2417749999999614,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() sets icon to 🌙 for light theme","status":"passed","title":"sets icon to 🌙 for light theme","duration":0.9873079999999845,"failureMessages":[],"location":{"line":212,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() does nothing gracefully when button is absent","status":"passed","title":"does nothing gracefully when button is absent","duration":1.5748780000000124,"failureMessages":[],"location":{"line":218,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","updateButton()"],"fullName":"Theme Toggle updateButton() falls back to default label strings when data-label-* attrs are absent","status":"passed","title":"falls back to default label strings when data-label-* attrs are absent","duration":1.0248790000000554,"failureMessages":[],"location":{"line":222,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic switches from dark to light","status":"passed","title":"switches from dark to light","duration":1.105119000000002,"failureMessages":[],"location":{"line":247,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic switches from light to dark","status":"passed","title":"switches from light to dark","duration":0.9384860000000117,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic persists the new theme to localStorage","status":"passed","title":"persists the new theme to localStorage","duration":0.8902569999999628,"failureMessages":[],"location":{"line":261,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic updates button aria-pressed after toggle","status":"passed","title":"updates button aria-pressed after toggle","duration":0.986567999999977,"failureMessages":[],"location":{"line":268,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","toggle logic"],"fullName":"Theme Toggle toggle logic treats absent data-theme as \"light\" and switches to dark","status":"passed","title":"treats absent data-theme as \"light\" and switches to dark","duration":0.9129989999999566,"failureMessages":[],"location":{"line":275,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic does not apply new theme when valid \"dark\" is stored (explicit choice wins)","status":"passed","title":"does not apply new theme when valid \"dark\" is stored (explicit choice wins)","duration":0.8834339999999656,"failureMessages":[],"location":{"line":286,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic does not apply new theme when valid \"light\" is stored","status":"passed","title":"does not apply new theme when valid \"light\" is stored","duration":0.7880059999999958,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic clears invalid stored value and follows system preference","status":"passed","title":"clears invalid stored value and follows system preference","duration":1.1100779999999872,"failureMessages":[],"location":{"line":313,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","system prefers-color-scheme change handler logic"],"fullName":"Theme Toggle system prefers-color-scheme change handler logic follows system preference when localStorage is empty","status":"passed","title":"follows system preference when localStorage is empty","duration":1.057649999999967,"failureMessages":[],"location":{"line":332,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class adds theme-transition class on toggle","status":"passed","title":"adds theme-transition class on toggle","duration":4.434802999999988,"failureMessages":[],"location":{"line":376,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class removes theme-transition class after timeout","status":"passed","title":"removes theme-transition class after timeout","duration":1.9777730000000133,"failureMessages":[],"location":{"line":387,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","theme-transition class"],"fullName":"Theme Toggle theme-transition class handles rapid toggles without premature class removal","status":"passed","title":"handles rapid toggles without premature class removal","duration":2.008609999999976,"failureMessages":[],"location":{"line":399,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic uses stored \"dark\" without clearing or overriding","status":"passed","title":"uses stored \"dark\" without clearing or overriding","duration":0.8607419999999593,"failureMessages":[],"location":{"line":426,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic uses stored \"light\" without clearing","status":"passed","title":"uses stored \"light\" without clearing","duration":0.8770420000000172,"failureMessages":[],"location":{"line":438,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic clears invalid stored value and falls back","status":"passed","title":"clears invalid stored value and falls back","duration":0.8427980000000161,"failureMessages":[],"location":{"line":449,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["Theme Toggle","anti-flash snippet localStorage validation logic"],"fullName":"Theme Toggle anti-flash snippet localStorage validation logic falls back to \"light\" when localStorage throws","status":"passed","title":"falls back to \"light\" when localStorage throws","duration":0.8607010000000059,"failureMessages":[],"location":{"line":460,"column":5},"meta":{},"tags":[]}],"startTime":1787953685423,"endTime":1787953685471.8606,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/theme-toggle.test.js"},{"assertionResults":[{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a single dok_id reference","status":"passed","title":"counts a single dok_id reference","duration":4.372235999999987,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts mixed-case Riksdag committee report identifiers","status":"passed","title":"counts mixed-case Riksdag committee report identifiers","duration":0.656519000000003,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts two-uppercase-letter committee betänkande codes","status":"passed","title":"counts two-uppercase-letter committee betänkande codes","duration":0.4645399999999995,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts parliamentary doc references","status":"passed","title":"counts parliamentary doc references","duration":0.4883340000000089,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts Riksrevisionen audit references","status":"passed","title":"counts Riksrevisionen audit references","duration":0.499795000000006,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a primary-source URL without any embedded dok_id","status":"passed","title":"counts a primary-source URL without any embedded dok_id","duration":0.5737039999999638,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts a riksdagen.se URL without doubling the count","status":"passed","title":"counts a riksdagen.se URL without doubling the count","duration":0.48123099999997976,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors returns zero for narrative prose without anchors","status":"passed","title":"returns zero for narrative prose without anchors","duration":0.40534900000000107,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors does NOT count ordinary English words as dok_ids","status":"passed","title":"does NOT count ordinary English words as dok_ids","duration":0.5670620000000213,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countBlufEvidenceAnchors"],"fullName":"validate-article — countBlufEvidenceAnchors counts multiple anchors of mixed types","status":"passed","title":"counts multiple anchors of mixed types","duration":0.44538399999999,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns null for a non-existent directory","status":"passed","title":"returns null for a non-existent directory","duration":0.8064800000000218,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns valid phrases from the real JSON","status":"passed","title":"returns valid phrases from the real JSON","duration":2.123816999999974,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — loadBannedPhrases"],"fullName":"validate-article — loadBannedPhrases returns de-duplicated phrases","status":"passed","title":"returns de-duplicated phrases","duration":0.7041980000000194,"failureMessages":[],"location":{"line":129,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countArticleEvidenceAnchors"],"fullName":"validate-article — countArticleEvidenceAnchors counts dok_id and URL anchors","status":"passed","title":"counts dok_id and URL anchors","duration":0.6199910000000273,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countArticleEvidenceAnchors"],"fullName":"validate-article — countArticleEvidenceAnchors does NOT count #rm- internal links","status":"passed","title":"does NOT count #rm- internal links","duration":0.5160170000000335,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases detects a banned phrase (case-insensitive)","status":"passed","title":"detects a banned phrase (case-insensitive)","duration":0.6294879999999807,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases detects multiple occurrences of the same phrase","status":"passed","title":"detects multiple occurrences of the same phrase","duration":0.48322500000000446,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases returns empty array for clean text","status":"passed","title":"returns empty array for clean text","duration":1.3916150000000016,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases matches case-insensitively","status":"passed","title":"matches case-insensitively","duration":0.5315559999999664,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanBannedPhrases"],"fullName":"validate-article — scanBannedPhrases skips empty and whitespace-only phrases without hanging","status":"passed","title":"skips empty and whitespace-only phrases without hanging","duration":0.5532559999999762,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords counts words in plain text","status":"passed","title":"counts words in plain text","duration":0.9855660000000057,"failureMessages":[],"location":{"line":187,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords excludes fenced code blocks","status":"passed","title":"excludes fenced code blocks","duration":0.4818920000000162,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords excludes fenced code blocks with language tag","status":"passed","title":"excludes fenced code blocks with language tag","duration":0.5857970000000137,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords strips markdown links but keeps link text","status":"passed","title":"strips markdown links but keeps link text","duration":0.4764319999999884,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords strips markdown table pipes and alignment rows","status":"passed","title":"strips markdown table pipes and alignment rows","duration":0.4964200000000005,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countWords"],"fullName":"validate-article — countWords handles table-heavy content without inflated counts","status":"passed","title":"handles table-heavy content without inflated counts","duration":0.49435599999998203,"failureMessages":[],"location":{"line":214,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity returns Infinity for text with no anchors","status":"passed","title":"returns Infinity for text with no anchors","duration":0.5652980000000412,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity computes density for text with anchors","status":"passed","title":"computes density for text with anchors","duration":0.6323639999999955,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — computeCitationDensity"],"fullName":"validate-article — computeCitationDensity does not count #rm- internal links as evidence anchors","status":"passed","title":"does not count #rm- internal links as evidence anchors","duration":0.5037929999999733,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance flags entries older than 6 months","status":"passed","title":"flags entries older than 6 months","duration":0.9417940000000158,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance ignores entries within 6 months","status":"passed","title":"ignores entries within 6 months","duration":0.8762009999999805,"failureMessages":[],"location":{"line":255,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance ignores entries with stale-vintage annotation on immediately preceding line","status":"passed","title":"ignores entries with stale-vintage annotation on immediately preceding line","duration":0.8342419999999606,"failureMessages":[],"location":{"line":261,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — scanStaleProvenance"],"fullName":"validate-article — scanStaleProvenance does NOT exempt entries when annotation is too far away","status":"passed","title":"does NOT exempt entries when annotation is too far away","duration":0.5933600000000183,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings returns 0 when no mermaid fences are present","status":"passed","title":"returns 0 when no mermaid fences are present","duration":0.6108239999999796,"failureMessages":[],"location":{"line":286,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings counts one opening fence per `\\`\\`\\`mermaid` line","status":"passed","title":"counts one opening fence per `\\`\\`\\`mermaid` line","duration":0.643304999999998,"failureMessages":[],"location":{"line":290,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings does not count `\\`\\`\\`mermaid` inside a fenced code block prose example","status":"passed","title":"does not count `\\`\\`\\`mermaid` inside a fenced code block prose example","duration":0.5938820000000078,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — countMermaidOpenings"],"fullName":"validate-article — countMermaidOpenings counts even when an opening has no matching close (raw count)","status":"passed","title":"counts even when an opening has no matching close (raw count)","duration":0.598590999999999,"failureMessages":[],"location":{"line":302,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences returns an empty array when every fence is properly closed","status":"passed","title":"returns an empty array when every fence is properly closed","duration":0.8065300000000093,"failureMessages":[],"location":{"line":311,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences flags a single unclosed fence","status":"passed","title":"flags a single unclosed fence","duration":0.7726370000000315,"failureMessages":[],"location":{"line":316,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences flags an unclosed fence followed by a properly closed one","status":"passed","title":"flags an unclosed fence followed by a properly closed one","duration":0.6867859999999837,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validate-article — findUnclosedMermaidFences"],"fullName":"validate-article — findUnclosedMermaidFences detects every unclosed fence in a chain of unclosed mermaid openings (regression: no loop-skip)","status":"passed","title":"detects every unclosed fence in a chain of unclosed mermaid openings (regression: no loop-skip)","duration":0.8685159999999996,"failureMessages":[],"location":{"line":345,"column":3},"meta":{},"tags":[]}],"startTime":1787953791508,"endTime":1787953791539.8684,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-article.test.ts"},{"assertionResults":[{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countHeadings counts all #-headings outside fences","status":"passed","title":"countHeadings counts all #-headings outside fences","duration":3.8885910000000194,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countCodeFences counts fenced blocks (pairs of ```)","status":"passed","title":"countCodeFences counts fenced blocks (pairs of ```)","duration":0.6300989999999729,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countCodeFences reports malformed unpaired fences","status":"passed","title":"countCodeFences reports malformed unpaired fences","duration":0.4740279999999757,"failureMessages":[],"location":{"line":118,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countMermaidBlocks counts only ```mermaid blocks","status":"passed","title":"countMermaidBlocks counts only ```mermaid blocks","duration":0.4784559999999942,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countTableRows counts every line of every markdown table","status":"passed","title":"countTableRows counts every line of every markdown table","duration":0.5762589999999932,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractDokIds picks up Riksdag dok_ids","status":"passed","title":"extractDokIds picks up Riksdag dok_ids","duration":0.7267410000000041,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractDokIds ignores plain English / translated words that start with H (no digit)","status":"passed","title":"extractDokIds ignores plain English / translated words that start with H (no digit)","duration":0.623738000000003,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractUrls returns absolute URLs in link targets and bare text","status":"passed","title":"extractUrls returns absolute URLs in link targets and bare text","duration":0.6502369999999473,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractSourceShaMarker returns the 40-hex sha when present","status":"passed","title":"extractSourceShaMarker returns the 40-hex sha when present","duration":0.7609240000000455,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters extractSourceShaMarker only accepts the marker as the trailing non-empty line","status":"passed","title":"extractSourceShaMarker only accepts the marker as the trailing non-empty line","duration":0.4813819999999964,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters hasRtlMarker only matches when within the first 1KB","status":"passed","title":"hasRtlMarker only matches when within the first 1KB","duration":0.567592999999988,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters countWords returns a reasonable approximation","status":"passed","title":"countWords returns a reasonable approximation","duration":1.6405720000000201,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["executive-brief structural counters"],"fullName":"executive-brief structural counters TRANSLATION_LANGS lists exactly the 13 non-English target languages","status":"passed","title":"TRANSLATION_LANGS lists exactly the 13 non-English target languages","duration":1.0355689999999527,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases returns empty array when translation has no banned English phrases","status":"passed","title":"returns empty array when translation has no banned English phrases","duration":0.8437999999999874,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases flags a translation that left \"Executive Brief\" untranslated","status":"passed","title":"flags a translation that left \"Executive Brief\" untranslated","duration":1.3353200000000243,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findBannedEnglishPhrases"],"fullName":"findBannedEnglishPhrases flags a translation that left \"BLUF\" in the body","status":"passed","title":"flags a translation that left \"BLUF\" in the body","duration":0.5993520000000103,"failureMessages":[],"location":{"line":217,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end passes every check for a valid Swedish translation","status":"passed","title":"passes every check for a valid Swedish translation","duration":1.0582919999999945,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end passes every check (including RTL marker) for a valid Arabic translation","status":"passed","title":"passes every check (including RTL marker) for a valid Arabic translation","duration":0.7350059999999985,"failureMessages":[],"location":{"line":241,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails dok-id-preservation when the translation drops an identifier","status":"passed","title":"fails dok-id-preservation when the translation drops an identifier","duration":0.7524980000000028,"failureMessages":[],"location":{"line":254,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails url-preservation when the translation drops an external URL","status":"passed","title":"fails url-preservation when the translation drops an external URL","duration":0.690021999999999,"failureMessages":[],"location":{"line":268,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end fails rtl-marker when an Arabic translation is missing the marker","status":"passed","title":"fails rtl-marker when an Arabic translation is missing the marker","duration":0.874888999999996,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags source-sha-marker as stale when trailer does not match current source SHA","status":"passed","title":"flags source-sha-marker as stale when trailer does not match current source SHA","duration":0.6786710000000085,"failureMessages":[],"location":{"line":295,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags source-sha-marker as missing when trailer is absent","status":"passed","title":"flags source-sha-marker as missing when trailer is absent","duration":0.7526090000000067,"failureMessages":[],"location":{"line":308,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags code-fence-count when the translation has an unpaired fence","status":"passed","title":"flags code-fence-count when the translation has an unpaired fence","duration":0.7551249999999641,"failureMessages":[],"location":{"line":323,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end flags word-count-drift when the translation is more than 25% shorter","status":"passed","title":"flags word-count-drift when the translation is more than 25% shorter","duration":1.1232229999999959,"failureMessages":[],"location":{"line":334,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateTranslationContent end-to-end"],"fullName":"validateTranslationContent end-to-end skips word-count-drift for CJK scripts (ja, zh) — whitespace tokeniser systematically undercounts","status":"passed","title":"skips word-count-drift for CJK scripts (ja, zh) — whitespace tokeniser systematically undercounts","duration":0.9130899999999542,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]}],"startTime":1787953814613,"endTime":1787953814636.913,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-executive-brief-translations.test.ts"},{"assertionResults":[{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown extracts the language code from an executive-brief_<lang>.md path","status":"passed","title":"extracts the language code from an executive-brief_<lang>.md path","duration":3.924149,"failureMessages":[],"location":{"line":11,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown returns null for the English-master executive-brief.md (no suffix)","status":"passed","title":"returns null for the English-master executive-brief.md (no suffix)","duration":0.5720010000000002,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractLangFromPath — executive-brief markdown"],"fullName":"extractLangFromPath — executive-brief markdown still works for news/<slug>-<lang>.html paths","status":"passed","title":"still works for news/<slug>-<lang>.html paths","duration":0.42831200000000536,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown English-master executive-brief.md is owned by the content category","status":"passed","title":"English-master executive-brief.md is owned by the content category","duration":0.5952449999999772,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown Swedish executive-brief_sv.md is owned by the translation category","status":"passed","title":"Swedish executive-brief_sv.md is owned by the translation category","duration":0.5601389999999924,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown Arabic and Chinese briefs are owned by the translation category","status":"passed","title":"Arabic and Chinese briefs are owned by the translation category","duration":0.4549519999999916,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown does not affect non-executive-brief markdown files outside analysis/daily","status":"passed","title":"does not affect non-executive-brief markdown files outside analysis/daily","duration":0.45595400000001973,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isFileOwnedByCategory — executive-brief markdown"],"fullName":"isFileOwnedByCategory — executive-brief markdown still enforces the existing news/*.html ownership rules","status":"passed","title":"still enforces the existing news/*.html ownership rules","duration":0.40357599999998683,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches flags a translation batch that touches the English-master brief","status":"passed","title":"flags a translation batch that touches the English-master brief","duration":1.5131739999999922,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches flags a content batch that touches translated briefs","status":"passed","title":"flags a content batch that touches translated briefs","duration":0.40639099999998507,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches passes a pure translation batch (all 13 non-EN briefs)","status":"passed","title":"passes a pure translation batch (all 13 non-EN briefs)","duration":0.679792999999961,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateFileList — mixed news + executive-brief batches"],"fullName":"validateFileList — mixed news + executive-brief batches ignores unrelated markdown files","status":"passed","title":"ignores unrelated markdown files","duration":0.35022499999996626,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns null when no ownership-surface files are present","status":"passed","title":"returns null when no ownership-surface files are present","duration":0.6053640000000087,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"translation\" when any executive-brief_<lang>.md is present","status":"passed","title":"returns \"translation\" when any executive-brief_<lang>.md is present","duration":0.47287500000004457,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when any news/*.html is present (all langs are content-owned)","status":"passed","title":"returns \"content\" when any news/*.html is present (all langs are content-owned)","duration":0.45745600000003606,"failureMessages":[],"location":{"line":142,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when only news/*.html and/or executive-brief.md are present","status":"passed","title":"returns \"content\" when only news/*.html and/or executive-brief.md are present","duration":0.41850299999998697,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns null for mixed content + translation surfaces (skip enforcement)","status":"passed","title":"returns null for mixed content + translation surfaces (skip enforcement)","duration":0.4491909999999848,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["detectCategoryFromFiles"],"fullName":"detectCategoryFromFiles returns \"content\" when only article.<lang>.md is present (forbidden but detected)","status":"passed","title":"returns \"content\" when only article.<lang>.md is present (forbidden but detected)","duration":0.3564079999999876,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseWorkflowCategoryArg"],"fullName":"parseWorkflowCategoryArg accepts long-form and short CLI category aliases","status":"passed","title":"accepts long-form and short CLI category aliases","duration":0.4820530000000076,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects article.sv.md in content category","status":"passed","title":"rejects article.sv.md in content category","duration":1.467138000000034,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects article.sv.md in translation category","status":"passed","title":"rejects article.sv.md in translation category","duration":0.7097190000000069,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files allows article.md (English source)","status":"passed","title":"allows article.md (English source)","duration":0.5414940000000001,"failureMessages":[],"location":{"line":218,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["forbidden article.<lang>.md files"],"fullName":"forbidden article.<lang>.md files rejects multiple localized article files","status":"passed","title":"rejects multiple localized article files","duration":0.6721589999999651,"failureMessages":[],"location":{"line":225,"column":3},"meta":{},"tags":[]}],"startTime":1787953826891,"endTime":1787953826908.672,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-file-ownership-exec-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["Canonical schema constants"],"fullName":"Canonical schema constants declares exactly 7 canonical columns in order","status":"passed","title":"declares exactly 7 canonical columns in order","duration":3.8393279999999663,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Canonical schema constants"],"fullName":"Canonical schema constants lists riksdag-regering as a required server","status":"passed","title":"lists riksdag-regering as a required server","duration":1.2767200000000116,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection extracts the MCP Reliability section body","status":"passed","title":"extracts the MCP Reliability section body","duration":0.8495199999999841,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection returns null when the section is absent","status":"passed","title":"returns null when the section is absent","duration":0.4079039999999736,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractMCPSection"],"fullName":"extractMCPSection accepts the section header with an emoji preamble","status":"passed","title":"accepts the section header with an emoji preamble","duration":0.42613700000003973,"failureMessages":[],"location":{"line":153,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable parses header + data rows correctly","status":"passed","title":"parses header + data rows correctly","duration":2.4565190000000143,"failureMessages":[],"location":{"line":164,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable returns empty arrays when no table is present","status":"passed","title":"returns empty arrays when no table is present","duration":0.5411040000000185,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseMCPTable"],"fullName":"parseMCPTable preserves row order (rowIndex is 1-based)","status":"passed","title":"preserves row order (rowIndex is 1-based)","duration":0.4139350000000377,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — happy path"],"fullName":"validateMCPReliability — happy path PASSES a canonical manifest with riksdag-regering coverage","status":"passed","title":"PASSES a canonical manifest with riksdag-regering coverage","duration":2.5644609999999943,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — file-exists"],"fullName":"validateMCPReliability — file-exists reports error when manifest is missing","status":"passed","title":"reports error when manifest is missing","duration":0.5915480000000457,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — section-missing"],"fullName":"validateMCPReliability — section-missing reports error when §MCP Reliability heading is absent","status":"passed","title":"reports error when §MCP Reliability heading is absent","duration":1.0889890000000264,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — table-missing"],"fullName":"validateMCPReliability — table-missing reports error when section exists but no table is present","status":"passed","title":"reports error when section exists but no table is present","duration":0.8466350000000489,"failureMessages":[],"location":{"line":229,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — column-order"],"fullName":"validateMCPReliability — column-order reports error when columns are in the wrong order","status":"passed","title":"reports error when columns are in the wrong order","duration":0.9118870000000356,"failureMessages":[],"location":{"line":238,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — extra-columns (warning only)"],"fullName":"validateMCPReliability — extra-columns (warning only) warns but does not fail when extra columns are present","status":"passed","title":"warns but does not fail when extra columns are present","duration":0.9737729999999942,"failureMessages":[],"location":{"line":249,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — no-rows"],"fullName":"validateMCPReliability — no-rows reports error when the table has header but no data rows","status":"passed","title":"reports error when the table has header but no data rows","duration":0.9056860000000029,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — non-numeric-cell"],"fullName":"validateMCPReliability — non-numeric-cell reports error when a numeric cell is not an integer","status":"passed","title":"reports error when a numeric cell is not an integer","duration":0.9920470000000137,"failureMessages":[],"location":{"line":267,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — arithmetic-consistency"],"fullName":"validateMCPReliability — arithmetic-consistency reports error when successes + failures exceeds calls","status":"passed","title":"reports error when successes + failures exceeds calls","duration":0.9047239999999874,"failureMessages":[],"location":{"line":276,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — arithmetic-consistency"],"fullName":"validateMCPReliability — arithmetic-consistency accepts successes + failures < calls (pending-outcome case)","status":"passed","title":"accepts successes + failures < calls (pending-outcome case)","duration":0.8595490000000154,"failureMessages":[],"location":{"line":283,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMCPReliability — required-server"],"fullName":"validateMCPReliability — required-server reports error when riksdag-regering has no rows","status":"passed","title":"reports error when riksdag-regering has no rows","duration":0.9104950000000258,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]}],"startTime":1787953822829,"endTime":1787953822850.9104,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-mcp-reliability.test.ts"},{"assertionResults":[{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 0.8 for realtime-* folders","status":"passed","title":"returns 0.8 for realtime-* folders","duration":3.365111000000013,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 0.9 for evening-analysis","status":"passed","title":"returns 0.9 for evening-analysis","duration":0.4925819999999703,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 1.0 for week-ahead / weekly-review baselines","status":"passed","title":"returns 1.0 for week-ahead / weekly-review baselines","duration":0.5490379999999959,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier returns 1.3 for month-ahead, 1.5 for monthly-review","status":"passed","title":"returns 1.3 for month-ahead, 1.5 for monthly-review","duration":0.37845900000002075,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["derivePeriodMultiplier"],"fullName":"derivePeriodMultiplier defaults to 1.0 for unknown subfolders","status":"passed","title":"defaults to 1.0 for unknown subfolders","duration":0.4316580000000272,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder recognises all documented Tier-C folder names","status":"passed","title":"recognises all documented Tier-C folder names","duration":0.7102499999999736,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder recognises realtime-HHMM subfolders as Tier-C","status":"passed","title":"recognises realtime-HHMM subfolders as Tier-C","duration":0.415157000000022,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isTierCFolder"],"fullName":"isTierCFolder rejects doc-type leaf folders","status":"passed","title":"rejects doc-type leaf folders","duration":0.5397800000000075,"failureMessages":[],"location":{"line":184,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — happy paths"],"fullName":"validateMethodologyReflection — happy paths PASSES a full Tier-C fixture that satisfies every rule","status":"passed","title":"PASSES a full Tier-C fixture that satisfies every rule","duration":4.697534999999959,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — happy paths"],"fullName":"validateMethodologyReflection — happy paths PASSES a minimal doc-type fixture (Pipeline Overview + References)","status":"passed","title":"PASSES a minimal doc-type fixture (Pipeline Overview + References)","duration":0.9932900000000018,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — file-exists rule"],"fullName":"validateMethodologyReflection — file-exists rule reports error when file is missing","status":"passed","title":"reports error when file is missing","duration":0.7513659999999618,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule flags files below the scaled minimum","status":"passed","title":"flags files below the scaled minimum","duration":1.3021980000000326,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule applies the 1.3× multiplier for month-ahead folders","status":"passed","title":"applies the 1.3× multiplier for month-ahead folders","duration":2.1561679999999797,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — byte-floor rule"],"fullName":"validateMethodologyReflection — byte-floor rule applies the 1.5× multiplier for monthly-review","status":"passed","title":"applies the 1.5× multiplier for monthly-review","duration":0.9485050000000115,"failureMessages":[],"location":{"line":240,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule flags missing §Known Limitations in Tier-C","status":"passed","title":"flags missing §Known Limitations in Tier-C","duration":1.180059999999969,"failureMessages":[],"location":{"line":248,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"What Would Strengthen Future Runs\" for Pass-1 → Pass-2","status":"passed","title":"accepts synonym H2 \"What Would Strengthen Future Runs\" for Pass-1 → Pass-2","duration":1.0157520000000204,"failureMessages":[],"location":{"line":255,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"Recommendations for Codification\" for Recommendations","status":"passed","title":"accepts synonym H2 \"Recommendations for Codification\" for Recommendations","duration":1.0567890000000375,"failureMessages":[],"location":{"line":265,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule accepts synonym H2 \"Cross-References\" for References","status":"passed","title":"accepts synonym H2 \"Cross-References\" for References","duration":1.0302189999999882,"failureMessages":[],"location":{"line":275,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule flags missing §Data Source Connectivity Audit in Tier-C","status":"passed","title":"flags missing §Data Source Connectivity Audit in Tier-C","duration":1.1672159999999963,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — required-section rule"],"fullName":"validateMethodologyReflection — required-section rule does NOT require §Data Source Connectivity Audit in doc-type folders","status":"passed","title":"does NOT require §Data Source Connectivity Audit in doc-type folders","duration":0.918610000000001,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) flags Upstream Watchpoint Reconciliation section without a table","status":"passed","title":"flags Upstream Watchpoint Reconciliation section without a table","duration":1.086714000000029,"failureMessages":[],"location":{"line":305,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) flags Watchpoint section with table but no disposition keywords","status":"passed","title":"flags Watchpoint section with table but no disposition keywords","duration":1.1725359999999796,"failureMessages":[],"location":{"line":312,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — watchpoint-table rule (Tier-C only)"],"fullName":"validateMethodologyReflection — watchpoint-table rule (Tier-C only) does NOT apply watchpoint rules to doc-type folders","status":"passed","title":"does NOT apply watchpoint rules to doc-type folders","duration":0.8868309999999724,"failureMessages":[],"location":{"line":319,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — sibling-cross-reference rule (Tier-C only)"],"fullName":"validateMethodologyReflection — sibling-cross-reference rule (Tier-C only) flags a Tier-C file with no sibling-run links","status":"passed","title":"flags a Tier-C file with no sibling-run links","duration":0.9961950000000002,"failureMessages":[],"location":{"line":328,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — sibling-cross-reference rule (Tier-C only)"],"fullName":"validateMethodologyReflection — sibling-cross-reference rule (Tier-C only) does NOT require sibling links on doc-type folders","status":"passed","title":"does NOT require sibling links on doc-type folders","duration":0.9636539999999627,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — confidence-label rule (universal)"],"fullName":"validateMethodologyReflection — confidence-label rule (universal) flags any file without [HIGH] / [MEDIUM] / [LOW] tokens","status":"passed","title":"flags any file without [HIGH] / [MEDIUM] / [LOW] tokens","duration":0.9915260000000217,"failureMessages":[],"location":{"line":343,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — confidence-label rule (universal)"],"fullName":"validateMethodologyReflection — confidence-label rule (universal) accepts [VERY HIGH] as a valid confidence variant","status":"passed","title":"accepts [VERY HIGH] as a valid confidence variant","duration":0.9734429999999747,"failureMessages":[],"location":{"line":349,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — imf-primary-violation rule"],"fullName":"validateMethodologyReflection — imf-primary-violation rule warns when World Bank is used for GDP data (economic substitution)","status":"passed","title":"warns when World Bank is used for GDP data (economic substitution)","duration":1.0861740000000282,"failureMessages":[],"location":{"line":358,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateMethodologyReflection — imf-primary-violation rule"],"fullName":"validateMethodologyReflection — imf-primary-violation rule does not warn when World Bank is used for governance data","status":"passed","title":"does not warn when World Bank is used for governance data","duration":0.9447890000000143,"failureMessages":[],"location":{"line":370,"column":3},"meta":{},"tags":[]}],"startTime":1787953785234,"endTime":1787953785268.9448,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validate-methodology-reflection.test.ts"},{"assertionResults":[{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders exposes a non-empty PLACEHOLDER_PATTERNS array","status":"passed","title":"exposes a non-empty PLACEHOLDER_PATTERNS array","duration":3.5539440000000013,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders scanPlaceholders returns the matched literal for every hit","status":"passed","title":"scanPlaceholders returns the matched literal for every hit","duration":1.5008699999999635,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders checkPlaceholders emits one violation per pattern hit with stable code","status":"passed","title":"checkPlaceholders emits one violation per pattern hit with stable code","duration":0.7826450000000023,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — placeholders"],"fullName":"article rules — placeholders checkPlaceholders returns empty array for clean text","status":"passed","title":"checkPlaceholders returns empty array for clean text","duration":1.0181059999999889,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks REQUIRED_LANDMARKS includes Reader Intelligence Guide, Executive Brief, BLUF, Article Sources","status":"passed","title":"REQUIRED_LANDMARKS includes Reader Intelligence Guide, Executive Brief, BLUF, Article Sources","duration":0.6250410000000102,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks passes a complete fixture","status":"passed","title":"checkLandmarks passes a complete fixture","duration":1.078439000000003,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks reports every missing landmark for a stub document","status":"passed","title":"checkLandmarks reports every missing landmark for a stub document","duration":0.7611960000000408,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks flags duplicate Reader Intelligence Guide headings","status":"passed","title":"checkLandmarks flags duplicate Reader Intelligence Guide headings","duration":0.5208849999999643,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — landmarks"],"fullName":"article rules — landmarks checkLandmarks flags an empty Reader Intelligence Guide table","status":"passed","title":"checkLandmarks flags an empty Reader Intelligence Guide table","duration":0.5688350000000355,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers FOOTER_MARKER_PATTERNS covers ISMS / Classified under / Hack23 ISMS / Article-Generation / Provenance / GDPR","status":"passed","title":"FOOTER_MARKER_PATTERNS covers ISMS / Classified under / Hack23 ISMS / Article-Generation / Provenance / GDPR","duration":0.4631069999999795,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers checkFooterMarkers flags exact-duplicate footer lines","status":"passed","title":"checkFooterMarkers flags exact-duplicate footer lines","duration":1.047031000000004,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — footer markers"],"fullName":"article rules — footer markers checkFooterMarkers does NOT flag distinct footer lines with the same prefix","status":"passed","title":"checkFooterMarkers does NOT flag distinct footer lines with the same prefix","duration":0.36942200000004277,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document extractPerDocumentSections returns each ### dok_id heading with its body","status":"passed","title":"extractPerDocumentSections returns each ### dok_id heading with its body","duration":0.768447999999978,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document checkPerDocument flags sections lacking any dok_id","status":"passed","title":"checkPerDocument flags sections lacking any dok_id","duration":0.6908540000000016,"failureMessages":[],"location":{"line":168,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document DOK_ID_TOKEN_RE matches both H… and short-prefix codes","status":"passed","title":"DOK_ID_TOKEN_RE matches both H… and short-prefix codes","duration":0.49700999999998885,"failureMessages":[],"location":{"line":175,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — per-document"],"fullName":"article rules — per-document MIN_PER_DOC_DOK_ID_HITS is at least 1","status":"passed","title":"MIN_PER_DOC_DOK_ID_HITS is at least 1","duration":0.3886669999999981,"failureMessages":[],"location":{"line":180,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug permissiveSlug produces lowercased hyphen-separated tokens","status":"passed","title":"permissiveSlug produces lowercased hyphen-separated tokens","duration":0.9452299999999809,"failureMessages":[],"location":{"line":186,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug permissiveSlug returns empty string for symbol-only headings","status":"passed","title":"permissiveSlug returns empty string for symbol-only headings","duration":0.3656349999999975,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug checkHeadingSlugs flags a heading that produces an empty slug","status":"passed","title":"checkHeadingSlugs flags a heading that produces an empty slug","duration":0.538408000000004,"failureMessages":[],"location":{"line":196,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — slug"],"fullName":"article rules — slug checkHeadingSlugs is silent on well-formed headings","status":"passed","title":"checkHeadingSlugs is silent on well-formed headings","duration":0.44324000000000296,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — mermaid fences"],"fullName":"article rules — mermaid fences checkUnclosedMermaidFences returns empty for balanced fences","status":"passed","title":"checkUnclosedMermaidFences returns empty for balanced fences","duration":0.7630089999999541,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["article rules — mermaid fences"],"fullName":"article rules — mermaid fences checkUnclosedMermaidFences reports unclosed openings with line numbers in the message","status":"passed","title":"checkUnclosedMermaidFences reports unclosed openings with line numbers in the message","duration":0.9915270000000191,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]}],"startTime":1787953839200,"endTime":1787953839219.9915,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators-article-rules.test.ts"},{"assertionResults":[{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics writes the key metrics into matching DOM elements","status":"passed","title":"writes the key metrics into matching DOM elements","duration":20.982471000000032,"failureMessages":[],"location":{"line":393,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics warns and is a no-op when overview is missing","status":"passed","title":"warns and is a no-op when overview is missing","duration":1.5793069999999716,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderKeyMetrics"],"fullName":"CIADashboardRenderer renderKeyMetrics skips alert elements when riskAlerts.last90Days is missing","status":"passed","title":"skips alert elements when riskAlerts.last90Days is missing","duration":1.1289539999999647,"failureMessages":[],"location":{"line":425,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance builds bar + line charts with correct labels and party count","status":"passed","title":"builds bar + line charts with correct labels and party count","duration":3.968980999999985,"failureMessages":[],"location":{"line":443,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance warns and is a no-op when parties array is missing","status":"passed","title":"warns and is a no-op when parties array is missing","duration":1.4691209999999728,"failureMessages":[],"location":{"line":465,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance does not call Chart when Chart is undefined","status":"passed","title":"does not call Chart when Chart is undefined","duration":1.152417000000014,"failureMessages":[],"location":{"line":474,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderPartyPerformance"],"fullName":"CIADashboardRenderer renderPartyPerformance replaces invalid numeric metrics with 0 and unnamed shortName with \"Unknown\"","status":"passed","title":"replaces invalid numeric metrics with 0 and unnamed shortName with \"Unknown\"","duration":1.4169730000000413,"failureMessages":[],"location":{"line":486,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings renders one ranking-item per MP with name, party and influence score","status":"passed","title":"renders one ranking-item per MP with name, party and influence score","duration":5.898993999999959,"failureMessages":[],"location":{"line":508,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings renders \"N/A\" when influenceScore is NaN","status":"passed","title":"renders \"N/A\" when influenceScore is NaN","duration":2.065607,"failureMessages":[],"location":{"line":519,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings does nothing when the container is missing","status":"passed","title":"does nothing when the container is missing","duration":1.833923000000027,"failureMessages":[],"location":{"line":529,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderTop10Rankings"],"fullName":"CIADashboardRenderer renderTop10Rankings warns and clears when rankings is invalid","status":"passed","title":"warns and clears when rankings is invalid","duration":1.9078820000000292,"failureMessages":[],"location":{"line":537,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns produces a stacked bar chart with one dataset per party row","status":"passed","title":"produces a stacked bar chart with one dataset per party row","duration":1.4283250000000294,"failureMessages":[],"location":{"line":553,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns returns silently when canvas is missing","status":"passed","title":"returns silently when canvas is missing","duration":0.8928210000000263,"failureMessages":[],"location":{"line":563,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderVotingPatterns"],"fullName":"CIADashboardRenderer renderVotingPatterns warns when votingMatrix structure is invalid","status":"passed","title":"warns when votingMatrix structure is invalid","duration":1.1403349999999932,"failureMessages":[],"location":{"line":569,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork renders one committee-card per committee and a network note","status":"passed","title":"renders one committee-card per committee and a network note","duration":3.3599309999999605,"failureMessages":[],"location":{"line":585,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork formats missing/invalid stats as \"N/A\"","status":"passed","title":"formats missing/invalid stats as \"N/A\"","duration":2.273005000000012,"failureMessages":[],"location":{"line":598,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork warns and bails when committees is invalid","status":"passed","title":"warns and bails when committees is invalid","duration":1.0582410000000095,"failureMessages":[],"location":{"line":609,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderCommitteeNetwork"],"fullName":"CIADashboardRenderer renderCommitteeNetwork does nothing when container is missing","status":"passed","title":"does nothing when container is missing","duration":1.0004829999999743,"failureMessages":[],"location":{"line":617,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance renders one card per ministry with assessment tag","status":"passed","title":"renders one card per ministry with assessment tag","duration":2.1588919999999803,"failureMessages":[],"location":{"line":630,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance warns when ministry list is empty","status":"passed","title":"warns when ministry list is empty","duration":1.1065009999999802,"failureMessages":[],"location":{"line":638,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderMinistryPerformance"],"fullName":"CIADashboardRenderer renderMinistryPerformance falls back to \"N/A\" when effectiveness is missing","status":"passed","title":"falls back to \"N/A\" when effectiveness is missing","duration":2.016444999999976,"failureMessages":[],"location":{"line":648,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics builds gender + experience charts indexed by Riksdag party order","status":"passed","title":"builds gender + experience charts indexed by Riksdag party order","duration":10.217317999999977,"failureMessages":[],"location":{"line":663,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics warns and is a no-op when demographics arrays are missing","status":"passed","title":"warns and is a no-op when demographics arrays are missing","duration":1.1560249999999996,"failureMessages":[],"location":{"line":685,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDemographics"],"fullName":"CIADashboardRenderer renderDemographics does not crash when canvases are missing from DOM","status":"passed","title":"does not crash when canvases are missing from DOM","duration":1.0922939999999812,"failureMessages":[],"location":{"line":693,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDocumentActivity"],"fullName":"CIADashboardRenderer renderDocumentActivity produces a line chart with motions/bet/prop datasets in recent years","status":"passed","title":"produces a line chart with motions/bet/prop datasets in recent years","duration":1.6568120000000022,"failureMessages":[],"location":{"line":707,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderDocumentActivity"],"fullName":"CIADashboardRenderer renderDocumentActivity warns and is a no-op when document activity is malformed","status":"passed","title":"warns and is a no-op when document activity is malformed","duration":1.1970010000000002,"failureMessages":[],"location":{"line":719,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution groups entries by YYYY-MM and renders sorted descending","status":"passed","title":"groups entries by YYYY-MM and renders sorted descending","duration":2.5353870000000143,"failureMessages":[],"location":{"line":734,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution warns and is a no-op for empty entries","status":"passed","title":"warns and is a no-op for empty entries","duration":1.2687250000000176,"failureMessages":[],"location":{"line":747,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","renderRiskEvolution"],"fullName":"CIADashboardRenderer renderRiskEvolution does nothing when the container is missing","status":"passed","title":"does nothing when the container is missing","duration":1.066255999999953,"failureMessages":[],"location":{"line":757,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","destroy"],"fullName":"CIADashboardRenderer destroy calls destroy() on every chart instance and clears the map","status":"passed","title":"calls destroy() on every chart instance and clears the map","duration":1.628088000000048,"failureMessages":[],"location":{"line":770,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer","destroy"],"fullName":"CIADashboardRenderer destroy is a safe no-op when no charts have been created","status":"passed","title":"is a safe no-op when no charts have been created","duration":3.350885999999946,"failureMessages":[],"location":{"line":786,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["CIADashboardRenderer"],"fullName":"CIADashboardRenderer drives all 9 renderers end-to-end without throwing","status":"passed","title":"drives all 9 renderers end-to-end without throwing","duration":4.82669599999997,"failureMessages":[],"location":{"line":797,"column":3},"meta":{},"tags":[]}],"startTime":1787953661774,"endTime":1787953661864.8267,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/visualizations.test.ts"},{"assertionResults":[{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the news-articles page set (recurse: true)","status":"passed","title":"registers the news-articles page set (recurse: true)","duration":3.813729999999964,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the sitemaps page set with all 14 language variants","status":"passed","title":"registers the sitemaps page set with all 14 language variants","duration":1.6471940000000131,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the political-intelligence page set with all 14 language variants","status":"passed","title":"registers the political-intelligence page set with all 14 language variants","duration":1.7255309999999895,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets registers the dashboards page set so /dashboards/*.html is served by vite preview","status":"passed","title":"registers the dashboards page set so /dashboards/*.html is served by vite preview","duration":0.5464430000000107,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite.config.js — staticPagesPlugin pageSets"],"fullName":"vite.config.js — staticPagesPlugin pageSets every directory listed in build-dashboard-pages.py output exists on disk","status":"passed","title":"every directory listed in build-dashboard-pages.py output exists on disk","duration":0.9513120000000299,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]}],"startTime":1787953906384,"endTime":1787953906392.9514,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-config-page-sets.test.ts"},{"assertionResults":[{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites root-level styles.css href to the stable bundle path (no SRI)","status":"passed","title":"rewrites root-level styles.css href to the stable bundle path (no SRI)","duration":7.474053000000026,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites ../styles.css references for one-level-deep pages","status":"passed","title":"rewrites ../styles.css references for one-level-deep pages","duration":1.7830890000000181,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages emits every HTML file in a directory page set and creates parent directories","status":"passed","title":"emits every HTML file in a directory page set and creates parent directories","duration":2.539484000000016,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages leaves pages without a styles.css link unchanged but still emits them","status":"passed","title":"leaves pages without a styles.css link unchanged but still emits them","duration":1.2886829999999918,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages falls back to scanning dist/assets/ when the manifest lacks a styles.css entry","status":"passed","title":"falls back to scanning dist/assets/ when the manifest lacks a styles.css entry","duration":1.0981859999999983,"failureMessages":[],"location":{"line":178,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages discovers a legacy hashed styles-*.css when the stable bundle is absent","status":"passed","title":"discovers a legacy hashed styles-*.css when the stable bundle is absent","duration":1.4320109999999886,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages throws a descriptive error when the bundled styles.css cannot be located","status":"passed","title":"throws a descriptive error when the bundled styles.css cannot be located","duration":2.4716869999999744,"failureMessages":[],"location":{"line":221,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages skips missing source entries silently rather than failing the build","status":"passed","title":"skips missing source entries silently rather than failing the build","duration":1.1527879999999868,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages preserves pre-existing attributes on the <link rel=\"stylesheet\"> tag","status":"passed","title":"preserves pre-existing attributes on the <link rel=\"stylesheet\"> tag","duration":1.6243709999999965,"failureMessages":[],"location":{"line":246,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages exposes the Vite plugin contract (apply, enforce, name, closeBundle hook)","status":"passed","title":"exposes the Vite plugin contract (apply, enforce, name, closeBundle hook)","duration":0.9381060000000048,"failureMessages":[],"location":{"line":274,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites <script type=\"module\" src=\"/src/browser/main.ts\"> → hashed bundle from manifest","status":"passed","title":"rewrites <script type=\"module\" src=\"/src/browser/main.ts\"> → hashed bundle from manifest","duration":2.2010310000000004,"failureMessages":[],"location":{"line":317,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages falls back to scanning dist/assets/js/ when manifest lacks a src/browser/<name>.ts entry","status":"passed","title":"falls back to scanning dist/assets/js/ when manifest lacks a src/browser/<name>.ts entry","duration":1.4021949999999492,"failureMessages":[],"location":{"line":348,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages leaves the dev script tag untouched when no hashed bundle can be resolved","status":"passed","title":"leaves the dev script tag untouched when no hashed bundle can be resolved","duration":1.148239999999987,"failureMessages":[],"location":{"line":372,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not rewrite script tags whose src does not match /src/browser/<name>.ts","status":"passed","title":"does not rewrite script tags whose src does not match /src/browser/<name>.ts","duration":1.209103999999968,"failureMessages":[],"location":{"line":394,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not duplicate the crossorigin attribute when the source tag already has one","status":"passed","title":"does not duplicate the crossorigin attribute when the source tag already has one","duration":1.4629679999999894,"failureMessages":[],"location":{"line":421,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages does not rewrite a non-module <script> tag whose src points at /src/browser/<name>.ts","status":"passed","title":"does not rewrite a non-module <script> tag whose src points at /src/browser/<name>.ts","duration":1.3695839999999748,"failureMessages":[],"location":{"line":455,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-static-pages"],"fullName":"vite-plugin-static-pages rewrites the dev script tag across many pages but resolves the manifest only once per entry","status":"passed","title":"rewrites the dev script tag across many pages but resolves the manifest only once per entry","duration":1.6498589999999922,"failureMessages":[],"location":{"line":487,"column":3},"meta":{},"tags":[]}],"startTime":1787953681302,"endTime":1787953681334.65,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-plugin-static-pages.test.ts"},{"assertionResults":[{"ancestorTitles":["vite-plugin-sw-build-id — plugin shape"],"fullName":"vite-plugin-sw-build-id — plugin shape exports a factory that returns the expected Vite plugin shape","status":"passed","title":"exports a factory that returns the expected Vite plugin shape","duration":10.034611999999981,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler substitutes __BUILD_ID__ with a GITHUB_SHA-derived value","status":"passed","title":"substitutes __BUILD_ID__ with a GITHUB_SHA-derived value","duration":1.603652000000011,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler substitutes __BUILD_ID__ via git fallback when GITHUB_SHA is not set","status":"passed","title":"substitutes __BUILD_ID__ via git fallback when GITHUB_SHA is not set","duration":7.125664000000029,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler replaces ALL occurrences of __BUILD_ID__ in the source file","status":"passed","title":"replaces ALL occurrences of __BUILD_ID__ in the source file","duration":1.0141990000000192,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — closeBundle handler"],"fullName":"vite-plugin-sw-build-id — closeBundle handler supports a custom outDir option","status":"passed","title":"supports a custom outDir option","duration":0.860320999999999,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — error paths"],"fullName":"vite-plugin-sw-build-id — error paths throws when public/sw.js does not exist","status":"passed","title":"throws when public/sw.js does not exist","duration":1.79283700000002,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["vite-plugin-sw-build-id — error paths"],"fullName":"vite-plugin-sw-build-id — error paths throws when sw.js is missing the __BUILD_ID__ placeholder","status":"passed","title":"throws when sw.js is missing the __BUILD_ID__ placeholder","duration":0.9704380000000015,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]}],"startTime":1787953849178,"endTime":1787953849201.9705,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/vite-plugin-sw-build-id.test.ts"},{"assertionResults":[{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should create client with default configuration","status":"passed","title":"should create client with default configuration","duration":4.414615999999967,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should accept custom configuration","status":"passed","title":"should accept custom configuration","duration":0.8693380000000275,"failureMessages":[],"location":{"line":45,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","constructor"],"fullName":"WorldBankClient constructor should use default values for partial config","status":"passed","title":"should use default values for partial config","duration":0.6595649999999864,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should sort results by date descending","status":"passed","title":"should sort results by date descending","duration":2.414009999999962,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return data points for valid API response","status":"passed","title":"should return data points for valid API response","duration":1.4006630000000087,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should filter out null values","status":"passed","title":"should filter out null values","duration":0.8028120000000172,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return empty array for invalid API response","status":"passed","title":"should return empty array for invalid API response","duration":0.7106410000000096,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should return empty array for non-array response","status":"passed","title":"should return empty array for non-array response","duration":0.7366200000000163,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should construct correct URL","status":"passed","title":"should construct correct URL","duration":3.5657959999999775,"failureMessages":[],"location":{"line":187,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should retry on failure","status":"passed","title":"should retry on failure","duration":1002.3510030000001,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should throw after max retries","status":"passed","title":"should throw after max retries","duration":2.678863000000092,"failureMessages":[],"location":{"line":233,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getIndicator"],"fullName":"WorldBankClient getIndicator should handle HTTP error responses","status":"passed","title":"should handle HTTP error responses","duration":0.7566369999999552,"failureMessages":[],"location":{"line":240,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getLatestIndicator"],"fullName":"WorldBankClient getLatestIndicator should return the first data point","status":"passed","title":"should return the first data point","duration":0.8096160000000054,"failureMessages":[],"location":{"line":253,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getLatestIndicator"],"fullName":"WorldBankClient getLatestIndicator should return null when no data available","status":"passed","title":"should return null when no data available","duration":0.6784800000000359,"failureMessages":[],"location":{"line":276,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","compareCountries"],"fullName":"WorldBankClient compareCountries should return comparison map for multiple countries","status":"passed","title":"should return comparison map for multiple countries","duration":0.8772819999999228,"failureMessages":[],"location":{"line":288,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","compareCountries"],"fullName":"WorldBankClient compareCountries should handle errors for individual countries gracefully","status":"passed","title":"should handle errors for individual countries gracefully","duration":0.8800979999998617,"failureMessages":[],"location":{"line":325,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have Sweden","status":"passed","title":"should have Sweden","duration":0.5875500000001921,"failureMessages":[],"location":{"line":351,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have all Nordic countries","status":"passed","title":"should have all Nordic countries","duration":0.5843139999999494,"failureMessages":[],"location":{"line":355,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have Germany for EU comparison","status":"passed","title":"should have Germany for EU comparison","duration":0.543327999999974,"failureMessages":[],"location":{"line":361,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","COUNTRY_CODES"],"fullName":"WorldBankClient COUNTRY_CODES should have EU aggregate","status":"passed","title":"should have EU aggregate","duration":0.589813999999933,"failureMessages":[],"location":{"line":365,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdp\" (NY.GDP.MKTP.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdp\" (NY.GDP.MKTP.CD) — IMF supplies that context","duration":0.6778090000000248,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdpGrowth\" (NY.GDP.MKTP.KD.ZG) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdpGrowth\" (NY.GDP.MKTP.KD.ZG) — IMF supplies that context","duration":0.5375359999998182,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"gdpPerCapita\" (NY.GDP.PCAP.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"gdpPerCapita\" (NY.GDP.PCAP.CD) — IMF supplies that context","duration":0.49398500000006607,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"unemployment\" (SL.UEM.TOTL.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"unemployment\" (SL.UEM.TOTL.ZS) — IMF supplies that context","duration":0.5231800000001385,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"inflation\" (FP.CPI.TOTL.ZG) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"inflation\" (FP.CPI.TOTL.ZG) — IMF supplies that context","duration":0.5122890000000098,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"consumerPriceIndex\" (FP.CPI.TOTL) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"consumerPriceIndex\" (FP.CPI.TOTL) — IMF supplies that context","duration":0.5354119999999511,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"govExpenditure\" (GC.XPN.TOTL.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"govExpenditure\" (GC.XPN.TOTL.GD.ZS) — IMF supplies that context","duration":0.4881639999998697,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"govRevenue\" (GC.REV.XGRT.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"govRevenue\" (GC.REV.XGRT.GD.ZS) — IMF supplies that context","duration":0.5668410000000677,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"taxRevenue\" (GC.TAX.TOTL.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"taxRevenue\" (GC.TAX.TOTL.GD.ZS) — IMF supplies that context","duration":0.5958659999998872,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"currentAccountBalance\" (BN.CAB.XOKA.GD.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"currentAccountBalance\" (BN.CAB.XOKA.GD.ZS) — IMF supplies that context","duration":0.5417740000000322,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"exportsGdpPct\" (NE.EXP.GNFS.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"exportsGdpPct\" (NE.EXP.GNFS.ZS) — IMF supplies that context","duration":0.6411600000001272,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"importsGdpPct\" (NE.IMP.GNFS.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"importsGdpPct\" (NE.IMP.GNFS.ZS) — IMF supplies that context","duration":0.9431460000000698,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"fdiNet\" (BN.KLT.DINV.CD) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"fdiNet\" (BN.KLT.DINV.CD) — IMF supplies that context","duration":0.6130679999998847,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"realInterestRate\" (FR.INR.RINR) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"realInterestRate\" (FR.INR.RINR) — IMF supplies that context","duration":0.6472429999998894,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"lendingRate\" (FR.INR.LEND) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"lendingRate\" (FR.INR.LEND) — IMF supplies that context","duration":2.527462000000014,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope INDICATOR_IDS does not expose economic key \"laborForceParticipation\" (SL.TLF.CACT.ZS) — IMF supplies that context","status":"passed","title":"INDICATOR_IDS does not expose economic key \"laborForceParticipation\" (SL.TLF.CACT.ZS) — IMF supplies that context","duration":0.6244690000000901,"failureMessages":[],"location":{"line":389,"column":16},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope includes the World Bank coverage areas (military, environment, governance, demographics, health, education)","status":"passed","title":"includes the World Bank coverage areas (military, environment, governance, demographics, health, education)","duration":0.7048399999998765,"failureMessages":[],"location":{"line":396,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope defines a meaningful number of World Bank indicators","status":"passed","title":"defines a meaningful number of World Bank indicators","duration":0.6671389999999064,"failureMessages":[],"location":{"line":405,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope uses a valid World Bank indicator ID format for every entry","status":"passed","title":"uses a valid World Bank indicator ID format for every entry","duration":1.801812999999811,"failureMessages":[],"location":{"line":409,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope must cover every non-economic Riksdag-relevant domain","status":"passed","title":"must cover every non-economic Riksdag-relevant domain","duration":1.094128999999839,"failureMessages":[],"location":{"line":415,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","INDICATOR_IDS — World Bank scope"],"fullName":"WorldBankClient INDICATOR_IDS — World Bank scope should stay in sync with JSON inventory (single source of truth)","status":"passed","title":"should stay in sync with JSON inventory (single source of truth)","duration":4.245097999999871,"failureMessages":[],"location":{"line":437,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should contain 6 governance indicator IDs","status":"passed","title":"should contain 6 governance indicator IDs","duration":0.802122000000054,"failureMessages":[],"location":{"line":469,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should include all WGI estimate indicators","status":"passed","title":"should include all WGI estimate indicators","duration":0.870209000000159,"failureMessages":[],"location":{"line":473,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI_INDICATOR_IDS"],"fullName":"WorldBankClient WGI_INDICATOR_IDS should match governance indicators in INDICATOR_IDS","status":"passed","title":"should match governance indicators in INDICATOR_IDS","duration":1.1315089999998236,"failureMessages":[],"location":{"line":482,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WB_SOURCES"],"fullName":"WorldBankClient WB_SOURCES should have WDI source as 2","status":"passed","title":"should have WDI source as 2","duration":0.8523559999998724,"failureMessages":[],"location":{"line":493,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WB_SOURCES"],"fullName":"WorldBankClient WB_SOURCES should have WGI source as 75","status":"passed","title":"should have WGI source as 75","duration":0.9991410000000087,"failureMessages":[],"location":{"line":497,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI source parameter in URL"],"fullName":"WorldBankClient WGI source parameter in URL should add source=75 for WGI indicators","status":"passed","title":"should add source=75 for WGI indicators","duration":1.0981259999998656,"failureMessages":[],"location":{"line":503,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","WGI source parameter in URL"],"fullName":"WorldBankClient WGI source parameter in URL should NOT add source parameter for WDI indicators","status":"passed","title":"should NOT add source parameter for WDI indicators","duration":1.0102810000000773,"failureMessages":[],"location":{"line":513,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getDefaultWorldBankClient"],"fullName":"WorldBankClient getDefaultWorldBankClient should return a singleton instance","status":"passed","title":"should return a singleton instance","duration":0.9003459999998995,"failureMessages":[],"location":{"line":525,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["WorldBankClient","getDefaultWorldBankClient"],"fullName":"WorldBankClient getDefaultWorldBankClient should have default configuration","status":"passed","title":"should have default configuration","duration":0.8592289999999139,"failureMessages":[],"location":{"line":531,"column":5},"meta":{},"tags":[]}],"startTime":1787953683913,"endTime":1787953684969.8591,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/world-bank-client.test.ts"},{"assertionResults":[{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only should define at least 8 indicators","status":"passed","title":"should define at least 8 indicators","duration":3.7755989999999997,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only should have required fields for each indicator","status":"passed","title":"should have required fields for each indicator","duration":11.793150999999966,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.MKTP.KD.ZG\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.MKTP.KD.ZG\" because economic context routes through IMF","duration":0.656819999999982,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.MKTP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.MKTP.CD\" because economic context routes through IMF","duration":0.3772870000000239,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GDP.PCAP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GDP.PCAP.CD\" because economic context routes through IMF","duration":0.5584759999999847,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GNP.MKTP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GNP.MKTP.CD\" because economic context routes through IMF","duration":0.3920840000000112,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NY.GNP.PCAP.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NY.GNP.PCAP.CD\" because economic context routes through IMF","duration":0.48194200000000365,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FP.CPI.TOTL.ZG\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FP.CPI.TOTL.ZG\" because economic context routes through IMF","duration":0.35533500000002505,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FP.CPI.TOTL\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FP.CPI.TOTL\" because economic context routes through IMF","duration":0.5191020000000321,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"SL.UEM.TOTL.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"SL.UEM.TOTL.ZS\" because economic context routes through IMF","duration":0.3743610000000217,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"SL.TLF.CACT.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"SL.TLF.CACT.ZS\" because economic context routes through IMF","duration":0.4190240000000358,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.XPN.TOTL.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.XPN.TOTL.GD.ZS\" because economic context routes through IMF","duration":0.35330099999998765,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.REV.XGRT.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.REV.XGRT.GD.ZS\" because economic context routes through IMF","duration":0.32436799999999266,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"GC.DOD.TOTL.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"GC.DOD.TOTL.GD.ZS\" because economic context routes through IMF","duration":0.4722840000000019,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"BN.CAB.XOKA.GD.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"BN.CAB.XOKA.GD.ZS\" because economic context routes through IMF","duration":0.35246000000000777,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"BN.KLT.DINV.CD\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"BN.KLT.DINV.CD\" because economic context routes through IMF","duration":0.4005700000000161,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NE.EXP.GNFS.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NE.EXP.GNFS.ZS\" because economic context routes through IMF","duration":0.3380939999999555,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"NE.IMP.GNFS.ZS\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"NE.IMP.GNFS.ZS\" because economic context routes through IMF","duration":0.3786190000000147,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"TX.VAL.MRCH.CD.WT\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"TX.VAL.MRCH.CD.WT\" because economic context routes through IMF","duration":0.3784379999999601,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FR.INR.RINR\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FR.INR.RINR\" because economic context routes through IMF","duration":0.37654500000002145,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only inventory excludes economic indicator \"FR.INR.LEND\" because economic context routes through IMF","status":"passed","title":"inventory excludes economic indicator \"FR.INR.LEND\" because economic context routes through IMF","duration":0.40990799999997307,"failureMessages":[],"location":{"line":75,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include military expenditure (defence historicals — non-economic residue)","status":"passed","title":"must include military expenditure (defence historicals — non-economic residue)","duration":1.5688580000000343,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include CO₂ emissions (environment residue)","status":"passed","title":"must include CO₂ emissions (environment residue)","duration":0.8228200000000356,"failureMessages":[],"location":{"line":90,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must include WGI governance indicators (residue)","status":"passed","title":"must include WGI governance indicators (residue)","duration":0.802643000000046,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","WORLD_BANK_INDICATORS — non-economic residue only"],"fullName":"world-bank-context WORLD_BANK_INDICATORS — non-economic residue only must map every indicator to a valid Riksdag committee","status":"passed","title":"must map every indicator to a valid Riksdag committee","duration":5.68397200000004,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have all 14 supported languages","status":"passed","title":"should have all 14 supported languages","duration":1.3072879999999714,"failureMessages":[],"location":{"line":120,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have all 5 section headings per language","status":"passed","title":"should have all 5 section headings per language","duration":1.082407000000046,"failureMessages":[],"location":{"line":128,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have non-empty strings for all headings","status":"passed","title":"should have non-empty strings for all headings","duration":2.427886000000001,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have correct English headings","status":"passed","title":"should have correct English headings","duration":0.5602989999999863,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","ECONOMIC_SECTION_HEADINGS"],"fullName":"world-bank-context ECONOMIC_SECTION_HEADINGS should have correct Swedish headings","status":"passed","title":"should have correct Swedish headings","duration":0.5734630000000038,"failureMessages":[],"location":{"line":155,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","NORDIC_COMPARISON"],"fullName":"world-bank-context NORDIC_COMPARISON should include Sweden and 4 comparison countries","status":"passed","title":"should include Sweden and 4 comparison countries","duration":1.5170309999999745,"failureMessages":[],"location":{"line":167,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","NORDIC_COMPARISON"],"fullName":"world-bank-context NORDIC_COMPARISON should have country names for all countries","status":"passed","title":"should have country names for all countries","duration":0.6488650000000007,"failureMessages":[],"location":{"line":176,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should return correct English heading","status":"passed","title":"should return correct English heading","duration":0.5057369999999537,"failureMessages":[],"location":{"line":185,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should return correct Swedish heading","status":"passed","title":"should return correct Swedish heading","duration":0.3923449999999775,"failureMessages":[],"location":{"line":191,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should fallback to English for unsupported language","status":"passed","title":"should fallback to English for unsupported language","duration":0.39031099999999697,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should fallback to English for null language","status":"passed","title":"should fallback to English for null language","duration":0.443300000000022,"failureMessages":[],"location":{"line":199,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getEconomicHeading"],"fullName":"world-bank-context getEconomicHeading should handle all 14 languages","status":"passed","title":"should handle all 14 languages","duration":0.7204790000000116,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","duration":1.2477859999999623,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","duration":0.7204690000000369,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","duration":0.6528319999999894,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","duration":0.6972350000000347,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","duration":0.7238360000000057,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","duration":0.6592640000000074,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FP.CPI.TOTL\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FP.CPI.TOTL\" (IMF-routed)","duration":0.8462139999999749,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","duration":0.7218519999999558,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","duration":0.718213999999989,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","duration":0.6877179999999612,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","duration":0.9005860000000325,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","duration":0.7893169999999827,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","duration":0.7353269999999839,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","duration":0.7351170000000025,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","duration":0.7525290000000382,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","duration":0.8407240000000229,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","duration":0.8142739999999549,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FR.INR.RINR\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FR.INR.RINR\" (IMF-routed)","duration":0.8045460000000162,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators no policy-area query returns economic indicator \"FR.INR.LEND\" (IMF-routed)","status":"passed","title":"no policy-area query returns economic indicator \"FR.INR.LEND\" (IMF-routed)","duration":0.8485089999999786,"failureMessages":[],"location":{"line":214,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must find defence indicators for NATO queries (defence historicals — non-economic residue)","status":"passed","title":"must find defence indicators for NATO queries (defence historicals — non-economic residue)","duration":0.7479910000000132,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must find climate indicators (environment residue)","status":"passed","title":"must find climate indicators (environment residue)","duration":0.9680619999999749,"failureMessages":[],"location":{"line":231,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return an array (never undefined) for any committee query","status":"passed","title":"must return an array (never undefined) for any committee query","duration":1.1793279999999982,"failureMessages":[],"location":{"line":236,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return empty for unrelated queries","status":"passed","title":"must return empty for unrelated queries","duration":0.7163210000000504,"failureMessages":[],"location":{"line":242,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must return empty for empty / whitespace queries","status":"passed","title":"must return empty for empty / whitespace queries","duration":0.7676379999999767,"failureMessages":[],"location":{"line":246,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","findRelevantIndicators"],"fullName":"world-bank-context findRelevantIndicators must be case-insensitive","status":"passed","title":"must be case-insensitive","duration":0.7224420000000009,"failureMessages":[],"location":{"line":251,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries must return queries for all configured indicators","status":"passed","title":"must return queries for all configured indicators","duration":0.7982749999999896,"failureMessages":[],"location":{"line":257,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries must use SWE country code for all queries","status":"passed","title":"must use SWE country code for all queries","duration":1.7319630000000075,"failureMessages":[],"location":{"line":262,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.MKTP.KD.ZG\" (IMF-routed)","duration":0.7989960000000451,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.MKTP.CD\" (IMF-routed)","duration":0.8320180000000619,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GDP.PCAP.CD\" (IMF-routed)","duration":0.9461509999999862,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GNP.MKTP.CD\" (IMF-routed)","duration":0.829091999999946,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NY.GNP.PCAP.CD\" (IMF-routed)","duration":0.8700390000000198,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FP.CPI.TOTL.ZG\" (IMF-routed)","duration":0.8444610000000239,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FP.CPI.TOTL\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FP.CPI.TOTL\" (IMF-routed)","duration":0.9360530000000153,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"SL.UEM.TOTL.ZS\" (IMF-routed)","duration":0.9498780000000124,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"SL.TLF.CACT.ZS\" (IMF-routed)","duration":0.9731820000000653,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.XPN.TOTL.GD.ZS\" (IMF-routed)","duration":0.990224000000012,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.REV.XGRT.GD.ZS\" (IMF-routed)","duration":1.174227999999971,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"GC.DOD.TOTL.GD.ZS\" (IMF-routed)","duration":1.029728000000091,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"BN.CAB.XOKA.GD.ZS\" (IMF-routed)","duration":2.0371939999999995,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"BN.KLT.DINV.CD\" (IMF-routed)","duration":0.8933329999999842,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NE.EXP.GNFS.ZS\" (IMF-routed)","duration":1.061868000000004,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"NE.IMP.GNFS.ZS\" (IMF-routed)","duration":1.040789000000018,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"TX.VAL.MRCH.CD.WT\" (IMF-routed)","duration":0.9594559999999319,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FR.INR.RINR\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FR.INR.RINR\" (IMF-routed)","duration":0.9731520000000273,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","getSwedishIndicatorQueries"],"fullName":"world-bank-context getSwedishIndicatorQueries committee query does not request economic indicator \"FR.INR.LEND\" (IMF-routed)","status":"passed","title":"committee query does not request economic indicator \"FR.INR.LEND\" (IMF-routed)","duration":1.172354999999925,"failureMessages":[],"location":{"line":268,"column":39},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect GDP / unemployment / inflation in English","status":"passed","title":"must detect GDP / unemployment / inflation in English","duration":1.8837670000000344,"failureMessages":[],"location":{"line":278,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect IMF as the primary economic data source","status":"passed","title":"must detect IMF as the primary economic data source","duration":1.2098949999999604,"failureMessages":[],"location":{"line":284,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect canonical IMF citation strings (DATABASE:INDICATOR_ID)","status":"passed","title":"must detect canonical IMF citation strings (DATABASE:INDICATOR_ID)","duration":1.7913029999999708,"failureMessages":[],"location":{"line":289,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect IMF projection vintage tags","status":"passed","title":"must detect IMF projection vintage tags","duration":1.2184710000000223,"failureMessages":[],"location":{"line":301,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect Swedish economic terms","status":"passed","title":"must detect Swedish economic terms","duration":1.1818630000000212,"failureMessages":[],"location":{"line":306,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must detect non-economic WB residue indicator IDs (defence, environment, governance)","status":"passed","title":"must detect non-economic WB residue indicator IDs (defence, environment, governance)","duration":1.1285930000000235,"failureMessages":[],"location":{"line":316,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context","hasEconomicContext"],"fullName":"world-bank-context hasEconomicContext must return false for content without economic context","status":"passed","title":"must return false for content without economic context","duration":1.5357460000000174,"failureMessages":[],"location":{"line":322,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage WORLD_BANK_INDICATORS is a non-empty array (inventory loaded successfully)","status":"passed","title":"WORLD_BANK_INDICATORS is a non-empty array (inventory loaded successfully)","duration":1.6509020000000874,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getSwedishIndicatorQueries returns a non-empty array with countryCode and indicatorId","status":"passed","title":"getSwedishIndicatorQueries returns a non-empty array with countryCode and indicatorId","duration":5.789711000000011,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage findRelevantIndicators matches by committee abbreviation (case-insensitive)","status":"passed","title":"findRelevantIndicators matches by committee abbreviation (case-insensitive)","duration":2.6178820000000087,"failureMessages":[],"location":{"line":351,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getEconomicHeading returns undefined for an unknown section key","status":"passed","title":"getEconomicHeading returns undefined for an unknown section key","duration":2.0176380000000336,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["world-bank-context — utility function coverage"],"fullName":"world-bank-context — utility function coverage getEconomicHeading returns all 5 sections for every supported language","status":"passed","title":"getEconomicHeading returns all 5 sections for every supported language","duration":4.53244600000005,"failureMessages":[],"location":{"line":365,"column":3},"meta":{},"tags":[]}],"startTime":1787953786279,"endTime":1787953786394.5325,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/world-bank-context.test.ts"},{"assertionResults":[{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory defines exactly 23 required artifacts","status":"passed","title":"defines exactly 23 required artifacts","duration":5.405281000000059,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family A has 9 artifacts","status":"passed","title":"Family A has 9 artifacts","duration":1.0946489999998903,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family B has 2 artifacts","status":"passed","title":"Family B has 2 artifacts","duration":0.7374509999999646,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family C has 5 artifacts","status":"passed","title":"Family C has 5 artifacts","duration":0.7362590000000182,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory Family D has 7 artifacts","status":"passed","title":"Family D has 7 artifacts","duration":0.8112390000000005,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory all artifact filenames end with .md","status":"passed","title":"all artifact filenames end with .md","duration":1.599544999999921,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory REQUIRED_ARTIFACT_FILENAMES matches ALL_REQUIRED_ARTIFACTS count","status":"passed","title":"REQUIRED_ARTIFACT_FILENAMES matches ALL_REQUIRED_ARTIFACTS count","duration":0.8262470000000803,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory MERMAID_REQUIRED_ARTIFACTS is a subset of all artifacts","status":"passed","title":"MERMAID_REQUIRED_ARTIFACTS is a subset of all artifacts","duration":1.864661999999953,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory PASS2_REQUIRED_ARTIFACTS excludes data-download-manifest.md","status":"passed","title":"PASS2_REQUIRED_ARTIFACTS excludes data-download-manifest.md","duration":0.818012000000067,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory STUB_PLACEHOLDERS contains expected markers","status":"passed","title":"STUB_PLACEHOLDERS contains expected markers","duration":0.7645819999999048,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory RECOGNISED_AGENCIES contains known Swedish agencies","status":"passed","title":"RECOGNISED_AGENCIES contains known Swedish agencies","duration":0.9655579999999873,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory EVIDENCE_URL_HOSTS covers all required primary sources","status":"passed","title":"EVIDENCE_URL_HOSTS covers all required primary sources","duration":0.6758549999999559,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory DOK_ID_PATTERN matches valid Riksdag document IDs","status":"passed","title":"DOK_ID_PATTERN matches valid Riksdag document IDs","duration":0.7720359999999573,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["Artifact Inventory"],"fullName":"Artifact Inventory EVIDENCE_PATTERN matches dok_ids and URL hosts","status":"passed","title":"EVIDENCE_PATTERN matches dok_ids and URL hosts","duration":0.8520759999998972,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) returns passed=true for a fully seeded analysis directory","status":"passed","title":"returns passed=true for a fully seeded analysis directory","duration":26.493137000000047,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) returns passed=false and aggregates check failures for an empty directory","status":"passed","title":"returns passed=false and aggregates check failures for an empty directory","duration":1.6016889999999648,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateAnalysisGate (orchestrator)"],"fullName":"validateAnalysisGate (orchestrator) reports the dok_id that lacks per-document coverage","status":"passed","title":"reports the dok_id that lacks per-document coverage","duration":12.802580999999918,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953868266,"endTime":1787953868325.8025,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/analysis-gate-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting passes through a simple field","status":"passed","title":"passes through a simple field","duration":3.6739600000000223,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing commas","status":"passed","title":"quotes fields containing commas","duration":0.5773909999999773,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing double quotes and doubles them","status":"passed","title":"quotes fields containing double quotes and doubles them","duration":0.43709799999999177,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting quotes fields containing CR or LF","status":"passed","title":"quotes fields containing CR or LF","duration":0.41849399999995285,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting treats null-ish input as empty string","status":"passed","title":"treats null-ish input as empty string","duration":0.5861170000000016,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting serialiseRow emits columns in CSV_COLUMNS order","status":"passed","title":"serialiseRow emits columns in CSV_COLUMNS order","duration":0.5096749999999588,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: RFC 4180 quoting"],"fullName":"report-writer: RFC 4180 quoting CSV_COLUMNS matches the issue spec","status":"passed","title":"CSV_COLUMNS matches the issue spec","duration":1.4093900000000303,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport emits one row per (tier, violation) pair","status":"passed","title":"emits one row per (tier, violation) pair","duration":1.7428939999999784,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport emits one per-tier row with blank violation fields when contract is green","status":"passed","title":"emits one per-tier row with blank violation fields when contract is green","duration":0.8980910000000222,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport emits a header-only file when rows are empty","status":"passed","title":"writeReport emits a header-only file when rows are empty","duration":0.9807159999999726,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport creates missing parent directories","status":"passed","title":"writeReport creates missing parent directories","duration":0.9302420000000211,"failureMessages":[],"location":{"line":130,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["report-writer: rowsForArticle + writeReport"],"fullName":"report-writer: rowsForArticle + writeReport writeReport round-trips a non-trivial row set","status":"passed","title":"writeReport round-trips a non-trivial row set","duration":0.7628090000000043,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags defaults to --dry-run mode","status":"passed","title":"defaults to --dry-run mode","duration":0.6563290000000279,"failureMessages":[],"location":{"line":172,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags recognises --check","status":"passed","title":"recognises --check","duration":0.4098170000000323,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags recognises --apply","status":"passed","title":"recognises --apply","duration":0.4572459999999978,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --tier=A","status":"passed","title":"parses --tier=A","duration":0.44517300000001114,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --tier=A,B,C as a list","status":"passed","title":"parses --tier=A,B,C as a list","duration":0.5462830000000167,"failureMessages":[],"location":{"line":189,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags treats --tier=all as null (all tiers)","status":"passed","title":"treats --tier=all as null (all tiers)","duration":0.4337019999999825,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --lang=sv,no","status":"passed","title":"parses --lang=sv,no","duration":0.6128080000000296,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags treats empty --lang= as \"all languages\" (langs=null)","status":"passed","title":"treats empty --lang= as \"all languages\" (langs=null)","duration":0.47216500000001815,"failureMessages":[],"location":{"line":201,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --date-from / --date-to","status":"passed","title":"parses --date-from / --date-to","duration":0.6161240000000134,"failureMessages":[],"location":{"line":209,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --output","status":"passed","title":"parses --output","duration":0.4401540000000068,"failureMessages":[],"location":{"line":215,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --news-dir","status":"passed","title":"parses --news-dir","duration":0.46439000000003716,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags parses --quiet","status":"passed","title":"parses --quiet","duration":0.43455399999999145,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags throws a typed CLI usage error instead of exiting for bad flags","status":"passed","title":"throws a typed CLI usage error instead of exiting for bad flags","duration":0.7808519999999817,"failureMessages":[],"location":{"line":227,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags throws for conflicting mode flags (--check + --dry-run, --apply + --check)","status":"passed","title":"throws for conflicting mode flags (--check + --dry-run, --apply + --check)","duration":1.394221000000016,"failureMessages":[],"location":{"line":232,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: parseFlags"],"fullName":"CLI: parseFlags main maps CLI usage errors to exit code 2","status":"passed","title":"main maps CLI usage errors to exit code 2","duration":1.553309000000013,"failureMessages":[],"location":{"line":239,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end listArticleFiles returns every .html file sorted","status":"passed","title":"listArticleFiles returns every .html file sorted","duration":1.1650909999999612,"failureMessages":[],"location":{"line":281,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end listArticleFiles skips news/index*.html","status":"passed","title":"listArticleFiles skips news/index*.html","duration":1.645511000000056,"failureMessages":[],"location":{"line":288,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --dry-run writes a CSV and exits 0","status":"passed","title":"--dry-run writes a CSV and exits 0","duration":4.6576820000000225,"failureMessages":[],"location":{"line":296,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --check exits non-zero when the synthetic articles violate the contract","status":"passed","title":"--check exits non-zero when the synthetic articles violate the contract","duration":1.7787809999999808,"failureMessages":[],"location":{"line":304,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --apply exits with CLI-misuse code 2","status":"passed","title":"--apply exits with CLI-misuse code 2","duration":1.1260480000000257,"failureMessages":[],"location":{"line":309,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --lang filter restricts scanned rows","status":"passed","title":"--lang filter restricts scanned rows","duration":1.2870399999999904,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --tier=B filter restricts to Tier B only","status":"passed","title":"--tier=B filter restricts to Tier B only","duration":1.6101150000000075,"failureMessages":[],"location":{"line":321,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --tier=C summary counts reflect emitted tiers, not pre-filter classification","status":"passed","title":"--tier=C summary counts reflect emitted tiers, not pre-filter classification","duration":1.3862859999999841,"failureMessages":[],"location":{"line":332,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CLI: scan end-to-end"],"fullName":"CLI: scan end-to-end --date-from / --date-to restrict by ISO date","status":"passed","title":"--date-from / --date-to restrict by ISO date","duration":1.2842050000000427,"failureMessages":[],"location":{"line":346,"column":3},"meta":{},"tags":[]}],"startTime":1787953807853,"endTime":1787953807892.2842,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename parses a canonical date-slug-lang filename","status":"passed","title":"parses a canonical date-slug-lang filename","duration":3.992385000000013,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename parses a legacy multi-segment slug","status":"passed","title":"parses a legacy multi-segment slug","duration":0.6085290000000327,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename handles absolute and relative paths equivalently","status":"passed","title":"handles absolute and relative paths equivalently","duration":0.5543379999999729,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename returns nulls for unparseable filenames","status":"passed","title":"returns nulls for unparseable filenames","duration":0.3963929999999891,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: parseArticleFilename"],"fullName":"classifier: parseArticleFilename lower-cases the language tag","status":"passed","title":"lower-cases the language tag","duration":0.43745899999998983,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment findAnalysisSource finds an executive-brief on disk","status":"passed","title":"findAnalysisSource finds an executive-brief on disk","duration":1.2779320000000212,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment findAnalysisSource returns null for unknown date/slug","status":"passed","title":"findAnalysisSource returns null for unknown date/slug","duration":0.9052449999999794,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier A — article with an analysis source","status":"passed","title":"Tier A — article with an analysis source","duration":1.8783369999999877,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier B — article without an analysis source","status":"passed","title":"Tier B — article without an analysis source","duration":1.1620060000000194,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C — non-EN article with a below-floor description","status":"passed","title":"Tier C — non-EN article with a below-floor description","duration":1.5364170000000286,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C — RTL article with above-ceiling title","status":"passed","title":"Tier C — RTL article with above-ceiling title","duration":1.7631809999999746,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment Tier C is not assigned to EN articles even with below-floor description","status":"passed","title":"Tier C is not assigned to EN articles even with below-floor description","duration":0.9091720000000123,"failureMessages":[],"location":{"line":149,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment multi-tier — Tier A + Tier C for a non-EN article with source + short description","status":"passed","title":"multi-tier — Tier A + Tier C for a non-EN article with source + short description","duration":0.9285189999999943,"failureMessages":[],"location":{"line":159,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment every reason is set when its tier is assigned","status":"passed","title":"every reason is set when its tier is assigned","duration":0.9367029999999659,"failureMessages":[],"location":{"line":173,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment isKnownLang accepts all 14 contract languages and the BCP-47 `nb` alias","status":"passed","title":"isKnownLang accepts all 14 contract languages and the BCP-47 `nb` alias","duration":0.9081499999999778,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment isKnownLang rejects an unknown language","status":"passed","title":"isKnownLang rejects an unknown language","duration":0.6524709999999914,"failureMessages":[],"location":{"line":191,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifier: tier assignment"],"fullName":"classifier: tier assignment classifier test exports parseArticleFilename / findAnalysisSource / isKnownLang","status":"passed","title":"classifier test exports parseArticleFilename / findAnalysisSource / isKnownLang","duration":0.7120739999999728,"failureMessages":[],"location":{"line":195,"column":3},"meta":{},"tags":[]}],"startTime":1787953840554,"endTime":1787953840574.7122,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/walker.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs parses --from and --to flags","status":"passed","title":"parses --from and --to flags","duration":3.8889819999999986,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs sets persist=true when --persist flag is present","status":"passed","title":"sets persist=true when --persist flag is present","duration":0.6080680000000029,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when --from is missing","status":"passed","title":"throws when --from is missing","duration":1.2976199999999949,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when --to is missing","status":"passed","title":"throws when --to is missing","duration":0.5126390000000356,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws when date format is invalid","status":"passed","title":"throws when date format is invalid","duration":0.5229190000000017,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs accepts --tom as an alias for --to (Swedish, used in repo docs)","status":"passed","title":"accepts --tom as an alias for --to (Swedish, used in repo docs)","duration":0.5118689999999901,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs prefers --to over --tom when both are provided","status":"passed","title":"prefers --to over --tom when both are provided","duration":0.5253739999999993,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArgs"],"fullName":"parseCalendarArgs throws CliArgsError (typed) for invalid arguments","status":"passed","title":"throws CliArgsError (typed) for invalid arguments","duration":0.5577940000000012,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a successful MCP primary manifest","status":"passed","title":"formats a successful MCP primary manifest","duration":0.9266149999999698,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a web fallback manifest with primary error","status":"passed","title":"formats a web fallback manifest with primary error","duration":0.6032289999999989,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["formatManifestMarkdown"],"fullName":"formatManifestMarkdown formats a none (both failed) manifest","status":"passed","title":"formats a none (both failed) manifest","duration":0.41505699999999024,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]}],"startTime":1787953911778,"endTime":1787953911789.415,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/manifest.test.ts"},{"assertionResults":[{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback succeeds via MCP primary path and records manifest correctly","status":"passed","title":"succeeds via MCP primary path and records manifest correctly","duration":6.695014999999955,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback triggers web fallback when MCP returns HTML error page","status":"passed","title":"triggers web fallback when MCP returns HTML error page","duration":3.1564500000000066,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback triggers web fallback when MCP returns the degraded-kalender sentinel","status":"passed","title":"triggers web fallback when MCP returns the degraded-kalender sentinel","duration":1.2782440000000292,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback retries MCP on network error before falling back","status":"passed","title":"retries MCP on network error before falling back","duration":1.1971919999999727,"failureMessages":[],"location":{"line":182,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback returns path=none when both paths fail after retry exhaustion","status":"passed","title":"returns path=none when both paths fail after retry exhaustion","duration":1.540264000000036,"failureMessages":[],"location":{"line":210,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback manifest includes correct `date` and `dateTo` fields","status":"passed","title":"manifest includes correct `date` and `dateTo` fields","duration":0.6193499999999972,"failureMessages":[],"location":{"line":223,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback does not sleep before the first MCP attempt","status":"passed","title":"does not sleep before the first MCP attempt","duration":0.638526000000013,"failureMessages":[],"location":{"line":235,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback"],"fullName":"fetchCalendarWithFallback does not retry HTML errors (immediate fallback)","status":"passed","title":"does not retry HTML errors (immediate fallback)","duration":0.9337090000000217,"failureMessages":[],"location":{"line":244,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchCalendarWithFallback – MCP succeeds on retry"],"fullName":"fetchCalendarWithFallback – MCP succeeds on retry succeeds on the second MCP attempt without triggering fallback","status":"passed","title":"succeeds on the second MCP attempt without triggering fallback","duration":0.9068780000000061,"failureMessages":[],"location":{"line":271,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarEvent shape"],"fullName":"CalendarEvent shape MCP-normalized events have all required fields","status":"passed","title":"MCP-normalized events have all required fields","duration":0.5961460000000329,"failureMessages":[],"location":{"line":300,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarEvent shape"],"fullName":"CalendarEvent shape web-fallback events have all required fields","status":"passed","title":"web-fallback events have all required fields","duration":0.550360000000012,"failureMessages":[],"location":{"line":313,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson creates the output directory and writes a JSON file","status":"passed","title":"creates the output directory and writes a JSON file","duration":1.062419000000034,"failureMessages":[],"location":{"line":347,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson written file contains correct schema, manifest, and events","status":"passed","title":"written file contains correct schema, manifest, and events","duration":0.9987100000000169,"failureMessages":[],"location":{"line":375,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson returns the output file path","status":"passed","title":"returns the output file path","duration":0.6586130000000026,"failureMessages":[],"location":{"line":407,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistCalendarJson"],"fullName":"persistCalendarJson uses {from}_{dateTo}.json when range spans multiple days","status":"passed","title":"uses {from}_{dateTo}.json when range spans multiple days","duration":0.666136999999992,"failureMessages":[],"location":{"line":418,"column":3},"meta":{},"tags":[]}],"startTime":1787953786873,"endTime":1787953786894.666,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/orchestrator-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should return result object with success status","status":"passed","title":"should return result object with success status","duration":3.6232239999999365,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate indexes successfully","status":"passed","title":"should generate indexes successfully","duration":0.6600760000001173,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate index files for all 14 languages","status":"passed","title":"should generate index files for all 14 languages","duration":0.659523999999692,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should generate index files with correct lang attribute","status":"passed","title":"should generate index files with correct lang attribute","duration":4.791992000000391,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include domain-specific keywords in generated indexes","status":"passed","title":"should include domain-specific keywords in generated indexes","duration":0.7499639999996361,"failureMessages":[],"location":{"line":113,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include translated Schema.org WebSite description per language","status":"passed","title":"should include translated Schema.org WebSite description per language","duration":0.5543080000006739,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include publisher and about in Schema.org ItemList articles","status":"passed","title":"should include publisher and about in Schema.org ItemList articles","duration":0.49464699999953154,"failureMessages":[],"location":{"line":135,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should set dir=\"rtl\" for Arabic and Hebrew indexes","status":"passed","title":"should set dir=\"rtl\" for Arabic and Hebrew indexes","duration":0.38803699999971286,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include search input with id and aria-label","status":"passed","title":"should include search input with id and aria-label","duration":0.751246999999239,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include load-more button and article counter","status":"passed","title":"should include load-more button and article counter","duration":1.1980130000001736,"failureMessages":[],"location":{"line":160,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include PAGE_SIZE and pagination logic","status":"passed","title":"should include PAGE_SIZE and pagination logic","duration":1.1364270000003671,"failureMessages":[],"location":{"line":169,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include readURLParams and updateURL for URL state management","status":"passed","title":"should include readURLParams and updateURL for URL state management","duration":0.9263639999999214,"failureMessages":[],"location":{"line":175,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should not include conflicting DOMContentLoaded content loader","status":"passed","title":"should not include conflicting DOMContentLoaded content loader","duration":0.7215809999997873,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include esc() helper and apply it to article fields in buildArticleCard","status":"passed","title":"should include esc() helper and apply it to article fields in buildArticleCard","duration":1.6802959999995437,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include AI-Disrupted News Generation section","status":"passed","title":"should include AI-Disrupted News Generation section","duration":0.878523999999743,"failureMessages":[],"location":{"line":203,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should localise AI newsroom section for non-English languages","status":"passed","title":"should localise AI newsroom section for non-English languages","duration":0.8999050000002171,"failureMessages":[],"location":{"line":209,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include app version marker","status":"passed","title":"should include app version marker","duration":0.686094000000594,"failureMessages":[],"location":{"line":215,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the unified `rm-site-footer` 3-column trust block","status":"passed","title":"should include the unified `rm-site-footer` 3-column trust block","duration":0.6665379999994911,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should localise footer brand description for non-English languages","status":"passed","title":"should localise footer brand description for non-English languages","duration":0.5453009999991991,"failureMessages":[],"location":{"line":230,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the unified `rm-site-header` chrome with theme toggle","status":"passed","title":"should include the unified `rm-site-header` chrome with theme toggle","duration":0.6270850000000792,"failureMessages":[],"location":{"line":239,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should include the anti-flash inline theme bootstrap in <head>","status":"passed","title":"should include the anti-flash inline theme bootstrap in <head>","duration":0.4666639999995823,"failureMessages":[],"location":{"line":249,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generateAllIndexes"],"fullName":"generateAllIndexes should emit Organization + WebSite + ItemList + BreadcrumbList JSON-LD","status":"passed","title":"should emit Organization + WebSite + ItemList + BreadcrumbList JSON-LD","duration":0.48430699999971694,"failureMessages":[],"location":{"line":254,"column":5},"meta":{},"tags":[]}],"startTime":1787953820377,"endTime":1787953820400.4844,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/orchestrator-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["getDefaultImfClient"],"fullName":"getDefaultImfClient returns the same instance across calls (singleton)","status":"passed","title":"returns the same instance across calls (singleton)","duration":3.9233770000000163,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.listDatamapperIndicators"],"fullName":"ImfClient.listDatamapperIndicators hits the /indicators endpoint and parses the envelope","status":"passed","title":"hits the /indicators endpoint and parses the envelope","duration":2.213434999999947,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch issues one Datamapper call per indicator for the same country","status":"passed","title":"issues one Datamapper call per indicator for the same country","duration":2.4984179999999583,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch isolates individual failures — a flaky indicator maps to []","status":"passed","title":"isolates individual failures — a flaky indicator maps to []","duration":1.7857239999999592,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch emits a diagnostic event when one indicator is fail-softed","status":"passed","title":"emits a diagnostic event when one indicator is fail-softed","duration":3.2738109999999665,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch rethrows non-retryable indicator HTTP errors instead of fail-softing them","status":"passed","title":"rethrows non-retryable indicator HTTP errors instead of fail-softing them","duration":2.6419070000000033,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch fail-softs fetch network TypeErrors but not programmer TypeErrors","status":"passed","title":"fail-softs fetch network TypeErrors but not programmer TypeErrors","duration":1.0770169999999553,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicatorsBatch"],"fullName":"ImfClient.getWeoIndicatorsBatch validates years up-front instead of swallowing caller errors","status":"passed","title":"validates years up-front instead of swallowing caller errors","duration":0.7105399999999804,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator prefers the latest non-projection value when available","status":"passed","title":"prefers the latest non-projection value when available","duration":1.0649339999999938,"failureMessages":[],"location":{"line":193,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator falls back to the earliest projection when only projections are present","status":"passed","title":"falls back to the earliest projection when only projections are present","duration":0.7564869999999928,"failureMessages":[],"location":{"line":216,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getLatestWeoIndicator"],"fullName":"ImfClient.getLatestWeoIndicator returns null when the series is empty","status":"passed","title":"returns null when the series is empty","duration":0.6689030000000002,"failureMessages":[],"location":{"line":237,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.compareCountriesWeo"],"fullName":"ImfClient.compareCountriesWeo returns one entry per country, null on failure","status":"passed","title":"returns one entry per country, null on failure","duration":0.9508400000000279,"failureMessages":[],"location":{"line":258,"column":3},"meta":{},"tags":[]}],"startTime":1787953834399,"endTime":1787953834420.951,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/client-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF refactor: bounded-context invariants","COFOG codes (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants COFOG codes (issue #2580 acceptance criterion) exposes only the canonical GF##_T form (legacy G02/G07/G09/G10 retired 2026-05)","status":"passed","title":"exposes only the canonical GF##_T form (legacy G02/G07/G09/G10 retired 2026-05)","duration":5.502973999999995,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Retry policy (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Retry policy (issue #2580 acceptance criterion) preserves the 30_000 ms RETRY_AFTER_CAP_MS cap","status":"passed","title":"preserves the 30_000 ms RETRY_AFTER_CAP_MS cap","duration":0.5280089999999973,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","WEO vintage default (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants WEO vintage default (issue #2580 acceptance criterion) keeps DEFAULT_WEO_VINTAGE at WEO-2026-04","status":"passed","title":"keeps DEFAULT_WEO_VINTAGE at WEO-2026-04","duration":0.44548400000002175,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","IMF SDMX subscription key auth boundary"],"fullName":"IMF refactor: bounded-context invariants IMF SDMX subscription key auth boundary is the sole reader of process.env IMF_SDMX_SUBSCRIPTION_KEY","status":"passed","title":"is the sole reader of process.env IMF_SDMX_SUBSCRIPTION_KEY","duration":1.7382450000000063,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps every source file under 300 lines","status":"passed","title":"keeps every source file under 300 lines","duration":1.301507000000015,"failureMessages":[],"location":{"line":95,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps imf-client.ts + imf-fetch.ts shims under 80 lines each","status":"passed","title":"keeps imf-client.ts + imf-fetch.ts shims under 80 lines each","duration":0.9751860000000079,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["IMF refactor: bounded-context invariants","Bounded-context file-size budget (issue #2580 acceptance criterion)"],"fullName":"IMF refactor: bounded-context invariants Bounded-context file-size budget (issue #2580 acceptance criterion) keeps each subcommand entry under 150 lines","status":"passed","title":"keeps each subcommand entry under 150 lines","duration":0.7745099999999638,"failureMessages":[],"location":{"line":114,"column":5},"meta":{},"tags":[]}],"startTime":1787953895945,"endTime":1787953895956.7744,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/refactor-invariants.test.ts"},{"assertionResults":[{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats a fetchedAt date older than 6 months as stale","status":"passed","title":"treats a fetchedAt date older than 6 months as stale","duration":3.988828999999953,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats a recent fetchedAt date as fresh","status":"passed","title":"treats a recent fetchedAt date as fresh","duration":0.6287379999999985,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isCacheStale"],"fullName":"isCacheStale treats invalid date strings as stale (conservative)","status":"passed","title":"treats invalid date strings as stale (conservative)","duration":0.5313049999999748,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["loadCachedIMFData"],"fullName":"loadCachedIMFData returns null when no cache file exists for the indicator/country pair","status":"passed","title":"returns null when no cache file exists for the indicator/country pair","duration":0.6458700000000022,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildFallbackPayload"],"fullName":"buildFallbackPayload annotates the cached payload with fallback metadata + transport=cache","status":"passed","title":"annotates the cached payload with fallback metadata + transport=cache","duration":1.259428000000014,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["buildFallbackPayload"],"fullName":"buildFallbackPayload uses the \">6 month vintage\" wording when stale=true (renderer key for yellow / red badge)","status":"passed","title":"uses the \">6 month vintage\" wording when stale=true (renderer key for yellow / red badge)","duration":0.588401000000033,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]}],"startTime":1787953921614,"endTime":1787953921622.5884,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/cache.test.ts"},{"assertionResults":[{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError ImfWeoSdmxOnlyError is always permanent","status":"passed","title":"ImfWeoSdmxOnlyError is always permanent","duration":4.005179999999996,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError empty-Datamapper sentinel is transient (Datamapper occasionally lags Fund publishing)","status":"passed","title":"empty-Datamapper sentinel is transient (Datamapper occasionally lags Fund publishing)","duration":0.5776109999999903,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError respects an explicit retryable=true / false flag (e.g. ImfHttpError)","status":"passed","title":"respects an explicit retryable=true / false flag (e.g. ImfHttpError)","duration":0.5858569999999759,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError AbortError is transient (timeout — worth one more shot)","status":"passed","title":"AbortError is transient (timeout — worth one more shot)","duration":0.384490000000028,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError classifies by HTTP status when no flag is present (429/5xx transient, 4xx permanent)","status":"passed","title":"classifies by HTTP status when no flag is present (429/5xx transient, 4xx permanent)","duration":0.5167169999999714,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["classifyImfFetchError"],"fullName":"classifyImfFetchError exports the sentinel code string used to tag empty-Datamapper errors","status":"passed","title":"exports the sentinel code string used to tag empty-Datamapper errors","duration":0.47470899999996163,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953926097,"endTime":1787953926103.4746,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/classifier.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should create client with default configuration","status":"passed","title":"should create client with default configuration","duration":4.180777999999975,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept custom configuration","status":"passed","title":"should accept custom configuration","duration":0.6602659999999787,"failureMessages":[],"location":{"line":57,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept string URL for backwards compatibility","status":"passed","title":"should accept string URL for backwards compatibility","duration":0.5459119999999871,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept serverUrl alias in config","status":"passed","title":"should accept serverUrl alias in config","duration":0.5492179999999962,"failureMessages":[],"location":{"line":75,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize request and error counts to zero","status":"passed","title":"should initialize request and error counts to zero","duration":0.6896820000000048,"failureMessages":[],"location":{"line":80,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should accept custom headers in config","status":"passed","title":"should accept custom headers in config","duration":1.2497699999999554,"failureMessages":[],"location":{"line":85,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize empty customHeaders when no headers provided","status":"passed","title":"should initialize empty customHeaders when no headers provided","duration":0.454921000000013,"failureMessages":[],"location":{"line":93,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","constructor"],"fullName":"MCPClient — integration spine constructor should initialize empty customHeaders for string URL config","status":"passed","title":"should initialize empty customHeaders for string URL config","duration":0.5142319999999927,"failureMessages":[],"location":{"line":97,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","sleep"],"fullName":"MCPClient — integration spine sleep should resolve after specified time","status":"passed","title":"should resolve after specified time","duration":50.439842,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport retries on transient network error then succeeds","status":"passed","title":"retries on transient network error then succeeds","duration":2.3960370000000353,"failureMessages":[],"location":{"line":126,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport does not retry on JSON-RPC error response","status":"passed","title":"does not retry on JSON-RPC error response","duration":2.7407719999999927,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","end-to-end retry + transport"],"fullName":"MCPClient — integration spine end-to-end retry + transport surfaces transport error via TRANSPORT_ERROR_RE-matchable message","status":"passed","title":"surfaces transport error via TRANSPORT_ERROR_RE-matchable message","duration":0.9255130000000236,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","statistics surface"],"fullName":"MCPClient — integration spine statistics surface exposes getStats/resetStats with the documented shape","status":"passed","title":"exposes getStats/resetStats with the documented shape","duration":1.0360000000000582,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke calendar.fetchCalendarEvents returns events array","status":"passed","title":"calendar.fetchCalendarEvents returns events array","duration":1.5458139999999503,"failureMessages":[],"location":{"line":195,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke reports.fetchPropositions returns array","status":"passed","title":"reports.fetchPropositions returns array","duration":0.8344919999999547,"failureMessages":[],"location":{"line":201,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke documents.searchDocuments returns array","status":"passed","title":"documents.searchDocuments returns array","duration":1.5097469999999475,"failureMessages":[],"location":{"line":207,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke speeches.searchSpeeches returns array","status":"passed","title":"speeches.searchSpeeches returns array","duration":0.9787329999999201,"failureMessages":[],"location":{"line":213,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke members.fetchMPs returns array","status":"passed","title":"members.fetchMPs returns array","duration":0.8995140000000674,"failureMessages":[],"location":{"line":219,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — integration spine","methods/* happy-path smoke"],"fullName":"MCPClient — integration spine methods/* happy-path smoke votes.fetchVotingGroup returns array","status":"passed","title":"votes.fetchVotingGroup returns array","duration":0.8604509999998982,"failureMessages":[],"location":{"line":225,"column":5},"meta":{},"tags":[]}],"startTime":1787953838688,"endTime":1787953838761.8604,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/client-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration writes every provider into a disjoint sub-tree under a shared dataRoot","status":"passed","title":"writes every provider into a disjoint sub-tree under a shared dataRoot","duration":8.246229999999969,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration every provider emits a sibling *.meta.json sidecar","status":"passed","title":"every provider emits a sibling *.meta.json sidecar","duration":2.3972089999999753,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — cross-source integration"],"fullName":"data-persistence — cross-source integration cross-write order does not corrupt later writes from a different provider","status":"passed","title":"cross-write order does not corrupt later writes from a different provider","duration":0.9506399999999644,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]}],"startTime":1787953867244,"endTime":1787953867255.9507,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/data-persistence-integration.test.ts"},{"assertionResults":[{"ancestorTitles":["pdf-converter","isPdfToTextAvailable"],"fullName":"pdf-converter isPdfToTextAvailable should return a boolean","status":"passed","title":"should return a boolean","duration":8.766767000000016,"failureMessages":[],"location":{"line":22,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","isPdfToTextAvailable"],"fullName":"pdf-converter isPdfToTextAvailable should cache the result","status":"passed","title":"should cache the result","duration":3.5227160000000026,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should return empty string for empty input","status":"passed","title":"should return empty string for empty input","duration":0.685053000000039,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should convert ALL CAPS lines to headings","status":"passed","title":"should convert ALL CAPS lines to headings","duration":0.7514579999999569,"failureMessages":[],"location":{"line":39,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should preserve paragraph breaks","status":"passed","title":"should preserve paragraph breaks","duration":0.5188419999999496,"failureMessages":[],"location":{"line":46,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should not convert short ALL CAPS as headings","status":"passed","title":"should not convert short ALL CAPS as headings","duration":0.6961539999999786,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should handle Swedish characters in headings","status":"passed","title":"should handle Swedish characters in headings","duration":0.511146999999994,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should normalise excessive whitespace","status":"passed","title":"should normalise excessive whitespace","duration":0.5721919999999727,"failureMessages":[],"location":{"line":68,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["pdf-converter","textToMarkdown"],"fullName":"pdf-converter textToMarkdown should handle mixed content","status":"passed","title":"should handle mixed content","duration":0.5808170000000246,"failureMessages":[],"location":{"line":74,"column":5},"meta":{},"tags":[]}],"startTime":1787953916118,"endTime":1787953916135.5808,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/pdf-converter.test.ts"},{"assertionResults":[{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon quarter horizon = 4 scenarios","status":"passed","title":"quarter horizon = 4 scenarios","duration":3.571257000000003,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon year horizon = 4 scenarios + 5 wildcards = 9 leaves","status":"passed","title":"year horizon = 4 scenarios + 5 wildcards = 9 leaves","duration":0.48022900000000845,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon election-cycle scenario tree = 4 scenarios × 3 coalition branches = 12 leaves","status":"passed","title":"election-cycle scenario tree = 4 scenarios × 3 coalition branches = 12 leaves","duration":0.4141850000000318,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon election-cycle total branches = 12 scenario leaves + 5 wildcards = 17","status":"passed","title":"election-cycle total branches = 12 scenario leaves + 5 wildcards = 17","duration":0.3355280000000107,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["scenario tree — branching factors per horizon"],"fullName":"scenario tree — branching factors per horizon coalition branching factor (3) is the only multiplier that yields the 12-leaf cycle tree","status":"passed","title":"coalition branching factor (3) is the only multiplier that yields the 12-leaf cycle tree","duration":0.3592130000000111,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — long-horizon scenario coverage"],"fullName":"analysis/article-types.json — long-horizon scenario coverage every long-horizon-forecast entry declares scenarioHorizonYears","status":"passed","title":"every long-horizon-forecast entry declares scenarioHorizonYears","duration":0.6056940000000282,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — long-horizon scenario coverage"],"fullName":"analysis/article-types.json — long-horizon scenario coverage at least one article-type targets the election-cycle horizon (4+ years)","status":"passed","title":"at least one article-type targets the election-cycle horizon (4+ years)","duration":0.4244449999999915,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]}],"startTime":1787953900200,"endTime":1787953900206.6057,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/coalition-branches.test.ts"},{"assertionResults":[{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window prompt explicitly documents the ±30-day trigger window","status":"passed","title":"prompt explicitly documents the ±30-day trigger window","duration":3.7185530000000426,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window activation predicate uses 30 as the day-delta threshold","status":"passed","title":"activation predicate uses 30 as the day-delta threshold","duration":0.6766170000000216,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — ±30-day activation window"],"fullName":"cycle-rollover module — ±30-day activation window prompt links the ±30-day window to the election anchor","status":"passed","title":"prompt links the ±30-day window to the election anchor","duration":0.6304310000000442,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T-30 → T-1 pre-election bridge","status":"passed","title":"prompt documents the T-30 → T-1 pre-election bridge","duration":0.4628270000000043,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T+1 → T+30 post-election bridge","status":"passed","title":"prompt documents the T+1 → T+30 post-election bridge","duration":0.5180599999999913,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt documents the T+31 → T+45 freeze period","status":"passed","title":"prompt documents the T+31 → T+45 freeze period","duration":0.47931699999998045,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["cycle-rollover module — bridge-period semantics"],"fullName":"cycle-rollover module — bridge-period semantics prompt explicitly forbids time-budget anchor-skip reasons","status":"passed","title":"prompt explicitly forbids time-budget anchor-skip reasons","duration":0.5626829999999927,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry exposes the electionCycles block","status":"passed","title":"exposes the electionCycles block","duration":0.4182529999999929,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry exposes a `next` cycle with an ISO date start","status":"passed","title":"exposes a `next` cycle with an ISO date start","duration":0.5991909999999621,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis/article-types.json — electionCycles registry"],"fullName":"analysis/article-types.json — electionCycles registry Swedish elections are quadrennial — current.start and next.start differ by ~4 years","status":"passed","title":"Swedish elections are quadrennial — current.start and next.start differ by ~4 years","duration":0.6792609999999968,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]}],"startTime":1787953899755,"endTime":1787953899764.6792,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/cycle-rollover.test.ts"},{"assertionResults":[{"ancestorTitles":["subtractDays"],"fullName":"subtractDays subtracts a single day across month boundary","status":"passed","title":"subtracts a single day across month boundary","duration":3.8690349999999967,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["subtractDays"],"fullName":"subtractDays subtracts multiple days across year boundary","status":"passed","title":"subtracts multiple days across year boundary","duration":0.5827320000000213,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["subtractDays"],"fullName":"subtractDays zero days is identity","status":"passed","title":"zero days is identity","duration":0.4923509999999851,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade VERY HIGH → HIGH","status":"passed","title":"VERY HIGH → HIGH","duration":0.40343500000000176,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade HIGH → MEDIUM","status":"passed","title":"HIGH → MEDIUM","duration":0.5003370000000018,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade MEDIUM → LOW","status":"passed","title":"MEDIUM → LOW","duration":0.5024809999999889,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade LOW → VERY LOW","status":"passed","title":"LOW → VERY LOW","duration":0.5828910000000178,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade VERY LOW stays at VERY LOW (floor)","status":"passed","title":"VERY LOW stays at VERY LOW (floor)","duration":0.39674300000001494,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["degrade"],"fullName":"degrade throws on unknown confidence value","status":"passed","title":"throws on unknown confidence value","duration":1.5881640000000061,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --from / --to","status":"passed","title":"parses --from / --to","duration":0.6941899999999919,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --date / --cycle","status":"passed","title":"parses --date / --cycle","duration":0.7201380000000199,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs parses --dry-run flag","status":"passed","title":"parses --dry-run flag","duration":0.4520959999999832,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback default is 14","status":"passed","title":"--max-lookback default is 14","duration":0.445904999999982,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback overrides default","status":"passed","title":"--max-lookback overrides default","duration":0.5591469999999958,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback accepts zero-padded positive integers","status":"passed","title":"--max-lookback accepts zero-padded positive integers","duration":0.6097320000000082,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is missing","status":"passed","title":"--max-lookback throws when value is missing","duration":0.6572610000000054,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is non-numeric","status":"passed","title":"--max-lookback throws when value is non-numeric","duration":0.6264429999999948,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs --max-lookback throws when value is zero","status":"passed","title":"--max-lookback throws when value is zero","duration":0.5110569999999939,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseArgs"],"fullName":"parseArgs returns CliArgs shape with required fields","status":"passed","title":"returns CliArgs shape with required fields","duration":0.5036730000000489,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward produces schema_version 1.0 output","status":"passed","title":"produces schema_version 1.0 output","duration":0.9557800000000043,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR confidence is degraded one level","status":"passed","title":"open PIR confidence is degraded one level","duration":0.7465379999999868,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR appends pir_id to existing inherits_from chain","status":"passed","title":"open PIR appends pir_id to existing inherits_from chain","duration":1.2160169999999653,"failureMessages":[],"location":{"line":110,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward answered PIR carried forward UNCHANGED preserves inherits_from history","status":"passed","title":"answered PIR carried forward UNCHANGED preserves inherits_from history","duration":0.7336840000000393,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR with VERY LOW stays at VERY LOW","status":"passed","title":"open PIR with VERY LOW stays at VERY LOW","duration":0.5171379999999886,"failureMessages":[],"location":{"line":157,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward open PIR drops answer_summary on roll-forward","status":"passed","title":"open PIR drops answer_summary on roll-forward","duration":0.5925299999999538,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from is a relative path when source is under repoRoot","status":"passed","title":"inherited_from is a relative path when source is under repoRoot","duration":0.4990149999999858,"failureMessages":[],"location":{"line":199,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from normalizes relative paths via path.relative semantics","status":"passed","title":"inherited_from normalizes relative paths via path.relative semantics","duration":0.6916749999999752,"failureMessages":[],"location":{"line":212,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward inherited_from falls back to absolute path when source is outside repoRoot","status":"passed","title":"inherited_from falls back to absolute path when source is outside repoRoot","duration":0.5837030000000141,"failureMessages":[],"location":{"line":222,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["rollForward"],"fullName":"rollForward uses fixed generated_at from injected now()","status":"passed","title":"uses fixed generated_at from injected now()","duration":0.5566029999999955,"failureMessages":[],"location":{"line":230,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+72h' horizon (3-day lookback)","status":"passed","title":"subtractDays() supports the 'T+72h' horizon (3-day lookback)","duration":0.7599329999999895,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+7d' horizon (7-day lookback)","status":"passed","title":"subtractDays() supports the 'T+7d' horizon (7-day lookback)","duration":0.7623979999999619,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+30d' horizon (30-day lookback)","status":"passed","title":"subtractDays() supports the 'T+30d' horizon (30-day lookback)","duration":0.8333109999999806,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+90d' horizon (90-day lookback)","status":"passed","title":"subtractDays() supports the 'T+90d' horizon (90-day lookback)","duration":0.5303530000000478,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+365d' horizon (365-day lookback)","status":"passed","title":"subtractDays() supports the 'T+365d' horizon (365-day lookback)","duration":0.7081459999999993,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows subtractDays() supports the 'T+1460d' horizon (1460-day lookback)","status":"passed","title":"subtractDays() supports the 'T+1460d' horizon (1460-day lookback)","duration":0.5747559999999794,"failureMessages":[],"location":{"line":263,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["horizon ladder — canonical lookback windows"],"fullName":"horizon ladder — canonical lookback windows the seven canonical horizons are distinct and monotonically increasing","status":"passed","title":"the seven canonical horizons are distinct and monotonically increasing","duration":0.6860550000000103,"failureMessages":[],"location":{"line":273,"column":3},"meta":{},"tags":[]}],"startTime":1787953829306,"endTime":1787953829333.686,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/horizon-rollforward.test.ts"},{"assertionResults":[{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema file exists and is valid JSON","status":"passed","title":"schema file exists and is valid JSON","duration":3.793172000000027,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema uses JSON Schema 2020-12","status":"passed","title":"schema uses JSON Schema 2020-12","duration":0.7381020000000262,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema $id is scoped to riksdagsmonitor.com","status":"passed","title":"schema $id is scoped to riksdagsmonitor.com","duration":0.4421379999999999,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema requires mandatory top-level fields","status":"passed","title":"schema requires mandatory top-level fields","duration":1.3674009999999726,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema defines pir_id pattern","status":"passed","title":"schema defines pir_id pattern","duration":0.5743850000000066,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema lists all valid cycle types","status":"passed","title":"schema lists all valid cycle types","duration":1.0798209999999813,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json top-level and pirEntry both enforce additionalProperties: false","status":"passed","title":"top-level and pirEntry both enforce additionalProperties: false","duration":0.5296610000000328,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema enforces conditional answer_summary via if/then/else","status":"passed","title":"schema enforces conditional answer_summary via if/then/else","duration":0.7374909999999772,"failureMessages":[],"location":{"line":94,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json schema requires answer_summary to be non-empty when present","status":"passed","title":"schema requires answer_summary to be non-empty when present","duration":0.6214429999999993,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["schemas/pir-status.schema.json"],"fullName":"schemas/pir-status.schema.json subfolder description acknowledges schema cannot enforce equality with cycle","status":"passed","title":"subfolder description acknowledges schema cannot enforce equality with cycle","duration":0.46547099999997954,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource returns null when no source exists in lookback window","status":"passed","title":"returns null when no source exists in lookback window","duration":1.5767319999999927,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource finds nearest source within lookback","status":"passed","title":"finds nearest source within lookback","duration":0.887061000000017,"failureMessages":[],"location":{"line":137,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["findLatestSource"],"fullName":"findLatestSource respects maxLookback limit","status":"passed","title":"respects maxLookback limit","duration":1.0820560000000228,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain prints usage and exits 1 with no args","status":"passed","title":"prints usage and exits 1 with no args","duration":1.3389970000000062,"failureMessages":[],"location":{"line":171,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 when --from source not found","status":"passed","title":"exits 1 when --from source not found","duration":0.8181809999999814,"failureMessages":[],"location":{"line":177,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 when --to path cannot derive date/cycle","status":"passed","title":"exits 1 when --to path cannot derive date/cycle","duration":1.0255010000000198,"failureMessages":[],"location":{"line":188,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 with unknown cycle","status":"passed","title":"exits 1 with unknown cycle","duration":0.6792919999999754,"failureMessages":[],"location":{"line":205,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 1 with invalid --max-lookback","status":"passed","title":"exits 1 with invalid --max-lookback","duration":0.6981370000000311,"failureMessages":[],"location":{"line":211,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 2 when source JSON is malformed","status":"passed","title":"exits 2 when source JSON is malformed","duration":0.9656180000000063,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain exits 2 when source fails strict validation","status":"passed","title":"exits 2 when source fails strict validation","duration":1.3385059999999953,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain writes target file successfully on happy path","status":"passed","title":"writes target file successfully on happy path","duration":2.001246999999978,"failureMessages":[],"location":{"line":254,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain --dry-run writes JSON to stdout and does not create file","status":"passed","title":"--dry-run writes JSON to stdout and does not create file","duration":1.03760299999999,"failureMessages":[],"location":{"line":282,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain creates target directory when missing","status":"passed","title":"creates target directory when missing","duration":1.1140459999999734,"failureMessages":[],"location":{"line":297,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["runMain"],"fullName":"runMain --date / --cycle resolves prior cycle within lookback window","status":"passed","title":"--date / --cycle resolves prior cycle within lookback window","duration":0.9990510000000086,"failureMessages":[],"location":{"line":310,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md references pir-status.json","status":"passed","title":"05-analysis-gate.md references pir-status.json","duration":0.5423749999999927,"failureMessages":[],"location":{"line":335,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md references pir-status.schema.json","status":"passed","title":"05-analysis-gate.md references pir-status.schema.json","duration":0.4404349999999795,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md enforces subfolder === cycle invariant","status":"passed","title":"05-analysis-gate.md enforces subfolder === cycle invariant","duration":0.5887029999999527,"failureMessages":[],"location":{"line":341,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md enforces conditional answer_summary","status":"passed","title":"05-analysis-gate.md enforces conditional answer_summary","duration":0.545501999999999,"failureMessages":[],"location":{"line":344,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract 05-analysis-gate.md keeps PIR and supplementary checks sequential","status":"passed","title":"05-analysis-gate.md keeps PIR and supplementary checks sequential","duration":0.5623030000000426,"failureMessages":[],"location":{"line":347,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md references pir-status.json","status":"passed","title":"ai-driven-analysis-guide.md references pir-status.json","duration":0.5324769999999717,"failureMessages":[],"location":{"line":354,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md references roll-forward script","status":"passed","title":"ai-driven-analysis-guide.md references roll-forward script","duration":0.529892000000018,"failureMessages":[],"location":{"line":357,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["analysis-gate pir-status.json contract"],"fullName":"analysis-gate pir-status.json contract ai-driven-analysis-guide.md clarifies open vs preserved status semantics","status":"passed","title":"ai-driven-analysis-guide.md clarifies open vs preserved status semantics","duration":0.6293880000000058,"failureMessages":[],"location":{"line":360,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["module export sanity"],"fullName":"module export sanity CycleType values are usable in fixtures","status":"passed","title":"CycleType values are usable in fixtures","duration":0.9798350000000369,"failureMessages":[],"location":{"line":371,"column":3},"meta":{},"tags":[]}],"startTime":1787953790470,"endTime":1787953790501.9797,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["validateSource"],"fullName":"validateSource accepts a valid fixture","status":"passed","title":"accepts a valid fixture","duration":4.235339999999951,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-objects","status":"passed","title":"rejects non-objects","duration":1.6840530000000058,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects missing schema_version","status":"passed","title":"rejects missing schema_version","duration":0.5812780000000544,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unsupported schema_version","status":"passed","title":"rejects unsupported schema_version","duration":0.5471049999999877,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-array pirs","status":"passed","title":"rejects non-array pirs","duration":0.6336660000000052,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects missing required field","status":"passed","title":"rejects missing required field","duration":0.6417110000000434,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level cycle","status":"passed","title":"rejects invalid top-level cycle","duration":0.6880779999999618,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level date format","status":"passed","title":"rejects invalid top-level date format","duration":0.4693189999999845,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects empty top-level subfolder","status":"passed","title":"rejects empty top-level subfolder","duration":0.809786000000031,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects top-level subfolder that does not equal cycle","status":"passed","title":"rejects top-level subfolder that does not equal cycle","duration":0.6237879999999905,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid top-level generated_at date-time","status":"passed","title":"rejects invalid top-level generated_at date-time","duration":0.4818520000000035,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid inherited_from type","status":"passed","title":"rejects invalid inherited_from type","duration":0.50513600000005,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects invalid pir_id pattern","status":"passed","title":"rejects invalid pir_id pattern","duration":0.44362100000000737,"failureMessages":[],"location":{"line":89,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects too-short statement","status":"passed","title":"rejects too-short statement","duration":0.5214359999999942,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unknown status enum","status":"passed","title":"rejects unknown status enum","duration":0.4628169999999727,"failureMessages":[],"location":{"line":125,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects unknown confidence enum","status":"passed","title":"rejects unknown confidence enum","duration":0.5446499999999901,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects answered without answer_summary","status":"passed","title":"rejects answered without answer_summary","duration":0.46277700000001687,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-answered with answer_summary","status":"passed","title":"rejects non-answered with answer_summary","duration":0.4819919999999911,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateSource"],"fullName":"validateSource rejects non-object pir entry","status":"passed","title":"rejects non-object pir entry","duration":0.4413069999999948,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]}],"startTime":1787953866356,"endTime":1787953866371.4414,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/pir-status-contract/status-classification.test.ts"},{"assertionResults":[{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports all artifacts missing when directory is empty","status":"passed","title":"reports all artifacts missing when directory is empty","duration":5.2462339999999585,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports success when all artifacts present","status":"passed","title":"reports success when all artifacts present","duration":2.235135000000014,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports specific missing artifact","status":"passed","title":"reports specific missing artifact","duration":1.7685020000000122,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkArtifactExistence"],"fullName":"checkArtifactExistence reports failure for zero-byte (empty) artifact","status":"passed","title":"reports failure for zero-byte (empty) artifact","duration":2.0106349999999793,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]}],"startTime":1787953924739,"endTime":1787953924751.0107,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/artifact-existence.test.ts"},{"assertionResults":[{"ancestorTitles":["checkCoalitionMathematics"],"fullName":"checkCoalitionMathematics passes with seat-count table","status":"passed","title":"passes with seat-count table","duration":5.598643000000038,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCoalitionMathematics"],"fullName":"checkCoalitionMathematics fails without vote-breakdown table","status":"passed","title":"fails without vote-breakdown table","duration":1.1268800000000283,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953936300,"endTime":1787953936306.127,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/coalition-mathematics.test.ts"},{"assertionResults":[{"ancestorTitles":["checkComparativeInternational"],"fullName":"checkComparativeInternational passes with comparator set declared","status":"passed","title":"passes with comparator set declared","duration":5.570601000000011,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkComparativeInternational"],"fullName":"checkComparativeInternational passes with 2+ comparator table rows","status":"passed","title":"passes with 2+ comparator table rows","duration":1.224142000000029,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953935441,"endTime":1787953935448.224,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/comparative-international.test.ts"},{"assertionResults":[{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate passes with 3+ hypotheses and 100% KJ coverage matrix","status":"passed","title":"passes with 3+ hypotheses and 100% KJ coverage matrix","duration":8.11606599999999,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate fails when KJ Coverage Matrix heading is missing","status":"passed","title":"fails when KJ Coverage Matrix heading is missing","duration":1.8201479999999606,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkDevilsAdvocate"],"fullName":"checkDevilsAdvocate fails when any KJ coverage row contains ❌","status":"passed","title":"fails when any KJ coverage row contains ❌","duration":0.9502590000000168,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953920709,"endTime":1787953920719.9502,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/devils-advocate.test.ts"},{"assertionResults":[{"ancestorTitles":["checkEvidenceCitations (aggregator)"],"fullName":"checkEvidenceCitations (aggregator) returns empty when files do not exist","status":"passed","title":"returns empty when files do not exist","duration":5.335750000000019,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkEvidenceCitations (aggregator)"],"fullName":"checkEvidenceCitations (aggregator) aggregates failures from both SWOT and significance-scoring sub-checks","status":"passed","title":"aggregates failures from both SWOT and significance-scoring sub-checks","duration":2.400675000000035,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]}],"startTime":1787953931449,"endTime":1787953931457.4006,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/evidence-citations.test.ts"},{"assertionResults":[{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 extracts the visible text from a Markdown H1","status":"passed","title":"extracts the visible text from a Markdown H1","duration":4.084797999999978,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 extracts the visible text from a centered HTML <h1> template heading","status":"passed","title":"extracts the visible text from a centered HTML <h1> template heading","duration":0.9815580000000068,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 prefers the Markdown H1 when both forms are present","status":"passed","title":"prefers the Markdown H1 when both forms are present","duration":0.6436750000000302,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 returns null when neither form is present","status":"passed","title":"returns null when neither form is present","duration":0.5882409999999823,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractExecutiveBriefH1"],"fullName":"extractExecutiveBriefH1 strips HTML tags and entities from the heading value","status":"passed","title":"strips HTML tags and entities from the heading value","duration":0.5008479999999622,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief — H1 placeholder parity (Markdown + HTML)"],"fullName":"checkExecutiveBrief — H1 placeholder parity (Markdown + HTML) fails when H1 still contains the 'REPLACE THIS H1' template placeholder (Markdown H1 path)","status":"passed","title":"fails when H1 still contains the 'REPLACE THIS H1' template placeholder (Markdown H1 path)","duration":7.347767999999974,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief — H1 placeholder parity (Markdown + HTML)"],"fullName":"checkExecutiveBrief — H1 placeholder parity (Markdown + HTML) fails when the template placeholder is left in an HTML H1 (centered <h1> parity)","status":"passed","title":"fails when the template placeholder is left in an HTML H1 (centered <h1> parity)","duration":1.589917000000014,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]}],"startTime":1787953909127,"endTime":1787953909143.5898,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/executive-brief-h1.test.ts"},{"assertionResults":[{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief passes with publishable H1, BLUF and Decisions sections","status":"passed","title":"passes with publishable H1, BLUF and Decisions sections","duration":9.60451599999999,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when BLUF missing","status":"passed","title":"fails when BLUF missing","duration":1.56152400000002,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 is bare-boilerplate '# Executive Brief'","status":"passed","title":"fails when H1 is bare-boilerplate '# Executive Brief'","duration":0.9012879999999655,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains the banned phrase 'AI-generated political intelligence'","status":"passed","title":"fails when H1 contains the banned phrase 'AI-generated political intelligence'","duration":0.8178110000000061,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief tolerates a leading emoji in an otherwise publishable H1","status":"passed","title":"tolerates a leading emoji in an otherwise publishable H1","duration":4.264895999999965,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when the brief has no H1 at all (renderer would fall back to BLUF first sentence)","status":"passed","title":"fails when the brief has no H1 at all (renderer would fall back to BLUF first sentence)","duration":1.11015900000001,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 collapses to nothing via cleanArticleTitle (subfolder-label boilerplate)","status":"passed","title":"fails when H1 collapses to nothing via cleanArticleTitle (subfolder-label boilerplate)","duration":1.1279220000000123,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains a literal ISO date (YYYY-MM-DD)","status":"passed","title":"fails when H1 contains a literal ISO date (YYYY-MM-DD)","duration":0.9658689999999979,"failureMessages":[],"location":{"line":106,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains an English long-form date","status":"passed","title":"fails when H1 contains an English long-form date","duration":1.230242999999973,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 contains a Swedish long-form date","status":"passed","title":"fails when H1 contains a Swedish long-form date","duration":1.0300579999999968,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 ends with a trailing comma","status":"passed","title":"fails when H1 ends with a trailing comma","duration":0.881069000000025,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 ends with a coordinating connector","status":"passed","title":"fails when H1 ends with a coordinating connector","duration":0.8164390000000026,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief fails when H1 is normalised-identical to a prior day brief in the same subfolder","status":"passed","title":"fails when H1 is normalised-identical to a prior day brief in the same subfolder","duration":2.1570499999999697,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkExecutiveBrief"],"fullName":"checkExecutiveBrief passes when prior-day brief in same subfolder has a different H1","status":"passed","title":"passes when prior-day brief in same subfolder has a different H1","duration":1.3712679999999864,"failureMessages":[],"location":{"line":179,"column":3},"meta":{},"tags":[]}],"startTime":1787953828345,"endTime":1787953828373.3713,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/executive-brief.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFamilyCStructure (aggregator)"],"fullName":"checkFamilyCStructure (aggregator) returns no failures when every Family C artifact is well-formed","status":"passed","title":"returns no failures when every Family C artifact is well-formed","duration":15.338300000000004,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFamilyCStructure (aggregator)"],"fullName":"checkFamilyCStructure (aggregator) aggregates failures from multiple sub-checks when artifacts are malformed","status":"passed","title":"aggregates failures from multiple sub-checks when artifacts are malformed","duration":1.9138130000000046,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]}],"startTime":1787953906862,"endTime":1787953906878.9138,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/family-c-structure.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFamilyDStructure (aggregator)"],"fullName":"checkFamilyDStructure (aggregator) returns no failures when both Family D artifacts are well-formed","status":"passed","title":"returns no failures when both Family D artifacts are well-formed","duration":6.215609000000029,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFamilyDStructure (aggregator)"],"fullName":"checkFamilyDStructure (aggregator) aggregates failures from both sub-checks","status":"passed","title":"aggregates failures from both sub-checks","duration":1.47742599999998,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]}],"startTime":1787953928326,"endTime":1787953928333.4775,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/family-d-structure.test.ts"},{"assertionResults":[{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators passes with 10+ dated indicators","status":"passed","title":"passes with 10+ dated indicators","duration":5.850454999999954,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators fails with fewer than 10 dated indicators","status":"passed","title":"fails with fewer than 10 dated indicators","duration":1.223651000000018,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkForwardIndicators"],"fullName":"checkForwardIndicators recognises quarterly date format","status":"passed","title":"recognises quarterly date format","duration":0.9095030000000293,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953926999,"endTime":1787953927006.9094,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/forward-indicators.test.ts"},{"assertionResults":[{"ancestorTitles":["checkIntelligenceAssessment"],"fullName":"checkIntelligenceAssessment passes with 3+ Key Judgments, confidence labels, and PIR","status":"passed","title":"passes with 3+ Key Judgments, confidence labels, and PIR","duration":5.942737000000022,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkIntelligenceAssessment"],"fullName":"checkIntelligenceAssessment fails with fewer than 3 Key Judgments","status":"passed","title":"fails with fewer than 3 Key Judgments","duration":1.1661339999999996,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]}],"startTime":1787953933717,"endTime":1787953933724.166,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/intelligence-assessment.test.ts"},{"assertionResults":[{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams passes with Mermaid block and style directive","status":"passed","title":"passes with Mermaid block and style directive","duration":4.945030000000031,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams passes with themeVariables","status":"passed","title":"passes with themeVariables","duration":1.9913689999999633,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams fails when Mermaid block missing","status":"passed","title":"fails when Mermaid block missing","duration":1.0531819999999925,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMermaidDiagrams"],"fullName":"checkMermaidDiagrams fails when colour config missing","status":"passed","title":"fails when colour config missing","duration":0.9869980000000282,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953925180,"endTime":1787953925188.987,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/mermaid-diagrams.test.ts"},{"assertionResults":[{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection passes when all nine required methodology-reflection sections are present","status":"passed","title":"passes when all nine required methodology-reflection sections are present","duration":9.570920999999998,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection accepts ## headings with leading emoji","status":"passed","title":"accepts ## headings with leading emoji","duration":1.5061709999999948,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when required sections are missing","status":"passed","title":"fails when required sections are missing","duration":1.7206009999999878,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when phrases are present only in body text but not as ## headings","status":"passed","title":"fails when phrases are present only in body text but not as ## headings","duration":0.8443609999999921,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when KJ Coverage Matrix has ❌ rows","status":"passed","title":"fails when KJ Coverage Matrix has ❌ rows","duration":1.132079000000033,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when a Confidence Distribution KJ row has empty Posterior","status":"passed","title":"fails when a Confidence Distribution KJ row has empty Posterior","duration":1.1436620000000062,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when Posterior cell is a `[REQUIRED]` placeholder","status":"passed","title":"fails when Posterior cell is a `[REQUIRED]` placeholder","duration":0.9877799999999866,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkMethodologyReflection"],"fullName":"checkMethodologyReflection fails when Re-run Log section is present but column header row is outside the section","status":"passed","title":"fails when Re-run Log section is present but column header row is outside the section","duration":0.9496780000000058,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]}],"startTime":1787953854425,"endTime":1787953854442.9497,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/methodology-reflection.test.ts"},{"assertionResults":[{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs passes when no stubs present","status":"passed","title":"passes when no stubs present","duration":5.9229799999999955,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects AI_MUST_REPLACE placeholder","status":"passed","title":"detects AI_MUST_REPLACE placeholder","duration":1.4892380000000003,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects TODO: placeholder","status":"passed","title":"detects TODO: placeholder","duration":0.9277569999999855,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects multiple stub types in same file","status":"passed","title":"detects multiple stub types in same file","duration":1.001985999999988,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkNoStubs"],"fullName":"checkNoStubs detects stubs in documents/ directory (Family E)","status":"passed","title":"detects stubs in documents/ directory (Family E)","duration":1.29140799999999,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]}],"startTime":1787953917050,"endTime":1787953917061.2915,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/no-stubs.test.ts"},{"assertionResults":[{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence exports the canonical 180_000 ms mtime threshold","status":"passed","title":"exports the canonical 180_000 ms mtime threshold","duration":4.193200999999988,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence passes when pass1/ snapshot differs from current file","status":"passed","title":"passes when pass1/ snapshot differs from current file","duration":3.1187400000000025,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence fails when pass1/ snapshot is identical to current file (no improvements)","status":"passed","title":"fails when pass1/ snapshot is identical to current file (no improvements)","duration":1.5890949999999862,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence skips artifacts that do not exist","status":"passed","title":"skips artifacts that do not exist","duration":0.7552550000000338,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPass2Evidence"],"fullName":"checkPass2Evidence returns pass2-evidence checkId on failure","status":"passed","title":"returns pass2-evidence checkId on failure","duration":1.2731540000000336,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953910897,"endTime":1787953910908.2732,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/pass2-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds extracts dok_ids from markdown content","status":"passed","title":"extracts dok_ids from markdown content","duration":4.554879000000028,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds deduplicates dok_ids","status":"passed","title":"deduplicates dok_ids","duration":0.8977510000000279,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds returns empty array when no dok_ids found","status":"passed","title":"returns empty array when no dok_ids found","duration":0.5134209999999939,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDokIds"],"fullName":"extractDokIds handles empty content","status":"passed","title":"handles empty content","duration":0.40315499999996973,"failureMessages":[],"location":{"line":43,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage passes when all dok_ids have analysis files","status":"passed","title":"passes when all dok_ids have analysis files","duration":2.168790999999999,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage reports missing document analysis","status":"passed","title":"reports missing document analysis","duration":1.2256250000000364,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage reports failure when manifest has no dok_ids","status":"passed","title":"reports failure when manifest has no dok_ids","duration":0.9659490000000233,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPerDocumentCoverage"],"fullName":"checkPerDocumentCoverage returns empty when manifest does not exist","status":"passed","title":"returns empty when manifest does not exist","duration":0.6386249999999905,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]}],"startTime":1787953910458,"endTime":1787953910469.6387,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/per-document-coverage.test.ts"},{"assertionResults":[{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus passes with valid pir-status.json","status":"passed","title":"passes with valid pir-status.json","duration":6.086866999999984,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when file missing","status":"passed","title":"fails when file missing","duration":0.9505500000000211,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails with invalid JSON","status":"passed","title":"fails with invalid JSON","duration":0.8820920000000001,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when schema_version is not 1.0","status":"passed","title":"fails when schema_version is not 1.0","duration":0.9355119999999602,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when subfolder != cycle","status":"passed","title":"fails when subfolder != cycle","duration":0.8155270000000314,"failureMessages":[],"location":{"line":77,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus validates PIR entry fields","status":"passed","title":"validates PIR entry fields","duration":0.9019289999999955,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus requires answer_summary when status is \"answered\"","status":"passed","title":"requires answer_summary when status is \"answered\"","duration":0.7986960000000067,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus passes when status is \"answered\" and answer_summary is present","status":"passed","title":"passes when status is \"answered\" and answer_summary is present","duration":0.8178110000000061,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkPirStatus"],"fullName":"checkPirStatus fails when non-answered PIR carries answer_summary","status":"passed","title":"fails when non-answered PIR carries answer_summary","duration":1.0171439999999734,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953870169,"endTime":1787953870182.017,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/pir-status.test.ts"},{"assertionResults":[{"ancestorTitles":["checkScenarioAnalysis"],"fullName":"checkScenarioAnalysis passes with 3+ scenarios","status":"passed","title":"passes with 3+ scenarios","duration":5.744567000000018,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkScenarioAnalysis"],"fullName":"checkScenarioAnalysis fails with fewer than 3 scenarios","status":"passed","title":"fails with fewer than 3 scenarios","duration":1.1303769999999531,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]}],"startTime":1787953937182,"endTime":1787953937189.1304,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/scenario-analysis.test.ts"},{"assertionResults":[{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence passes when all significance-scoring bullets have evidence","status":"passed","title":"passes when all significance-scoring bullets have evidence","duration":5.939391999999998,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence fails when significance-scoring bullet is missing evidence","status":"passed","title":"fails when significance-scoring bullet is missing evidence","duration":1.3199819999999818,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSignificanceScoringEvidence"],"fullName":"checkSignificanceScoringEvidence returns empty when significance-scoring.md does not exist","status":"passed","title":"returns empty when significance-scoring.md does not exist","duration":0.6786810000000401,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953930116,"endTime":1787953930123.6787,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/significance-scoring.test.ts"},{"assertionResults":[{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when no recognised agency mentioned","status":"passed","title":"passes when no recognised agency mentioned","duration":5.925566000000003,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when agency mentioned with statskontoret.se URL","status":"passed","title":"passes when agency mentioned with statskontoret.se URL","duration":1.378150000000005,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence passes when agency mentioned with \"none found\"","status":"passed","title":"passes when agency mentioned with \"none found\"","duration":0.8699090000000069,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStatskontoretEvidence"],"fullName":"checkStatskontoretEvidence fails when agency mentioned without Statskontoret row","status":"passed","title":"fails when agency mentioned without Statskontoret row","duration":0.78569200000004,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]}],"startTime":1787953919829,"endTime":1787953919837.7856,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/statskontoret-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence passes when all SWOT bullets have evidence","status":"passed","title":"passes when all SWOT bullets have evidence","duration":6.4625709999999685,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence fails when a SWOT bullet is missing evidence","status":"passed","title":"fails when a SWOT bullet is missing evidence","duration":1.4075559999999996,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkSwotEvidence"],"fullName":"checkSwotEvidence returns empty when swot-analysis.md does not exist","status":"passed","title":"returns empty when swot-analysis.md does not exist","duration":0.7080259999999612,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]}],"startTime":1787953930560,"endTime":1787953930568.708,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-checks/swot-evidence.test.ts"},{"assertionResults":[{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive returns empty array when directory does not exist","status":"passed","title":"returns empty array when directory does not exist","duration":4.539641000000017,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive collects top-level .md files only","status":"passed","title":"collects top-level .md files only","duration":1.583785999999975,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive recurses into nested directories and returns paths relative to baseDir","status":"passed","title":"recurses into nested directories and returns paths relative to baseDir","duration":1.2876109999999699,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["collectMdFilesRecursive"],"fullName":"collectMdFilesRecursive honours a non-empty prefix and joins paths under it","status":"passed","title":"honours a non-empty prefix and joins paths under it","duration":0.7306480000000306,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]}],"startTime":1787953919391,"endTime":1787953919399.7307,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-shared/file-walkers.test.ts"},{"assertionResults":[{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup returns plain headings unchanged","status":"passed","title":"returns plain headings unchanged","duration":3.765299999999968,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup strips simple HTML tags","status":"passed","title":"strips simple HTML tags","duration":0.5604289999999992,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup strips multi-tag HTML wrapping with collapse of whitespace","status":"passed","title":"strips multi-tag HTML wrapping with collapse of whitespace","duration":0.5736139999999637,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup decodes   entities","status":"passed","title":"decodes   entities","duration":0.3974240000000009,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["stripHeadingMarkup"],"fullName":"stripHeadingMarkup collapses internal whitespace and trims edges","status":"passed","title":"collapses internal whitespace and trims edges","duration":0.423753999999974,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading matches an H2 heading body","status":"passed","title":"matches an H2 heading body","duration":1.0609870000000114,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading matches an H4 heading","status":"passed","title":"matches an H4 heading","duration":0.478336000000013,"failureMessages":[],"location":{"line":51,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading does not match H1","status":"passed","title":"does not match H1","duration":0.32650200000000495,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading strips a leading emoji before matching","status":"passed","title":"strips a leading emoji before matching","duration":1.6907260000000406,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasHeading"],"fullName":"hasHeading returns false when no heading line matches","status":"passed","title":"returns false when no heading line matches","duration":0.35142700000000104,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection returns the body of the matching ## section","status":"passed","title":"returns the body of the matching ## section","duration":0.9051249999999982,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection stops at the next H2 heading","status":"passed","title":"stops at the next H2 heading","duration":0.5915880000000016,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection returns empty string when section is absent","status":"passed","title":"returns empty string when section is absent","duration":0.34638899999998785,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractSection"],"fullName":"extractSection tolerates an emoji prefix on the section heading","status":"passed","title":"tolerates an emoji prefix on the section heading","duration":0.45193599999998924,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives BULLET_RE matches dash and asterisk bullets","status":"passed","title":"BULLET_RE matches dash and asterisk bullets","duration":0.48168199999997796,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives TABLE_ROW_RE matches markdown table rows","status":"passed","title":"TABLE_ROW_RE matches markdown table rows","duration":0.46288700000002336,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives TABLE_SEP_RE matches table separator rows","status":"passed","title":"TABLE_SEP_RE matches table separator rows","duration":0.6452990000000227,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["exported regex primitives"],"fullName":"exported regex primitives ANY_HEADING_RE matches H1–H6","status":"passed","title":"ANY_HEADING_RE matches H1–H6","duration":0.46910800000000563,"failureMessages":[],"location":{"line":107,"column":3},"meta":{},"tags":[]}],"startTime":1787953903048,"endTime":1787953903062.469,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/agentic/gate-shared/markdown-helpers.test.ts"},{"assertionResults":[{"ancestorTitles":["canonical og:locale regex — anchor contract"],"fullName":"canonical og:locale regex — anchor contract the script defines a regex matching the single `<meta property=\"og:locale\">` tag","status":"passed","title":"the script defines a regex matching the single `<meta property=\"og:locale\">` tag","duration":3.648161000000016,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale regex — anchor contract"],"fullName":"canonical og:locale regex — anchor contract the script enumerates 14 canonical locale codes (en_US, sv_SE, da_DK, nb_NO, fi_FI, ...)","status":"passed","title":"the script enumerates 14 canonical locale codes (en_US, sv_SE, da_DK, nb_NO, fi_FI, ...)","duration":0.8596599999999626,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale alias rule — BCP-47 nb over legacy no"],"fullName":"canonical og:locale alias rule — BCP-47 nb over legacy no the alias table maps the legacy `no_NO` locale to canonical `nb_NO`","status":"passed","title":"the alias table maps the legacy `no_NO` locale to canonical `nb_NO`","duration":0.5817900000000122,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale alias rule — BCP-47 nb over legacy no"],"fullName":"canonical og:locale alias rule — BCP-47 nb over legacy no the script documents the BCP-47 preference (Norwegian Bokmål)","status":"passed","title":"the script documents the BCP-47 preference (Norwegian Bokmål)","duration":0.3811640000000125,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["canonical og:locale idempotency rule"],"fullName":"canonical og:locale idempotency rule the script documents the \"leave file alone if og:locale:alternate exists\" rule","status":"passed","title":"the script documents the \"leave file alone if og:locale:alternate exists\" rule","duration":0.4904989999999998,"failureMessages":[],"location":{"line":67,"column":3},"meta":{},"tags":[]}],"startTime":1787953913083,"endTime":1787953913088.4905,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/canonical.test.ts"},{"assertionResults":[{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts every metadata surface","status":"passed","title":"extracts every metadata surface","duration":5.788959000000034,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts meta tag content regardless of attribute order","status":"passed","title":"extracts meta tag content regardless of attribute order","duration":1.435767999999996,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent decodes entity-bearing unquoted meta attribute values","status":"passed","title":"decodes entity-bearing unquoted meta attribute values","duration":0.6242390000000455,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent populates bodyPlainText from <article> contents","status":"passed","title":"populates bodyPlainText from <article> contents","duration":0.6903429999999844,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent decodes HTML entities in metadata","status":"passed","title":"decodes HTML entities in metadata","duration":0.5364739999999983,"failureMessages":[],"location":{"line":84,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent returns empty lang when <html lang=\"…\"> is missing (CLI applies the fallback)","status":"passed","title":"returns empty lang when <html lang=\"…\"> is missing (CLI applies the fallback)","duration":0.5194520000000011,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts <html lang> from single-quoted, unquoted, and reordered attributes","status":"passed","title":"extracts <html lang> from single-quoted, unquoted, and reordered attributes","duration":0.7163409999999999,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent extracts JSON-LD with extra/reordered attributes and single quotes","status":"passed","title":"extracts JSON-LD with extra/reordered attributes and single quotes","duration":0.413503999999989,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent survives a malformed JSON-LD block without crashing","status":"passed","title":"survives a malformed JSON-LD block without crashing","duration":0.5054560000000379,"failureMessages":[],"location":{"line":116,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent scans multiple JSON-LD blocks and picks the first with the field","status":"passed","title":"scans multiple JSON-LD blocks and picks the first with the field","duration":0.4634680000000344,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent handles JSON-LD @graph arrays","status":"passed","title":"handles JSON-LD @graph arrays","duration":0.4586889999999926,"failureMessages":[],"location":{"line":131,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode test helper decodes numeric references","status":"passed","title":"htmlDecode test helper decodes numeric references","duration":0.4041260000000193,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode leaves invalid numeric references untouched","status":"passed","title":"htmlDecode leaves invalid numeric references untouched","duration":0.42016700000004903,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent htmlDecode is single-pass (CodeQL js/double-escaping regression)","status":"passed","title":"htmlDecode is single-pass (CodeQL js/double-escaping regression)","duration":0.39168300000000045,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags test helper removes inline tags and collapses whitespace","status":"passed","title":"stripTags test helper removes inline tags and collapses whitespace","duration":0.43452300000001287,"failureMessages":[],"location":{"line":158,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags handles script/style end tags with whitespace before `>`","status":"passed","title":"stripTags handles script/style end tags with whitespace before `>`","duration":0.3857320000000186,"failureMessages":[],"location":{"line":162,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent stripTags handles malformed script end tags with trailing tokens","status":"passed","title":"stripTags handles malformed script end tags with trailing tokens","duration":0.3605049999999892,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["html-inspector: inspectHtmlContent"],"fullName":"html-inspector: inspectHtmlContent inspectHtmlContent strips a script block whose end tag has whitespace","status":"passed","title":"inspectHtmlContent strips a script block whose end tag has whitespace","duration":0.4661429999999882,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]}],"startTime":1787953837733,"endTime":1787953837747.466,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/hreflang.test.ts"},{"assertionResults":[{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script exists (memory: hand-authored bypass pipeline)","status":"passed","title":"the backfill script exists (memory: hand-authored bypass pipeline)","duration":3.7123210000000313,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script targets the hand-authored breaking-news family (memory pin)","status":"passed","title":"the backfill script targets the hand-authored breaking-news family (memory pin)","duration":0.7214209999999639,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script walks the `news/` directory (covers all hand-authored families)","status":"passed","title":"the backfill script walks the `news/` directory (covers all hand-authored families)","duration":0.6210130000000049,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate backfill — hand-authored coverage"],"fullName":"og:locale:alternate backfill — hand-authored coverage the backfill script supports --dry-run (smoke-check contract)","status":"passed","title":"the backfill script supports --dry-run (smoke-check contract)","duration":0.48522800000000643,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — html-inspector surface (smoke)"],"fullName":"og:locale:alternate — html-inspector surface (smoke) inspectHtmlContent extracts `<html lang>` (the alternate base lang)","status":"passed","title":"inspectHtmlContent extracts `<html lang>` (the alternate base lang)","duration":1.5605919999999855,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — html-inspector surface (smoke)"],"fullName":"og:locale:alternate — html-inspector surface (smoke) inspectHtmlContent surfaces an empty lang when `<html lang>` is missing","status":"passed","title":"inspectHtmlContent surfaces an empty lang when `<html lang>` is missing","duration":0.5903059999999982,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — 14-language registry parity"],"fullName":"og:locale:alternate — 14-language registry parity every language in the news-indexes 14-language list has an og locale value","status":"passed","title":"every language in the news-indexes 14-language list has an og locale value","duration":1.92307100000005,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["og:locale:alternate — 14-language registry parity"],"fullName":"og:locale:alternate — 14-language registry parity Norwegian uses BCP-47 nb_NO (not no_NO) for og:locale:alternate","status":"passed","title":"Norwegian uses BCP-47 nb_NO (not no_NO) for og:locale:alternate","duration":0.41071899999997186,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]}],"startTime":1787953900650,"endTime":1787953900661.4106,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/backfill-article-metadata/rules/og-locale-alternate.test.ts"},{"assertionResults":[{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a valid MCP JSON-RPC `kalender` response","status":"passed","title":"returns events from a valid MCP JSON-RPC `kalender` response","duration":5.861635999999976,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a direct `result.kalender` response (no content wrapper)","status":"passed","title":"returns events from a direct `result.kalender` response (no content wrapper)","duration":0.8233109999999897,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns events from a `result.events` key","status":"passed","title":"returns events from a `result.events` key","duration":0.7094180000000279,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) when MCP returns an HTML document","status":"passed","title":"throws CalendarMcpError(html) when MCP returns an HTML document","duration":2.7908760000000257,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(http) on a non-OK HTTP status with non-HTML body","status":"passed","title":"throws CalendarMcpError(http) on a non-OK HTTP status with non-HTML body","duration":0.714006999999981,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(network) on a fetch network error","status":"passed","title":"throws CalendarMcpError(network) on a fetch network error","duration":0.7068830000000048,"failureMessages":[],"location":{"line":126,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(tool) when the JSON-RPC response has an `error` field","status":"passed","title":"throws CalendarMcpError(tool) when the JSON-RPC response has an `error` field","duration":0.5751170000000343,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns an empty array when `result.kalender` is an empty array","status":"passed","title":"returns an empty array when `result.kalender` is an empty array","duration":0.6677799999999934,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents returns an empty array when `result` has no recognised events key","status":"passed","title":"returns an empty array when `result` has no recognised events key","duration":0.7339750000000436,"failureMessages":[],"location":{"line":165,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on the degraded-kalender sentinel in content text","status":"passed","title":"throws CalendarMcpError(html) on the degraded-kalender sentinel in content text","duration":0.8561440000000289,"failureMessages":[],"location":{"line":176,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on a degraded sentinel in a direct result (no content wrapper)","status":"passed","title":"throws CalendarMcpError(html) on a degraded sentinel in a direct result (no content wrapper)","duration":0.5519429999999943,"failureMessages":[],"location":{"line":200,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(json) when content text is malformed JSON","status":"passed","title":"throws CalendarMcpError(json) when content text is malformed JSON","duration":0.6672700000000304,"failureMessages":[],"location":{"line":220,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents includes rawHtml in responseText when sentinel has rawHtml","status":"passed","title":"includes rawHtml in responseText when sentinel has rawHtml","duration":0.7287249999999972,"failureMessages":[],"location":{"line":236,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents includes the error string in the thrown message for degraded sentinel","status":"passed","title":"includes the error string in the thrown message for degraded sentinel","duration":1.3739229999999907,"failureMessages":[],"location":{"line":259,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["callMcpCalendarEvents"],"fullName":"callMcpCalendarEvents throws CalendarMcpError(html) on a rawHtml-only sentinel (no error field)","status":"passed","title":"throws CalendarMcpError(html) on a rawHtml-only sentinel (no error field)","duration":0.6231570000000488,"failureMessages":[],"location":{"line":277,"column":3},"meta":{},"tags":[]}],"startTime":1787953833931,"endTime":1787953833949.623,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/client.test.ts"},{"assertionResults":[{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a DOCTYPE HTML response","status":"passed","title":"returns true for a DOCTYPE HTML response","duration":3.7126719999999978,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a lower-case <!doctype html> response","status":"passed","title":"returns true for a lower-case <!doctype html> response","duration":0.5718709999999874,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a bare <html> opening tag","status":"passed","title":"returns true for a bare <html> opening tag","duration":0.46478000000001884,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for an uppercase <HTML> opening tag","status":"passed","title":"returns true for an uppercase <HTML> opening tag","duration":0.3246780000000058,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a leading <head> tag fragment","status":"passed","title":"returns true for a leading <head> tag fragment","duration":0.47185400000000755,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for a self-closing <meta /> fragment","status":"passed","title":"returns true for a self-closing <meta /> fragment","duration":0.47958799999997836,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for a JSON response","status":"passed","title":"returns false for a JSON response","duration":0.383707999999956,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for an empty string","status":"passed","title":"returns false for an empty string","duration":0.3020559999999932,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns false for a leading whitespace + JSON response","status":"passed","title":"returns false for a leading whitespace + JSON response","duration":0.6171860000000038,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isHtmlErrorResponse"],"fullName":"isHtmlErrorResponse returns true for whitespace before DOCTYPE","status":"passed","title":"returns true for whitespace before DOCTYPE","duration":0.4915409999999838,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) matches the canonical HTML opening sequences","status":"passed","title":"matches the canonical HTML opening sequences","duration":0.5085520000000088,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) does NOT match JSON or JSON-RPC payloads","status":"passed","title":"does NOT match JSON or JSON-RPC payloads","duration":0.38260600000000977,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["HTML_PREFIX_RE (regex guard against future drift)"],"fullName":"HTML_PREFIX_RE (regex guard against future drift) does NOT match plain text or empty strings","status":"passed","title":"does NOT match plain text or empty strings","duration":0.48954700000001594,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when an upstream error string is present","status":"passed","title":"returns true when an upstream error string is present","duration":0.5006270000000086,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when a rawHtml field is present","status":"passed","title":"returns true when a rawHtml field is present","duration":0.4370580000000359,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true when both error and rawHtml are present","status":"passed","title":"returns true when both error and rawHtml are present","duration":0.4002800000000093,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns true for rawHtml-only sentinel without error field","status":"passed","title":"returns true for rawHtml-only sentinel without error field","duration":0.3750830000000178,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false for a legitimate empty calendar window","status":"passed","title":"returns false for a legitimate empty calendar window","duration":0.37114400000001524,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false when error/rawHtml are empty or whitespace","status":"passed","title":"returns false when error/rawHtml are empty or whitespace","duration":0.3503759999999829,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false when error/rawHtml are non-string types","status":"passed","title":"returns false when error/rawHtml are non-string types","duration":0.5428459999999973,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isDegradedKalenderSentinel"],"fullName":"isDegradedKalenderSentinel returns false for an empty object","status":"passed","title":"returns false for an empty object","duration":0.477484000000004,"failureMessages":[],"location":{"line":141,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarMcpError"],"fullName":"CalendarMcpError has the correct name and kind","status":"passed","title":"has the correct name and kind","duration":0.6981670000000122,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["CalendarMcpError"],"fullName":"CalendarMcpError correctly identifies all error kinds","status":"passed","title":"correctly identifies all error kinds","duration":0.6356400000000235,"failureMessages":[],"location":{"line":155,"column":3},"meta":{},"tags":[]}],"startTime":1787953869709,"endTime":1787953869723.6357,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/errors.test.ts"},{"assertionResults":[{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent maps standard MCP event fields","status":"passed","title":"maps standard MCP event fields","duration":4.687937999999974,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent handles upper-case DTSTART / SUMMARY keys","status":"passed","title":"handles upper-case DTSTART / SUMMARY keys","duration":0.6637029999999982,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent includes dtend when present","status":"passed","title":"includes dtend when present","duration":0.39392700000001923,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent collects multiple doc_refs from array fields","status":"passed","title":"collects multiple doc_refs from array fields","duration":0.7654529999999795,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent handles null / undefined gracefully","status":"passed","title":"handles null / undefined gracefully","duration":1.0869350000000395,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeMcpCalendarEvent"],"fullName":"normalizeMcpCalendarEvent omits dtend when not present in raw event","status":"passed","title":"omits dtend when not present in raw event","duration":0.6026789999999664,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953918028,"endTime":1787953918036.6028,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/mcp/normaliser.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle returns null when no datetime found","status":"passed","title":"returns null when no datetime found","duration":3.6400350000000117,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle extracts organ and akt from data attributes","status":"passed","title":"extracts organ and akt from data attributes","duration":1.6041940000000068,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarArticle"],"fullName":"parseCalendarArticle falls back to span text for org and akt when data attributes absent","status":"passed","title":"falls back to span text for org and akt when data attributes absent","duration":1.0738799999999742,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]}],"startTime":1787953938943,"endTime":1787953938949.074,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/article-block.test.ts"},{"assertionResults":[{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime extracts the datetime attribute from a <time> tag","status":"passed","title":"extracts the datetime attribute from a <time> tag","duration":3.8027099999999905,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime returns null when no <time> tag is present","status":"passed","title":"returns null when no <time> tag is present","duration":0.6187189999999987,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDatetime"],"fullName":"extractDatetime returns null when <time> has no datetime attribute","status":"passed","title":"returns null when <time> has no datetime attribute","duration":0.4622659999999996,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns true when class list contains calendar-item","status":"passed","title":"returns true when class list contains calendar-item","duration":0.5257540000000063,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns true with single-quoted attribute","status":"passed","title":"returns true with single-quoted attribute","duration":0.3925460000000385,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["hasCalendarItemClass"],"fullName":"hasCalendarItemClass returns false when class list does not contain calendar-item","status":"passed","title":"returns false when class list does not contain calendar-item","duration":0.52489300000002,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDataAttr"],"fullName":"extractDataAttr extracts a data-* attribute value","status":"passed","title":"extracts a data-* attribute value","duration":0.5494390000000067,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractDataAttr"],"fullName":"extractDataAttr returns null when attribute is missing","status":"passed","title":"returns null when attribute is missing","duration":0.425596999999982,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isRiksdagDocumentHref"],"fullName":"isRiksdagDocumentHref accepts canonical betankande paths","status":"passed","title":"accepts canonical betankande paths","duration":0.5046749999999633,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["isRiksdagDocumentHref"],"fullName":"isRiksdagDocumentHref rejects unrelated URLs","status":"passed","title":"rejects unrelated URLs","duration":0.44606499999997595,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeOrgCode"],"fullName":"normalizeOrgCode uppercases short organ codes","status":"passed","title":"uppercases short organ codes","duration":0.7577090000000339,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953921158,"endTime":1787953921167.7578,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/extractors.test.ts"},{"assertionResults":[{"ancestorTitles":["parseCalendarListItem"],"fullName":"parseCalendarListItem returns null when no datetime found","status":"passed","title":"returns null when no datetime found","duration":3.6457359999999994,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseCalendarListItem"],"fullName":"parseCalendarListItem extracts all fields from a well-formed list item","status":"passed","title":"extracts all fields from a well-formed list item","duration":3.0416649999999663,"failureMessages":[],"location":{"line":20,"column":3},"meta":{},"tags":[]}],"startTime":1787953939376,"endTime":1787953939383.0417,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/list-item.test.ts"},{"assertionResults":[{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml parses article pattern events","status":"passed","title":"parses article pattern events","duration":6.585950999999966,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml falls back to list-item pattern when no articles found","status":"passed","title":"falls back to list-item pattern when no articles found","duration":1.3502280000000155,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml returns empty array for HTML with no recognisable calendar markup","status":"passed","title":"returns empty array for HTML with no recognisable calendar markup","duration":1.048813999999993,"failureMessages":[],"location":{"line":78,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml ignores non-calendar article blocks even when they contain time elements","status":"passed","title":"ignores non-calendar article blocks even when they contain time elements","duration":0.5484769999999912,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseRiksdagKalendariumHtml"],"fullName":"parseRiksdagKalendariumHtml parses calendar-item articles when class attribute uses single quotes","status":"passed","title":"parses calendar-item articles when class attribute uses single quotes","duration":0.6371630000000437,"failureMessages":[],"location":{"line":93,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar fetches and parses a calendar page with article events","status":"passed","title":"fetches and parses a calendar page with article events","duration":1.6512519999999995,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar throws on a non-OK HTTP response","status":"passed","title":"throws on a non-OK HTTP response","duration":1.8680980000000318,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["fetchWebCalendar"],"fullName":"fetchWebCalendar throws on a network fetch failure","status":"passed","title":"throws on a network fetch failure","duration":0.6653850000000148,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]}],"startTime":1787953872841,"endTime":1787953872855.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/fetch-calendar/scraper/parse.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json exposes every coreLanguages value as a key in the 14-language list","status":"passed","title":"exposes every coreLanguages value as a key in the 14-language list","duration":3.884093000000007,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json every registry workflow file exists in .github/workflows/","status":"passed","title":"every registry workflow file exists in .github/workflows/","duration":1.140736000000004,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json every registry entry uses one of the known families (tier-A/B/C surface)","status":"passed","title":"every registry entry uses one of the known families (tier-A/B/C surface)","duration":0.6877780000000371,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — registry parity vs analysis/article-types.json"],"fullName":"generate-news-indexes/constants — registry parity vs analysis/article-types.json has at least one tier-C aggregation entry (week-ahead / month-ahead)","status":"passed","title":"has at least one tier-C aggregation entry (week-ahead / month-ahead)","duration":0.5380170000000248,"failureMessages":[],"location":{"line":86,"column":3},"meta":{},"tags":[]}],"startTime":1787953909582,"endTime":1787953909587.6877,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/constants/article-types.test.ts"},{"assertionResults":[{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should return object with all 14 language keys","status":"passed","title":"should return object with all 14 language keys","duration":5077.173564999999,"failureMessages":[],"location":{"line":56,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should return arrays for each language","status":"passed","title":"should return arrays for each language","duration":5125.172743,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["scanNewsArticles"],"fullName":"scanNewsArticles should sort articles by date descending","status":"passed","title":"should sort articles by date descending","duration":5115.504405,"failureMessages":[],"location":{"line":83,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits FAQPage JSON-LD","status":"passed","title":"emits FAQPage JSON-LD","duration":19.091617000000042,"failureMessages":[],"location":{"line":115,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits a visible FAQ section with localised heading","status":"passed","title":"emits a visible FAQ section with localised heading","duration":1.3621210000001156,"failureMessages":[],"location":{"line":120,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features localises the FAQ heading for Swedish","status":"passed","title":"localises the FAQ heading for Swedish","duration":1.0963130000000092,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features emits a crawler-visible article list as a collapsible <details> block","status":"passed","title":"emits a crawler-visible article list as a collapsible <details> block","duration":0.9756769999985409,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — SEO features"],"fullName":"generate-news-indexes/template — SEO features does NOT use inline positioning styles on the article list","status":"passed","title":"does NOT use inline positioning styles on the article list","duration":1.2273679999998421,"failureMessages":[],"location":{"line":140,"column":3},"meta":{},"tags":[]}],"startTime":1787953873316,"endTime":1787953888658.2273,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/article-merge.test.ts"},{"assertionResults":[{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should parse metadata from a real article file","status":"passed","title":"should parse metadata from a real article file","duration":61.25865699999997,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should return null for non-article files","status":"passed","title":"should return null for non-article files","duration":1.3488760000000184,"failureMessages":[],"location":{"line":88,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract correct language from filename suffix","status":"passed","title":"should extract correct language from filename suffix","duration":8.879728,"failureMessages":[],"location":{"line":101,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should classify week-ahead articles as prospective","status":"passed","title":"should classify week-ahead articles as prospective","duration":1.5566650000000095,"failureMessages":[],"location":{"line":125,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should classify committee-reports as analysis","status":"passed","title":"should classify committee-reports as analysis","duration":1.1918919999999957,"failureMessages":[],"location":{"line":142,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract topics from article:tag meta tags","status":"passed","title":"should extract topics from article:tag meta tags","duration":2.0017879999999764,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["parseArticleMetadata"],"fullName":"parseArticleMetadata should extract tags from article:tag meta tags","status":"passed","title":"should extract tags from article:tag meta tags","duration":1.1993160000000103,"failureMessages":[],"location":{"line":181,"column":5},"meta":{},"tags":[]}],"startTime":1787953848664,"endTime":1787953848741.1992,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/frontmatter.test.ts"},{"assertionResults":[{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags emits one <link rel=\"alternate\"> per language plus x-default","status":"passed","title":"emits one <link rel=\"alternate\"> per language plus x-default","duration":3.934718000000032,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags includes x-default pointing to news/index.html","status":"passed","title":"includes x-default pointing to news/index.html","duration":0.7496739999999704,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags maps Norwegian hreflang to nb (BCP-47)","status":"passed","title":"maps Norwegian hreflang to nb (BCP-47)","duration":0.5411240000000248,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateHreflangTags"],"fullName":"generate-news-indexes/template — generateHreflangTags includes Swedish alternate link","status":"passed","title":"includes Swedish alternate link","duration":0.5401709999999866,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles returns empty string for non-RTL pages","status":"passed","title":"returns empty string for non-RTL pages","duration":0.7301569999999629,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles returns RTL styles for RTL pages","status":"passed","title":"returns RTL styles for RTL pages","duration":0.49399599999998145,"failureMessages":[],"location":{"line":55,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateRTLStyles"],"fullName":"generate-news-indexes/template — generateRTLStyles RTL styles include direction-aware transforms","status":"passed","title":"RTL styles include direction-aware transforms","duration":0.5931509999999776,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns empty string for unsupported language key","status":"passed","title":"returns empty string for unsupported language key","duration":0.46313700000001745,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Danish","status":"passed","title":"returns a notice for Danish","duration":0.6502570000000105,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Norwegian","status":"passed","title":"returns a notice for Norwegian","duration":0.4599010000000021,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Arabic with dir=\"ltr\" on the EN badge","status":"passed","title":"returns a notice for Arabic with dir=\"ltr\" on the EN badge","duration":0.531265000000019,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a notice for Hebrew with dir=\"ltr\" on the EN badge","status":"passed","title":"returns a notice for Hebrew with dir=\"ltr\" on the EN badge","duration":0.4409660000000031,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice notices for non-RTL languages do not include dir=\"ltr\" on the badge","status":"passed","title":"notices for non-RTL languages do not include dir=\"ltr\" on the badge","duration":0.5085920000000215,"failureMessages":[],"location":{"line":96,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: da","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: da","duration":0.6396679999999719,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: no","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: no","duration":0.4262679999999932,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: fi","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: fi","duration":0.43754899999999,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: de","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: de","duration":0.46279600000002574,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: fr","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: fr","duration":0.36505399999998644,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: es","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: es","duration":0.45294799999999213,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: nl","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: nl","duration":0.3705639999999448,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ar","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ar","duration":0.5472649999999817,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: he","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: he","duration":0.4203069999999798,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ja","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ja","duration":0.5059669999999983,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: ko","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: ko","duration":0.4400039999999876,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/template — generateLanguageNotice"],"fullName":"generate-news-indexes/template — generateLanguageNotice returns a non-empty notice for every non-EN/SV language: zh","status":"passed","title":"returns a non-empty notice for every non-EN/SV language: zh","duration":0.4347439999999665,"failureMessages":[],"location":{"line":101,"column":84},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list exports exactly 14 languages (single source of truth)","status":"passed","title":"exports exactly 14 languages (single source of truth)","duration":1.2694769999999949,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list uses BCP-47 nb (not legacy no) for Norwegian hreflang","status":"passed","title":"uses BCP-47 nb (not legacy no) for Norwegian hreflang","duration":0.5900850000000446,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list marks Arabic and Hebrew as RTL","status":"passed","title":"marks Arabic and Hebrew as RTL","duration":0.48241299999995135,"failureMessages":[],"location":{"line":138,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["generate-news-indexes/constants — 14-language list"],"fullName":"generate-news-indexes/constants — 14-language list marks all other languages as LTR (rtl flag absent or false)","status":"passed","title":"marks all other languages as LTR (rtl flag absent or false)","duration":0.8681460000000243,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]}],"startTime":1787953869247,"endTime":1787953869266.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/i18n.test.ts"},{"assertionResults":[{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify German prospective articles","status":"passed","title":"should classify German prospective articles","duration":55.200946999999985,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify French analysis articles","status":"passed","title":"should classify French analysis articles","duration":1.6376269999999522,"failureMessages":[],"location":{"line":76,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Japanese breaking news articles","status":"passed","title":"should classify Japanese breaking news articles","duration":3.8657680000000028,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Arabic prospective articles","status":"passed","title":"should classify Arabic prospective articles","duration":0.8729050000000029,"failureMessages":[],"location":{"line":108,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Finnish analysis articles","status":"passed","title":"should classify Finnish analysis articles","duration":1.1230429999999956,"failureMessages":[],"location":{"line":124,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should classify Korean breaking news articles","status":"passed","title":"should classify Korean breaking news articles","duration":0.909121999999968,"failureMessages":[],"location":{"line":140,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["classifyArticleType multi-language"],"fullName":"classifyArticleType multi-language should default to retrospective when no keywords match","status":"passed","title":"should default to retrospective when no keywords match","duration":0.9731120000000146,"failureMessages":[],"location":{"line":156,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from German tags","status":"passed","title":"should extract topics from German tags","duration":2.0821679999999674,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from Japanese tags","status":"passed","title":"should extract topics from Japanese tags","duration":1.234310999999991,"failureMessages":[],"location":{"line":205,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["extractTopics multi-language"],"fullName":"extractTopics multi-language should extract topics from Arabic tags","status":"passed","title":"should extract topics from Arabic tags","duration":1.3749740000000088,"failureMessages":[],"location":{"line":224,"column":5},"meta":{},"tags":[]}],"startTime":1787953836240,"endTime":1787953836309.375,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/helpers/slug.test.ts"},{"assertionResults":[{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) assembles all five fragments in the expected order","status":"passed","title":"assembles all five fragments in the expected order","duration":4.123801999999955,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) produces a non-empty runtime body","status":"passed","title":"produces a non-empty runtime body","duration":0.6050330000000486,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime entry (CSP-relevant)"],"fullName":"client-script-runtime entry (CSP-relevant) stays under the 200 KB CSP audit budget (single review unit)","status":"passed","title":"stays under the 200 KB CSP audit budget (single review unit)","duration":0.4930530000000317,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — helpers fragment"],"fullName":"client-script-runtime — helpers fragment exposes the esc() XSS-safe HTML escaper","status":"passed","title":"exposes the esc() XSS-safe HTML escaper","duration":0.4665340000000242,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — rendering fragment"],"fullName":"client-script-runtime — rendering fragment defines buildArticleCard()","status":"passed","title":"defines buildArticleCard()","duration":0.4545709999999872,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — rendering fragment"],"fullName":"client-script-runtime — rendering fragment escapes article fields through esc()","status":"passed","title":"escapes article fields through esc()","duration":0.4975610000000188,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — filtering fragment"],"fullName":"client-script-runtime — filtering fragment wires the type and topic filter selects","status":"passed","title":"wires the type and topic filter selects","duration":0.44525399999997717,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — sorting fragment"],"fullName":"client-script-runtime — sorting fragment wires the sort filter select","status":"passed","title":"wires the sort filter select","duration":0.37751700000001165,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["client-script-runtime — search fragment"],"fullName":"client-script-runtime — search fragment wires the search input","status":"passed","title":"wires the search input","duration":0.4741080000000011,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]}],"startTime":1787953913509,"endTime":1787953913517.474,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/template/client-script-runtime.test.ts"},{"assertionResults":[{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include collapsible filter-bar-wrapper details element","status":"passed","title":"should include collapsible filter-bar-wrapper details element","duration":4.045968999999786,"failureMessages":[],"location":{"line":40,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include clear-filters button with localized English label","status":"passed","title":"should include clear-filters button with localized English label","duration":0.7591410000004544,"failureMessages":[],"location":{"line":46,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localized clear-filters label for Swedish","status":"passed","title":"should include localized clear-filters label for Swedish","duration":0.5378280000004452,"failureMessages":[],"location":{"line":52,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localized clear-filters label for Arabic","status":"passed","title":"should include localized clear-filters label for Arabic","duration":0.49230199999965407,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include filter-active-count badge with aria-live","status":"passed","title":"should include filter-active-count badge with aria-live","duration":0.6016669999999067,"failureMessages":[],"location":{"line":60,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include article-card-skeleton elements in articles grid","status":"passed","title":"should include article-card-skeleton elements in articles grid","duration":0.7607539999999062,"failureMessages":[],"location":{"line":65,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should set aria-busy on articles grid initially for skeleton state","status":"passed","title":"should set aria-busy on articles grid initially for skeleton state","duration":0.5393000000003667,"failureMessages":[],"location":{"line":73,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include skeleton cards with aria-hidden for accessibility","status":"passed","title":"should include skeleton cards with aria-hidden for accessibility","duration":0.6916849999997794,"failureMessages":[],"location":{"line":78,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include computeRecency function in client script","status":"passed","title":"should include computeRecency function in client script","duration":1.3490870000005089,"failureMessages":[],"location":{"line":86,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include RECENCY_LABELS JSON blob in client script","status":"passed","title":"should include RECENCY_LABELS JSON blob in client script","duration":1.475282999999763,"failureMessages":[],"location":{"line":93,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should localise RECENCY_LABELS for Swedish","status":"passed","title":"should localise RECENCY_LABELS for Swedish","duration":1.1116910000000644,"failureMessages":[],"location":{"line":100,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include localizeRecency function in client script","status":"passed","title":"should include localizeRecency function in client script","duration":0.4572870000001785,"failureMessages":[],"location":{"line":106,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include recency-badge in article card builder","status":"passed","title":"should include recency-badge in article card builder","duration":0.6878790000000663,"failureMessages":[],"location":{"line":110,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include data-date-recent attribute in article card builder","status":"passed","title":"should include data-date-recent attribute in article card builder","duration":0.4730549999994764,"failureMessages":[],"location":{"line":115,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include updateFilterChrome function in client script","status":"passed","title":"should include updateFilterChrome function in client script","duration":0.6116159999992306,"failureMessages":[],"location":{"line":119,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include clearAllFilters function in client script","status":"passed","title":"should include clearAllFilters function in client script","duration":0.5056370000002062,"failureMessages":[],"location":{"line":124,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should wire clear-filters button to clearAllFilters via onclick","status":"passed","title":"should wire clear-filters button to clearAllFilters via onclick","duration":0.46412899999995716,"failureMessages":[],"location":{"line":128,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should apply dir=\"ltr\" to language badges in RTL layout (Arabic)","status":"passed","title":"should apply dir=\"ltr\" to language badges in RTL layout (Arabic)","duration":0.5684550000005402,"failureMessages":[],"location":{"line":133,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should set IS_RTL = false for non-RTL languages (English)","status":"passed","title":"should set IS_RTL = false for non-RTL languages (English)","duration":0.42052700000022014,"failureMessages":[],"location":{"line":147,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["Phase 2 UI features"],"fullName":"Phase 2 UI features should include filter-bar with all four filter groups","status":"passed","title":"should include filter-bar with all four filter groups","duration":0.5483969999995679,"failureMessages":[],"location":{"line":154,"column":7},"meta":{},"tags":[]}],"startTime":1787953846722,"endTime":1787953846739.5483,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/generate-news-indexes/template/phase2-ui-features.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary walks the scripts/imf tree and finds .ts source files (sanity)","status":"passed","title":"walks the scripts/imf tree and finds .ts source files (sanity)","duration":3.6431519999999864,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary reads IMF_SDMX_SUBSCRIPTION_KEY from process.env in exactly one file","status":"passed","title":"reads IMF_SDMX_SUBSCRIPTION_KEY from process.env in exactly one file","duration":1.8046489999999835,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF SDMX subscription key auth boundary"],"fullName":"IMF SDMX subscription key auth boundary the auth boundary file actually contains a process.env read","status":"passed","title":"the auth boundary file actually contains a process.env read","duration":0.7146380000000363,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]}],"startTime":1787953923860,"endTime":1787953923866.7146,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/config/auth.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfClient constructor"],"fullName":"ImfClient constructor applies sensible defaults","status":"passed","title":"applies sensible defaults","duration":4.3400760000000105,"failureMessages":[],"location":{"line":16,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient constructor"],"fullName":"ImfClient constructor accepts overrides","status":"passed","title":"accepts overrides","duration":0.6262930000000324,"failureMessages":[],"location":{"line":29,"column":3},"meta":{},"tags":[]}],"startTime":1787953931892,"endTime":1787953931896.6262,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/config/defaults.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError exposes name, status, and retryable for a 500 response","status":"passed","title":"exposes name, status, and retryable for a 500 response","duration":4.347430000000031,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError marks 429 as retryable","status":"passed","title":"marks 429 as retryable","duration":0.5745060000000421,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError marks 404 as NOT retryable","status":"passed","title":"marks 404 as NOT retryable","duration":0.4858400000000529,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfHttpError"],"fullName":"ImfHttpError captures Retry-After header when present","status":"passed","title":"captures Retry-After header when present","duration":0.458217999999988,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]}],"startTime":1787953934587,"endTime":1787953934592.4858,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/errors/http-error.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfWeoSdmxOnlyError"],"fullName":"ImfWeoSdmxOnlyError error payload carries the SDMX path so callers can recover programmatically","status":"passed","title":"error payload carries the SDMX path so callers can recover programmatically","duration":5.768772000000013,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfWeoSdmxOnlyError"],"fullName":"ImfWeoSdmxOnlyError normalises lower-cased ISO3 inputs to upper-case in the error payload","status":"passed","title":"normalises lower-cased ISO3 inputs to upper-case in the error payload","duration":0.7948079999999891,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]}],"startTime":1787953932804,"endTime":1787953932810.795,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/errors/weo-sdmx-only.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form exposes the four canonical GF##_T codes as named exports","status":"passed","title":"exposes the four canonical GF##_T codes as named exports","duration":3.9099520000000325,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form IMF_GFS_COFOG_CODES catalog contains every GF##_T entry","status":"passed","title":"IMF_GFS_COFOG_CODES catalog contains every GF##_T entry","duration":1.5802189999999996,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form rejects the retired bare G02 / G07 / G09 / G10 codes","status":"passed","title":"rejects the retired bare G02 / G07 / G09 / G10 codes","duration":0.7656129999999735,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF GFS COFOG codes — canonical GF##_T form"],"fullName":"IMF GFS COFOG codes — canonical GF##_T form every catalog value matches the GF##_T pattern","status":"passed","title":"every catalog value matches the GF##_T pattern","duration":0.5918980000000147,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953931016,"endTime":1787953931023.5918,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/cofog-codes.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF_FM_INDICATORS"],"fullName":"IMF_FM_INDICATORS exposes Fiscal Monitor indicators","status":"passed","title":"exposes Fiscal Monitor indicators","duration":3.6305469999999787,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]}],"startTime":1787953941146,"endTime":1787953941149.6306,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/fm.test.ts"},{"assertionResults":[{"ancestorTitles":["IMF_WEO_INDICATORS"],"fullName":"IMF_WEO_INDICATORS exposes the canonical WEO headline indicator codes","status":"passed","title":"exposes the canonical WEO headline indicator codes","duration":3.7154969999999707,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY lists exactly the 9 WEO codes verified live on the Datamapper (2026-05-10)","status":"passed","title":"lists exactly the 9 WEO codes verified live on the Datamapper (2026-05-10)","duration":1.1996770000000083,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY flags the 4 IMF_WEO_INDICATORS codes that are SDMX-only (Datamapper returns empty envelopes)","status":"passed","title":"flags the 4 IMF_WEO_INDICATORS codes that are SDMX-only (Datamapper returns empty envelopes)","duration":0.45988099999999577,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY"],"fullName":"IMF_WEO_DATAMAPPER_AVAILABLE / IMF_WEO_SDMX_ONLY partitions IMF_WEO_INDICATORS into available + SDMX-only with no overlap","status":"passed","title":"partitions IMF_WEO_INDICATORS into available + SDMX-only with no overlap","duration":0.838279,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath builds the canonical WEO 9.0.0 SDMX path","status":"passed","title":"builds the canonical WEO 9.0.0 SDMX path","duration":0.46219500000000835,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath upper-cases the country code so case-mismatched ISO inputs still resolve","status":"passed","title":"upper-cases the country code so case-mismatched ISO inputs still resolve","duration":0.4054790000000139,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weoSdmxPath"],"fullName":"weoSdmxPath URL-encodes both the indicator and country segments","status":"passed","title":"URL-encodes both the indicator and country segments","duration":0.46527100000002974,"failureMessages":[],"location":{"line":74,"column":3},"meta":{},"tags":[]}],"startTime":1787953914385,"endTime":1787953914393.4653,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/indicators/weo.test.ts"},{"assertionResults":[{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues returns [] when the indicator node is absent","status":"passed","title":"returns [] when the indicator node is absent","duration":4.361456000000032,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues returns [] when the country node is absent","status":"passed","title":"returns [] when the country node is absent","duration":0.5310840000000212,"failureMessages":[],"location":{"line":27,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues sorts descending by year","status":"passed","title":"sorts descending by year","duration":0.5959760000000074,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues stamps projection years with the supplied vintage","status":"passed","title":"stamps projection years with the supplied vintage","duration":0.7619060000000104,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues drops null / \"n/a\" / NaN values and non-numeric years","status":"passed","title":"drops null / \"n/a\" / NaN values and non-numeric years","duration":0.4846870000000081,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues tolerates empty or missing raw envelopes","status":"passed","title":"tolerates empty or missing raw envelopes","duration":0.5608700000000226,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperValues"],"fullName":"parseDatamapperValues tolerates partial Datamapper envelope nodes","status":"passed","title":"tolerates partial Datamapper envelope nodes","duration":0.4657930000000192,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators converts the indicators envelope into a Map keyed by code","status":"passed","title":"converts the indicators envelope into a Map keyed by code","duration":0.521837000000005,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators skips entries missing the dataset field (defensive against schema drift)","status":"passed","title":"skips entries missing the dataset field (defensive against schema drift)","duration":0.44312999999999647,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators returns an empty Map for null / undefined / missing-indicators envelopes","status":"passed","title":"returns an empty Map for null / undefined / missing-indicators envelopes","duration":0.5046949999999697,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["parseDatamapperIndicators"],"fullName":"parseDatamapperIndicators passes through optional lastUpdate when present, omits it otherwise","status":"passed","title":"passes through optional lastUpdate when present, omits it otherwise","duration":0.6519499999999994,"failureMessages":[],"location":{"line":123,"column":3},"meta":{},"tags":[]}],"startTime":1787953895503,"endTime":1787953895512.6519,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/parsers/datamapper-envelope.test.ts"},{"assertionResults":[{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator parses the Datamapper envelope and returns descending years","status":"passed","title":"parses the Datamapper envelope and returns descending years","duration":6.8571790000000306,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator flags future years as projections and stamps the vintage","status":"passed","title":"flags future years as projections and stamps the vintage","duration":1.4260300000000257,"failureMessages":[],"location":{"line":61,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator returns an empty array when the response has no matching indicator","status":"passed","title":"returns an empty array when the response has no matching indicator","duration":1.3692440000000374,"failureMessages":[],"location":{"line":92,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator drops non-finite / null values defensively","status":"passed","title":"drops non-finite / null values defensively","duration":0.8031239999999684,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator truncates to the requested year count","status":"passed","title":"truncates to the requested year count","duration":0.8601100000000201,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator rejects non-positive or non-integer year counts","status":"passed","title":"rejects non-positive or non-integer year counts","duration":2.25645499999996,"failureMessages":[],"location":{"line":138,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator normalises ISO-3 input to uppercase before building the URL","status":"passed","title":"normalises ISO-3 input to uppercase before building the URL","duration":0.7198880000000258,"failureMessages":[],"location":{"line":144,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator sends an explicit User-Agent for IMF Datamapper compatibility","status":"passed","title":"sends an explicit User-Agent for IMF Datamapper compatibility","duration":0.7437930000000392,"failureMessages":[],"location":{"line":157,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient — Datamapper transport","getWeoIndicator"],"fullName":"ImfClient — Datamapper transport getWeoIndicator does NOT send Ocp-Apim-Subscription-Key on Datamapper requests (case-insensitive check)","status":"passed","title":"does NOT send Ocp-Apim-Subscription-Key on Datamapper requests (case-insensitive check)","duration":1.131988999999976,"failureMessages":[],"location":{"line":177,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicator → SDMX-only diagnostic"],"fullName":"ImfClient.getWeoIndicator → SDMX-only diagnostic throws ImfWeoSdmxOnlyError when Datamapper returns 0 points for a known SDMX-only code","status":"passed","title":"throws ImfWeoSdmxOnlyError when Datamapper returns 0 points for a known SDMX-only code","duration":1.0360200000000077,"failureMessages":[],"location":{"line":197,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient.getWeoIndicator → SDMX-only diagnostic"],"fullName":"ImfClient.getWeoIndicator → SDMX-only diagnostic returns [] (does NOT throw) for non-listed codes when the Datamapper envelope is genuinely empty","status":"passed","title":"returns [] (does NOT throw) for non-listed codes when the Datamapper envelope is genuinely empty","duration":0.8736250000000041,"failureMessages":[],"location":{"line":203,"column":3},"meta":{},"tags":[]}],"startTime":1787953838196,"endTime":1787953838214.8735,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/datamapper.test.ts"},{"assertionResults":[{"ancestorTitles":["RETRY_AFTER_CAP_MS"],"fullName":"RETRY_AFTER_CAP_MS is exactly 30_000 ms (30 s)","status":"passed","title":"is exactly 30_000 ms (30 s)","duration":3.5394979999999805,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay applies exponential back-off: 1s / 2s / 4s","status":"passed","title":"applies exponential back-off: 1s / 2s / 4s","duration":0.5975290000000086,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay honours a positive Retry-After header (delta-seconds)","status":"passed","title":"honours a positive Retry-After header (delta-seconds)","duration":0.40156200000001263,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay caps Retry-After at 30 s to avoid pathological sleeps","status":"passed","title":"caps Retry-After at 30 s to avoid pathological sleeps","duration":0.36419200000000274,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay ignores invalid / non-positive Retry-After and falls back to exponential","status":"passed","title":"ignores invalid / non-positive Retry-After and falls back to exponential","duration":0.44747800000004645,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["calculateRetryDelay"],"fullName":"calculateRetryDelay clamps negative attempt numbers to attempt 0","status":"passed","title":"clamps negative attempt numbers to attempt 0","duration":0.46672399999999925,"failureMessages":[],"location":{"line":52,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour retries on 429 with back-off","status":"passed","title":"retries on 429 with back-off","duration":1004.1919700000001,"failureMessages":[],"location":{"line":71,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour retries on 5xx and gives up after maxRetries","status":"passed","title":"retries on 5xx and gives up after maxRetries","duration":1003.4863600000001,"failureMessages":[],"location":{"line":87,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry non-transient 4xx responses","status":"passed","title":"does not retry non-transient 4xx responses","duration":1.3253609999997025,"failureMessages":[],"location":{"line":92,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry JSON parse errors from successful responses","status":"passed","title":"does not retry JSON parse errors from successful responses","duration":0.9842530000000806,"failureMessages":[],"location":{"line":100,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["ImfClient retry behaviour"],"fullName":"ImfClient retry behaviour does not retry non-network TypeError programmer errors","status":"passed","title":"does not retry non-network TypeError programmer errors","duration":1.0113340000002609,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]}],"startTime":1787953897303,"endTime":1787953899320.0112,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/retry.test.ts"},{"assertionResults":[{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch prepends the SDMX base URL when path is missing the leading slash","status":"passed","title":"prepends the SDMX base URL when path is missing the leading slash","duration":5.245101999999974,"failureMessages":[],"location":{"line":31,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch sends Ocp-Apim-Subscription-Key header when configured via constructor option","status":"passed","title":"sends Ocp-Apim-Subscription-Key header when configured via constructor option","duration":0.9032310000000052,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch falls back to IMF_SDMX_SUBSCRIPTION_KEY env var when constructor option omitted","status":"passed","title":"falls back to IMF_SDMX_SUBSCRIPTION_KEY env var when constructor option omitted","duration":0.6800329999999803,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch omits Ocp-Apim-Subscription-Key when no key is configured","status":"passed","title":"omits Ocp-Apim-Subscription-Key when no key is configured","duration":0.663252,"failureMessages":[],"location":{"line":81,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch does NOT send the SDMX subscription key on Datamapper (WEO) calls","status":"passed","title":"does NOT send the SDMX subscription key on Datamapper (WEO) calls","duration":1.3095519999999965,"failureMessages":[],"location":{"line":101,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces a \"subscription key missing or invalid\" diagnostic on SDMX 401","status":"passed","title":"surfaces a \"subscription key missing or invalid\" diagnostic on SDMX 401","duration":2.4144110000000296,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces the auth-failure diagnostic on SDMX 403","status":"passed","title":"surfaces the auth-failure diagnostic on SDMX 403","duration":0.7203890000000115,"failureMessages":[],"location":{"line":133,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch surfaces the auth-failure diagnostic on SDMX 404 when no subscription key was sent (APIM mask)","status":"passed","title":"surfaces the auth-failure diagnostic on SDMX 404 when no subscription key was sent (APIM mask)","duration":0.697435999999982,"failureMessages":[],"location":{"line":147,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["sdmxFetch"],"fullName":"sdmxFetch does NOT mask a real 404 as auth-failure when a subscription key WAS sent","status":"passed","title":"does NOT mask a real 404 as auth-failure when a subscription key WAS sent","duration":1.1443029999999794,"failureMessages":[],"location":{"line":170,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) rewrites comma-form into /data/dataflow/.../ slash-form for sdmx/3.0","status":"passed","title":"rewrites comma-form into /data/dataflow/.../ slash-form for sdmx/3.0","duration":0.40620100000001,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) preserves the query string when rewriting","status":"passed","title":"preserves the query string when rewriting","duration":0.3674679999999739,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) handles missing leading slash on input","status":"passed","title":"handles missing leading slash on input","duration":0.3311899999999923,"failureMessages":[],"location":{"line":207,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) handles dataflow ref without a key suffix (structure-only query)","status":"passed","title":"handles dataflow ref without a key suffix (structure-only query)","duration":0.34366399999998976,"failureMessages":[],"location":{"line":213,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) does NOT rewrite when base URL is not the sdmx/3.0 surface (defence-in-depth)","status":"passed","title":"does NOT rewrite when base URL is not the sdmx/3.0 surface (defence-in-depth)","duration":0.40086000000002286,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) does NOT double-rewrite an already slash-form path","status":"passed","title":"does NOT double-rewrite an already slash-form path","duration":0.34027699999995775,"failureMessages":[],"location":{"line":228,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite)"],"fullName":"normalizeSdmxPathForBase (SDMX 3.0 dataflow rewrite) passes through non-data paths unchanged (e.g. /structure, /dataflow)","status":"passed","title":"passes through non-data paths unchanged (e.g. /structure, /dataflow)","duration":0.3651439999999866,"failureMessages":[],"location":{"line":234,"column":3},"meta":{},"tags":[]}],"startTime":1787953827355,"endTime":1787953827371.3652,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf/transport/sdmx.test.ts"},{"assertionResults":[{"ancestorTitles":["compare subcommand"],"fullName":"compare subcommand exports runCompare as a function","status":"passed","title":"exports runCompare as a function","duration":3.6217909999999733,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]}],"startTime":1787953941589,"endTime":1787953941592.6218,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/compare.test.ts"},{"assertionResults":[{"ancestorTitles":["list-indicators subcommand"],"fullName":"list-indicators subcommand exports runListIndicators as a function","status":"passed","title":"exports runListIndicators as a function","duration":3.8603580000000193,"failureMessages":[],"location":{"line":15,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["list-indicators subcommand"],"fullName":"list-indicators subcommand exports runListDatamapperIndicators as a function","status":"passed","title":"exports runListDatamapperIndicators as a function","duration":0.5531860000000393,"failureMessages":[],"location":{"line":19,"column":3},"meta":{},"tags":[]}],"startTime":1787953940702,"endTime":1787953940706.5532,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/list-indicators.test.ts"},{"assertionResults":[{"ancestorTitles":["sdmx subcommand"],"fullName":"sdmx subcommand exports runSdmx as a function","status":"passed","title":"exports runSdmx as a function","duration":3.5608179999999834,"failureMessages":[],"location":{"line":12,"column":3},"meta":{},"tags":[]}],"startTime":1787953942023,"endTime":1787953942026.5608,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/sdmx.test.ts"},{"assertionResults":[{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget DEFAULT_WEO_VINTAGE is pinned to WEO-2026-04 (renderer + provenance reads this label)","status":"passed","title":"DEFAULT_WEO_VINTAGE is pinned to WEO-2026-04 (renderer + provenance reads this label)","duration":3.6802020000000084,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget WEO_FETCH_MAX_ATTEMPTS is a positive integer","status":"passed","title":"WEO_FETCH_MAX_ATTEMPTS is a positive integer","duration":0.6718979999999988,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["weo subcommand — vintage + retry budget"],"fullName":"weo subcommand — vintage + retry budget runWeo is exported as a function","status":"passed","title":"runWeo is exported as a function","duration":0.3963820000000169,"failureMessages":[],"location":{"line":30,"column":3},"meta":{},"tags":[]}],"startTime":1787953939820,"endTime":1787953939825.3965,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/imf-fetch/subcommands/weo.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should use MCP_GATEWAY_API_KEY env var as auth token when MCP_AUTH_TOKEN is not set","status":"passed","title":"should use MCP_GATEWAY_API_KEY env var as auth token when MCP_AUTH_TOKEN is not set","duration":33.266028000000006,"failureMessages":[],"location":{"line":61,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should read gateway API key from MCP config file when env vars are unset","status":"passed","title":"should read gateway API key from MCP config file when env vars are unset","duration":6.445970000000045,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file has malformed JSON","status":"passed","title":"should return empty auth token when config file has malformed JSON","duration":6.622660999999994,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file is missing gateway field and mcpServers has no riksdag-regering","status":"passed","title":"should return empty auth token when config file is missing gateway field and mcpServers has no riksdag-regering","duration":8.400188999999955,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should read auth from mcpServers riksdag-regering headers when gateway.apiKey is absent","status":"passed","title":"should read auth from mcpServers riksdag-regering headers when gateway.apiKey is absent","duration":7.482710999999995,"failureMessages":[],"location":{"line":97,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should prefer gateway.apiKey over mcpServers when both are present","status":"passed","title":"should prefer gateway.apiKey over mcpServers when both are present","duration":7.953331999999989,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should return empty auth token when config file does not exist","status":"passed","title":"should return empty auth token when config file does not exist","duration":6.497435999999993,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should respect GH_AW_MCP_CONFIG environment variable for config path","status":"passed","title":"should respect GH_AW_MCP_CONFIG environment variable for config path","duration":7.30258299999997,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should strip legacy \"Bearer \" prefix from MCP_AUTH_TOKEN env var","status":"passed","title":"should strip legacy \"Bearer \" prefix from MCP_AUTH_TOKEN env var","duration":7.010897,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — auth token resolution"],"fullName":"MCPClient — auth token resolution should expose hasMcpGatewayApiKey() without leaking the token value","status":"passed","title":"should expose hasMcpGatewayApiKey() without leaking the token value","duration":1.0133070000000544,"failureMessages":[],"location":{"line":151,"column":3},"meta":{},"tags":[]}],"startTime":1787953857326,"endTime":1787953857418.0134,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/auth.test.ts"},{"assertionResults":[{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should expose DEFAULT_MAX_RETRIES = 3","status":"passed","title":"should expose DEFAULT_MAX_RETRIES = 3","duration":6.862570000000005,"failureMessages":[],"location":{"line":23,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should expose RETRY_DELAY = 2000 ms","status":"passed","title":"should expose RETRY_DELAY = 2000 ms","duration":1.477076000000011,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults should resolve a non-empty DEFAULT_MCP_SERVER_URL","status":"passed","title":"should resolve a non-empty DEFAULT_MCP_SERVER_URL","duration":1.310004000000049,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should default to 30000 ms when MCP_CLIENT_TIMEOUT_MS is unset","status":"passed","title":"getDefaultTimeout() should default to 30000 ms when MCP_CLIENT_TIMEOUT_MS is unset","duration":1.0238170000000082,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should honour numeric MCP_CLIENT_TIMEOUT_MS","status":"passed","title":"getDefaultTimeout() should honour numeric MCP_CLIENT_TIMEOUT_MS","duration":1.002597000000037,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["config/defaults"],"fullName":"config/defaults getDefaultTimeout() should fall back to 30000 ms on invalid MCP_CLIENT_TIMEOUT_MS","status":"passed","title":"getDefaultTimeout() should fall back to 30000 ms on invalid MCP_CLIENT_TIMEOUT_MS","duration":1.084681000000046,"failureMessages":[],"location":{"line":53,"column":3},"meta":{},"tags":[]}],"startTime":1787953922955,"endTime":1787953922968.0847,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/defaults.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should use MCP_SERVER_URL env var when explicitly set","status":"passed","title":"should use MCP_SERVER_URL env var when explicitly set","duration":31.23777899999999,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when MCP_GATEWAY_API_KEY is set and MCP_SERVER_URL is absent","status":"passed","title":"should auto-route to gateway URL when MCP_GATEWAY_API_KEY is set and MCP_SERVER_URL is absent","duration":6.492155999999966,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should honour MCP_GATEWAY_PORT env var when present","status":"passed","title":"should honour MCP_GATEWAY_PORT env var when present","duration":6.909756999999956,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when mcp-config.json has gateway.apiKey (AWF sandbox)","status":"passed","title":"should auto-route to gateway URL when mcp-config.json has gateway.apiKey (AWF sandbox)","duration":7.990421000000026,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should auto-route to gateway URL when mcp-config.json has mcpServers riksdag-regering headers Authorization","status":"passed","title":"should auto-route to gateway URL when mcp-config.json has mcpServers riksdag-regering headers Authorization","duration":7.398672999999974,"failureMessages":[],"location":{"line":108,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should pick up gateway.port from mcp-config.json (gh-aw v0.69+ uses 8080)","status":"passed","title":"should pick up gateway.port from mcp-config.json (gh-aw v0.69+ uses 8080)","duration":7.53833400000002,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient — default server URL resolution (AWF gateway auto-detect)"],"fullName":"MCPClient — default server URL resolution (AWF gateway auto-detect) should fall back to direct onrender URL when no gateway indicators are present","status":"passed","title":"should fall back to direct onrender URL when no gateway indicators are present","duration":6.404742999999996,"failureMessages":[],"location":{"line":134,"column":3},"meta":{},"tags":[]}],"startTime":1787953890393,"endTime":1787953890467.4048,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/config/gateway-resolver.test.ts"},{"assertionResults":[{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed should expose a frozen pattern list with the documented signatures","status":"passed","title":"should expose a frozen pattern list with the documented signatures","duration":4.112409999999954,"failureMessages":[],"location":{"line":21,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: document not indexed","status":"passed","title":"classifies known signal as not_indexed: document not indexed","duration":0.7681880000000092,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: No document for that id","status":"passed","title":"classifies known signal as not_indexed: No document for that id","duration":0.4659819999999968,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: Document not found in this riksmöte","status":"passed","title":"classifies known signal as not_indexed: Document not found in this riksmöte","duration":0.35066600000004655,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed classifies known signal as not_indexed: dok_id not found: H101FiU01","status":"passed","title":"classifies known signal as not_indexed: dok_id not found: H101FiU01","duration":0.4142250000000445,"failureMessages":[],"location":{"line":35,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed does not classify bare \"404\"/\"not found\" as not_indexed","status":"passed","title":"does not classify bare \"404\"/\"not found\" as not_indexed","duration":0.47043100000001914,"failureMessages":[],"location":{"line":39,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed suppresses not_indexed when message is a transport error","status":"passed","title":"suppresses not_indexed when message is a transport error","duration":0.6749740000000202,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed uses dok_id-aware fallback when the dok_id appears in the message","status":"passed","title":"uses dok_id-aware fallback when the dok_id appears in the message","duration":0.3972639999999501,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed does not use dok_id fallback when message is a transport error","status":"passed","title":"does not use dok_id fallback when message is a transport error","duration":0.5252839999999992,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/not-indexed"],"fullName":"error-classification/not-indexed returns false for empty / undefined messages","status":"passed","title":"returns false for empty / undefined messages","duration":0.4592999999999847,"failureMessages":[],"location":{"line":62,"column":3},"meta":{},"tags":[]}],"startTime":1787953922048,"endTime":1787953922056.5254,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/error-classification/not-indexed.test.ts"},{"assertionResults":[{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: MCP server error: 500","status":"passed","title":"matches transport signature: MCP server error: 500","duration":3.7337009999999964,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: MCP transport error","status":"passed","title":"matches transport signature: MCP transport error","duration":0.46216500000002725,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: Server error","status":"passed","title":"matches transport signature: Server error","duration":0.39471900000000915,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: /endpoint not reachable","status":"passed","title":"matches transport signature: /endpoint not reachable","duration":0.30724600000002056,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: ECONNREFUSED 127.0.0.1:8080","status":"passed","title":"matches transport signature: ECONNREFUSED 127.0.0.1:8080","duration":0.29605400000002646,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: ETIMEDOUT","status":"passed","title":"matches transport signature: ETIMEDOUT","duration":0.45442100000002483,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: fetch failed","status":"passed","title":"matches transport signature: fetch failed","duration":0.3072050000000104,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: network unreachable","status":"passed","title":"matches transport signature: network unreachable","duration":0.26374400000003106,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: gateway timeout","status":"passed","title":"matches transport signature: gateway timeout","duration":0.5006870000000276,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 500","status":"passed","title":"matches transport signature: HTTP 500","duration":0.2800039999999626,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 502","status":"passed","title":"matches transport signature: HTTP 502","duration":0.30770599999999604,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches transport signature: HTTP 503","status":"passed","title":"matches transport signature: HTTP 503","duration":0.3192579999999907,"failureMessages":[],"location":{"line":28,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: document not indexed","status":"passed","title":"does not match application-level signature: document not indexed","duration":0.2944209999999998,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: no document for that id","status":"passed","title":"does not match application-level signature: no document for that id","duration":0.2629929999999945,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: dok_id not found: H101FiU01","status":"passed","title":"does not match application-level signature: dok_id not found: H101FiU01","duration":0.30784599999998363,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: Method not found","status":"passed","title":"does not match application-level signature: Method not found","duration":0.35244999999997617,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE does not match application-level signature: Invalid tool name","status":"passed","title":"does not match application-level signature: Invalid tool name","duration":0.26020699999997987,"failureMessages":[],"location":{"line":38,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE is case-insensitive","status":"passed","title":"is case-insensitive","duration":0.385550999999964,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["error-classification/transport — TRANSPORT_ERROR_RE"],"fullName":"error-classification/transport — TRANSPORT_ERROR_RE matches HTTP 500/502/503 as word boundary, not 5001 / 5023","status":"passed","title":"matches HTTP 500/502/503 as word boundary, not 5001 / 5023","duration":0.4242950000000292,"failureMessages":[],"location":{"line":47,"column":3},"meta":{},"tags":[]}],"startTime":1787953935015,"endTime":1787953935025.4243,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/error-classification/transport.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should fetch calendar events with date range","status":"passed","title":"should fetch calendar events with date range","duration":5.967242999999996,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should pass optional org and akt parameters","status":"passed","title":"should pass optional org and akt parameters","duration":1.554079999999999,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should return empty array when response has no events key","status":"passed","title":"should return empty array when response has no events key","duration":0.7157599999999888,"failureMessages":[],"location":{"line":70,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should throw when the server returns the degraded-kalender sentinel","status":"passed","title":"should throw when the server returns the degraded-kalender sentinel","duration":2.476456999999982,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should throw when the server returns a rawHtml-only sentinel (no error field)","status":"passed","title":"should throw when the server returns a rawHtml-only sentinel (no error field)","duration":1.0033990000000017,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/calendar — fetchCalendarEvents"],"fullName":"methods/calendar — fetchCalendarEvents should include the upstream error message in the thrown error","status":"passed","title":"should include the upstream error message in the thrown error","duration":0.868186000000037,"failureMessages":[],"location":{"line":136,"column":3},"meta":{},"tags":[]}],"startTime":1787953895049,"endTime":1787953895061.8682,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/calendar.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface searchDocuments routes to search_dokument","status":"passed","title":"searchDocuments routes to search_dokument","duration":5.168538000000012,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface fetchGovernmentDocuments routes to search_regering","status":"passed","title":"fetchGovernmentDocuments routes to search_regering","duration":0.7355069999999841,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface searchDocuments returns empty array when result has no documents key","status":"passed","title":"searchDocuments returns empty array when result has no documents key","duration":1.1430310000000077,"failureMessages":[],"location":{"line":66,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/documents — tool-name surface"],"fullName":"methods/documents — tool-name surface exposes fetchDocumentDetails / fetchDocumentDetailsWithCoverage on the public surface","status":"passed","title":"exposes fetchDocumentDetails / fetchDocumentDetailsWithCoverage on the public surface","duration":0.4562750000000051,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]}],"startTime":1787953918955,"endTime":1787953918963.4563,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/documents.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/members — fetchMPs"],"fullName":"methods/members — fetchMPs routes to search_ledamoter tool","status":"passed","title":"routes to search_ledamoter tool","duration":5.573677000000032,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/members — fetchMPs"],"fullName":"methods/members — fetchMPs passes parti / valkrets / status filters when provided","status":"passed","title":"passes parti / valkrets / status filters when provided","duration":1.4286649999999668,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953928781,"endTime":1787953928788.4287,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/members.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should fetch committee reports with limit","status":"passed","title":"should fetch committee reports with limit","duration":5.714129999999955,"failureMessages":[],"location":{"line":40,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should pass optional rm and organ parameters","status":"passed","title":"should pass optional rm and organ parameters","duration":1.6414429999999811,"failureMessages":[],"location":{"line":56,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchCommitteeReports"],"fullName":"methods/reports — fetchCommitteeReports should return empty array when response has no reports key","status":"passed","title":"should return empty array when response has no reports key","duration":0.6624510000000328,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should fetch propositions with default limit","status":"passed","title":"should fetch propositions with default limit","duration":0.9808869999999956,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should pass optional rm parameter","status":"passed","title":"should pass optional rm parameter","duration":0.7922229999999786,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should call correct tool name (get_propositioner)","status":"passed","title":"should call correct tool name (get_propositioner)","duration":0.6874470000000201,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/reports — fetchPropositions"],"fullName":"methods/reports — fetchPropositions should return empty array when response has no propositions key","status":"passed","title":"should return empty array when response has no propositions key","duration":0.5409530000000018,"failureMessages":[],"location":{"line":144,"column":3},"meta":{},"tags":[]}],"startTime":1787953893689,"endTime":1787953893700.541,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/reports.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/speeches — searchSpeeches"],"fullName":"methods/speeches — searchSpeeches routes to search_anforanden tool","status":"passed","title":"routes to search_anforanden tool","duration":5.2085630000000265,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/speeches — searchSpeeches"],"fullName":"methods/speeches — searchSpeeches returns empty array when result has no speeches key","status":"passed","title":"returns empty array when result has no speeches key","duration":1.5353450000000066,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]}],"startTime":1787953933276,"endTime":1787953933282.5354,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/speeches.test.ts"},{"assertionResults":[{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingRecords routes to search_voteringar","status":"passed","title":"fetchVotingRecords routes to search_voteringar","duration":5.675726999999995,"failureMessages":[],"location":{"line":33,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingGroup routes to get_voting_group","status":"passed","title":"fetchVotingGroup routes to get_voting_group","duration":0.9652169999999956,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["methods/votes"],"fullName":"methods/votes fetchVotingRecords returns empty array when result is empty","status":"passed","title":"fetchVotingRecords returns empty array when result is empty","duration":1.362922000000026,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]}],"startTime":1787953922514,"endTime":1787953922522.363,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/methods/votes.test.ts"},{"assertionResults":[{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should make successful HTTP request with JSON-RPC 2.0","status":"passed","title":"should make successful HTTP request with JSON-RPC 2.0","duration":5.979917,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should send correct JSON-RPC 2.0 request format","status":"passed","title":"should send correct JSON-RPC 2.0 request format","duration":1.3657670000000053,"failureMessages":[],"location":{"line":59,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should include custom headers from config in requests","status":"passed","title":"should include custom headers from config in requests","duration":0.7727869999999939,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not override runtime headers with custom headers","status":"passed","title":"should not override runtime headers with custom headers","duration":0.9869580000000155,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should handle JSON-RPC error responses","status":"passed","title":"should handle JSON-RPC error responses","duration":2.5552040000000034,"failureMessages":[],"location":{"line":117,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on non-ok HTTP response","status":"passed","title":"should throw on non-ok HTTP response","duration":0.7908610000000067,"failureMessages":[],"location":{"line":127,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on 404 response","status":"passed","title":"should throw on 404 response","duration":0.8740369999999871,"failureMessages":[],"location":{"line":139,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not retry on non-network errors","status":"passed","title":"should not retry on non-network errors","duration":0.6778090000000248,"failureMessages":[],"location":{"line":146,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should track statistics","status":"passed","title":"should track statistics","duration":0.8481879999999933,"failureMessages":[],"location":{"line":154,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should use default empty params when none provided","status":"passed","title":"should use default empty params when none provided","duration":0.8119499999999675,"failureMessages":[],"location":{"line":169,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should not add prefix when using direct server URL","status":"passed","title":"should not add prefix when using direct server URL","duration":0.5337499999999977,"failureMessages":[],"location":{"line":181,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should use bare tool names when using MCP gateway URL","status":"passed","title":"should use bare tool names when using MCP gateway URL","duration":0.6029690000000301,"failureMessages":[],"location":{"line":192,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — JSON-RPC dispatcher"],"fullName":"MCPClient.request — JSON-RPC dispatcher should throw on Internal error from gateway without retry","status":"passed","title":"should throw on Internal error from gateway without retry","duration":0.893481999999949,"failureMessages":[],"location":{"line":204,"column":3},"meta":{},"tags":[]}],"startTime":1787953836785,"endTime":1787953836802.8936,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/jsonrpc.test.ts"},{"assertionResults":[{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay returns RETRY_DELAY for retryCount=0 (first retry)","status":"passed","title":"returns RETRY_DELAY for retryCount=0 (first retry)","duration":3.898499999999956,"failureMessages":[],"location":{"line":27,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay doubles per retry (2^N exponential backoff)","status":"passed","title":"doubles per retry (2^N exponential backoff)","duration":0.5693360000000212,"failureMessages":[],"location":{"line":31,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","calculateRetryDelay"],"fullName":"transport/retry — pure helpers calculateRetryDelay clamps negative retryCount to 0 (no underflow)","status":"passed","title":"clamps negative retryCount to 0 (no underflow)","duration":0.5306039999999825,"failureMessages":[],"location":{"line":37,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for AbortError (timeout-induced)","status":"passed","title":"returns true for AbortError (timeout-induced)","duration":0.4246350000000234,"failureMessages":[],"location":{"line":44,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Network error","status":"passed","title":"returns true for transient signature: Network error","duration":0.43985399999996844,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: ECONNREFUSED","status":"passed","title":"returns true for transient signature: ECONNREFUSED","duration":0.46401800000001003,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Connection closed","status":"passed","title":"returns true for transient signature: Connection closed","duration":0.39987899999999854,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: Too Many Requests","status":"passed","title":"returns true for transient signature: Too Many Requests","duration":0.32899600000001783,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns true for transient signature: fetch failed: network issue","status":"passed","title":"returns true for transient signature: fetch failed: network issue","duration":0.3890089999999873,"failureMessages":[],"location":{"line":56,"column":7},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError returns false for HTTP server errors (non-network)","status":"passed","title":"returns false for HTTP server errors (non-network)","duration":0.509003000000007,"failureMessages":[],"location":{"line":60,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["transport/retry — pure helpers","isRetryableNetworkError"],"fullName":"transport/retry — pure helpers isRetryableNetworkError handles empty / undefined message safely","status":"passed","title":"handles empty / undefined message safely","duration":0.3997279999999819,"failureMessages":[],"location":{"line":65,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should retry on network error","status":"passed","title":"should retry on network error","duration":2.7843030000000226,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should retry on ECONNREFUSED error","status":"passed","title":"should retry on ECONNREFUSED error","duration":0.8871310000000108,"failureMessages":[],"location":{"line":104,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["MCPClient.request — end-to-end retry loop"],"fullName":"MCPClient.request — end-to-end retry loop should fail after max retries","status":"passed","title":"should fail after max retries","duration":2.723569999999995,"failureMessages":[],"location":{"line":119,"column":3},"meta":{},"tags":[]}],"startTime":1787953896417,"endTime":1787953896432.7236,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/retry.test.ts"},{"assertionResults":[{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should expose EXTERNAL_URL_FETCH_TIMEOUT_MS = 15000 ms","status":"passed","title":"should expose EXTERNAL_URL_FETCH_TIMEOUT_MS = 15000 ms","duration":3.872370999999987,"failureMessages":[],"location":{"line":38,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return body text on 2xx response","status":"passed","title":"should return body text on 2xx response","duration":0.9122689999999807,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should pass Accept header on the outgoing request","status":"passed","title":"should pass Accept header on the outgoing request","duration":1.7587629999999876,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return null on non-2xx response and log a warning","status":"passed","title":"should return null on non-2xx response and log a warning","duration":2.380708000000027,"failureMessages":[],"location":{"line":60,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should return null on network error and log a warning","status":"passed","title":"should return null on network error and log a warning","duration":0.87717200000003,"failureMessages":[],"location":{"line":69,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["transport/timeout"],"fullName":"transport/timeout should honour the timeoutMs override","status":"passed","title":"should honour the timeoutMs override","duration":6.230586000000017,"failureMessages":[],"location":{"line":76,"column":3},"meta":{},"tags":[]}],"startTime":1787953908188,"endTime":1787953908204.2305,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/mcp-client/transport/timeout.test.ts"},{"assertionResults":[{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets MAX_ENRICHMENT_PER_TYPE === 5 (verbatim)","status":"passed","title":"MAX_ENRICHMENT_PER_TYPE === 5 (verbatim)","duration":3.9841600000000312,"failureMessages":[],"location":{"line":37,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets LONG_HORIZON_FULL_TEXT_FLOOR === 10 (verbatim)","status":"passed","title":"LONG_HORIZON_FULL_TEXT_FLOOR === 10 (verbatim)","duration":0.49435499999998456,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets floor is strictly greater than per-type cap (so long-horizon raises the budget)","status":"passed","title":"floor is strictly greater than per-type cap (so long-horizon raises the budget)","duration":0.5419449999999983,"failureMessages":[],"location":{"line":45,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["full-text enrichment budgets"],"fullName":"full-text enrichment budgets every re-export site exposes the same constant value","status":"passed","title":"every re-export site exposes the same constant value","duration":0.6273750000000291,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]}],"startTime":1787953926558,"endTime":1787953926563.6274,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/enrichment/full-text-selection.test.ts"},{"assertionResults":[{"ancestorTitles":["persistDownloadedData — collision avoidance"],"fullName":"persistDownloadedData — collision avoidance should suffix duplicate doc IDs within a batch","status":"passed","title":"should suffix duplicate doc IDs within a batch","duration":6.165906000000007,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]}],"startTime":1787953927888,"endTime":1787953927894.166,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/collision-avoidance.test.ts"},{"assertionResults":[{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should write data files without _metadata injection","status":"passed","title":"should write data files without _metadata injection","duration":5.894926999999996,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should write sidecar .meta.json alongside data file","status":"passed","title":"should write sidecar .meta.json alongside data file","duration":1.4810640000000035,"failureMessages":[],"location":{"line":55,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should handle all document types","status":"passed","title":"should handle all document types","duration":2.291080000000022,"failureMessages":[],"location":{"line":71,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should create date-stamped vote directories","status":"passed","title":"should create date-stamped vote directories","duration":0.9375550000000317,"failureMessages":[],"location":{"line":89,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should skip null documents","status":"passed","title":"should skip null documents","duration":0.8772619999999733,"failureMessages":[],"location":{"line":100,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should handle empty data gracefully","status":"passed","title":"should handle empty data gracefully","duration":0.6538040000000365,"failureMessages":[],"location":{"line":110,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should allow custom mcpToolMap overrides","status":"passed","title":"should allow custom mcpToolMap overrides","duration":0.9016679999999724,"failureMessages":[],"location":{"line":116,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistDownloadedData"],"fullName":"data-persistence — documents persistDownloadedData should return correct dataRoot in result","status":"passed","title":"should return correct dataRoot in result","duration":0.45475099999998747,"failureMessages":[],"location":{"line":129,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should persist events to date-stamped directories","status":"passed","title":"should persist events to date-stamped directories","duration":1.2265769999999634,"failureMessages":[],"location":{"line":136,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should use \"undated\" for events without valid date","status":"passed","title":"should use \"undated\" for events without valid date","duration":0.7201580000000263,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should skip null events","status":"passed","title":"should skip null events","duration":0.7105910000000222,"failureMessages":[],"location":{"line":152,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should write metadata with correct tool name","status":"passed","title":"should write metadata with correct tool name","duration":0.7398349999999709,"failureMessages":[],"location":{"line":159,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistEvents"],"fullName":"data-persistence — documents persistEvents should handle \"from\" field as date fallback","status":"passed","title":"should handle \"from\" field as date fallback","duration":0.774530000000027,"failureMessages":[],"location":{"line":170,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should persist MP profiles using intressent_id","status":"passed","title":"should persist MP profiles using intressent_id","duration":0.9272260000000188,"failureMessages":[],"location":{"line":180,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should skip null MP entries","status":"passed","title":"should skip null MP entries","duration":0.48722200000003113,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should fall back to resolveDocId when intressent_id missing","status":"passed","title":"should fall back to resolveDocId when intressent_id missing","duration":0.6809149999999704,"failureMessages":[],"location":{"line":197,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","persistMPs"],"fullName":"data-persistence — documents persistMPs should write metadata with correct tool name","status":"passed","title":"should write metadata with correct tool name","duration":0.6566090000000031,"failureMessages":[],"location":{"line":204,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["data-persistence — documents","getDataRoot"],"fullName":"data-persistence — documents getDataRoot should return path ending with analysis/data","status":"passed","title":"should return path ending with analysis/data","duration":0.7261090000000081,"failureMessages":[],"location":{"line":217,"column":5},"meta":{},"tags":[]}],"startTime":1787953837269,"endTime":1787953837290.726,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/documents.test.ts"},{"assertionResults":[{"ancestorTitles":["persistIMFData"],"fullName":"persistIMFData stores IMF data under imf/{indicator}/{country}.json with sidecar","status":"passed","title":"stores IMF data under imf/{indicator}/{country}.json with sidecar","duration":5.202682999999979,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistIMFData"],"fullName":"persistIMFData omits optional provenance fields when not supplied","status":"passed","title":"omits optional provenance fields when not supplied","duration":1.1440020000000004,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]}],"startTime":1787953929229,"endTime":1787953929235.144,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/imf.test.ts"},{"assertionResults":[{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should store generic MCP tool response in server/tool subdirs","status":"passed","title":"should store generic MCP tool response in server/tool subdirs","duration":5.482817000000011,"failureMessages":[],"location":{"line":36,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should use UUID-based fallback for empty id","status":"passed","title":"should use UUID-based fallback for empty id","duration":1.505899999999997,"failureMessages":[],"location":{"line":54,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should derive riksmote from call.params.rm when not explicitly provided","status":"passed","title":"should derive riksmote from call.params.rm when not explicitly provided","duration":0.8621449999999982,"failureMessages":[],"location":{"line":67,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","happy path"],"fullName":"persistMCPResponse happy path should use explicit riksmote param over call.params.rm","status":"passed","title":"should use explicit riksmote param over call.params.rm","duration":0.772927999999979,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should sanitize raw `../` in server and tool names","status":"passed","title":"should sanitize raw `../` in server and tool names","duration":1.0999590000000126,"failureMessages":[],"location":{"line":94,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should handle dots-only server names","status":"passed","title":"should handle dots-only server names","duration":0.8183520000000044,"failureMessages":[],"location":{"line":106,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should neutralise URL-encoded traversal (%2e%2e/) in server name","status":"passed","title":"should neutralise URL-encoded traversal (%2e%2e/) in server name","duration":1.0081279999999992,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should neutralise uppercase URL-encoded traversal (%2E%2E%2F) in tool name","status":"passed","title":"should neutralise uppercase URL-encoded traversal (%2E%2E%2F) in tool name","duration":0.8741770000000315,"failureMessages":[],"location":{"line":134,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should strip embedded NUL bytes (\\0) from server, tool and id","status":"passed","title":"should strip embedded NUL bytes (\\0) from server, tool and id","duration":1.1712029999999913,"failureMessages":[],"location":{"line":147,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should reject absolute path injection in tool name (unix)","status":"passed","title":"should reject absolute path injection in tool name (unix)","duration":0.7685690000000136,"failureMessages":[],"location":{"line":162,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should reject absolute path injection in tool name (windows-style)","status":"passed","title":"should reject absolute path injection in tool name (windows-style)","duration":0.8152270000000499,"failureMessages":[],"location":{"line":173,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["persistMCPResponse","path traversal prevention"],"fullName":"persistMCPResponse path traversal prevention should sanitize multi-level traversal (..\\..\\..)","status":"passed","title":"should sanitize multi-level traversal (..\\..\\..)","duration":0.7670259999999871,"failureMessages":[],"location":{"line":184,"column":5},"meta":{},"tags":[]}],"startTime":1787953848214,"endTime":1787953848230.767,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/mcp-response.test.ts"},{"assertionResults":[{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta strips in-memory MCP annotations from the raw `.json` file","status":"passed","title":"strips in-memory MCP annotations from the raw `.json` file","duration":5.117803000000038,"failureMessages":[],"location":{"line":49,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta writes provenance to a separate `.meta.json` sidecar","status":"passed","title":"writes provenance to a separate `.meta.json` sidecar","duration":1.0094899999999711,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta produces byte-identical `.json` output across repeated calls (parallel-workflow safety)","status":"passed","title":"produces byte-identical `.json` output across repeated calls (parallel-workflow safety)","duration":0.8665129999999976,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta does not mutate the input document (defensive copy)","status":"passed","title":"does not mutate the input document (defensive copy)","duration":0.6601359999999659,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta throws if baseFilename does not end with .json","status":"passed","title":"throws if baseFilename does not end with .json","duration":1.5057800000000157,"failureMessages":[],"location":{"line":114,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistence sidecar discipline — writeDocumentAndMeta"],"fullName":"persistence sidecar discipline — writeDocumentAndMeta creates the output directory if it does not exist","status":"passed","title":"creates the output directory if it does not exist","duration":0.8306349999999725,"failureMessages":[],"location":{"line":121,"column":3},"meta":{},"tags":[]}],"startTime":1787953892299,"endTime":1787953892308.8306,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/meta-sidecar.test.ts"},{"assertionResults":[{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should prefer dok_id when available","status":"passed","title":"should prefer dok_id when available","duration":3.9750829999999837,"failureMessages":[],"location":{"line":17,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should fall back to titel when dok_id is missing","status":"passed","title":"should fall back to titel when dok_id is missing","duration":0.5754870000000096,"failureMessages":[],"location":{"line":22,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should fall back through dokument_id, id, rel_dok_id, titel, title","status":"passed","title":"should fall back through dokument_id, id, rel_dok_id, titel, title","duration":0.5085820000000467,"failureMessages":[],"location":{"line":28,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should use index-based fallback when all fields empty","status":"passed","title":"should use index-based fallback when all fields empty","duration":0.4536099999999692,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should trim whitespace from identifiers","status":"passed","title":"should trim whitespace from identifiers","duration":0.3724280000000135,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["resolveDocId"],"fullName":"resolveDocId should skip empty string fields","status":"passed","title":"should skip empty string fields","duration":0.43667799999997214,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]}],"startTime":1787953932336,"endTime":1787953932342.4368,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/resolve-doc-id.test.ts"},{"assertionResults":[{"ancestorTitles":["persistRiksbankData"],"fullName":"persistRiksbankData should store Riksbank artifacts with sidecar","status":"passed","title":"should store Riksbank artifacts with sidecar","duration":5.242125999999985,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953938072,"endTime":1787953938077.2422,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/riksbank.test.ts"},{"assertionResults":[{"ancestorTitles":["persistSCBData"],"fullName":"persistSCBData should store SCB table data with sidecar","status":"passed","title":"should store SCB table data with sidecar","duration":5.432492000000025,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistSCBData"],"fullName":"persistSCBData should work without query parameter","status":"passed","title":"should work without query parameter","duration":1.1137259999999856,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]}],"startTime":1787953936742,"endTime":1787953936749.1138,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/scb.test.ts"},{"assertionResults":[{"ancestorTitles":["persistDownloadedData — sidecar invariant"],"fullName":"persistDownloadedData — sidecar invariant strips in-memory MCP coverage metadata so data files remain byte-identical","status":"passed","title":"strips in-memory MCP coverage metadata so data files remain byte-identical","duration":6.434578999999985,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistDownloadedData — sidecar invariant"],"fullName":"persistDownloadedData — sidecar invariant produces byte-identical data files for parallel writes (collision-free)","status":"passed","title":"produces byte-identical data files for parallel writes (collision-free)","duration":1.3760059999999612,"failureMessages":[],"location":{"line":79,"column":3},"meta":{},"tags":[]}],"startTime":1787953903509,"endTime":1787953903517.376,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/sidecar-invariant.test.ts"},{"assertionResults":[{"ancestorTitles":["persistStatskontoretData"],"fullName":"persistStatskontoretData should store Statskontoret data with dataset/artifact structure and sidecar","status":"passed","title":"should store Statskontoret data with dataset/artifact structure and sidecar","duration":5.26262399999996,"failureMessages":[],"location":{"line":26,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["persistStatskontoretData"],"fullName":"persistStatskontoretData should sanitize dataset and artifact names","status":"passed","title":"should sanitize dataset and artifact names","duration":1.2154260000000363,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]}],"startTime":1787953929676,"endTime":1787953929683.2153,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/statskontoret.test.ts"},{"assertionResults":[{"ancestorTitles":["persistWorldBankData"],"fullName":"persistWorldBankData should store data with indicator/country structure","status":"passed","title":"should store data with indicator/country structure","duration":5.277702000000033,"failureMessages":[],"location":{"line":25,"column":3},"meta":{},"tags":[]}],"startTime":1787953937632,"endTime":1787953937637.2776,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/parliamentary-data/persistence/world-bank.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBluf"],"fullName":"extractBluf extracts the prose paragraph following a `## BLUF` heading","status":"passed","title":"extracts the prose paragraph following a `## BLUF` heading","duration":4.0693899999999985,"failureMessages":[],"location":{"line":48,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf accepts a decorated BLUF heading (e.g. with an emoji prefix)","status":"passed","title":"accepts a decorated BLUF heading (e.g. with an emoji prefix)","duration":0.9120270000000232,"failureMessages":[],"location":{"line":63,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf returns null when no BLUF heading is present","status":"passed","title":"returns null when no BLUF heading is present","duration":0.4880939999999896,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf skips blockquote / table / list-only first paragraphs (returns null)","status":"passed","title":"skips blockquote / table / list-only first paragraphs (returns null)","duration":0.4543610000000058,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBluf"],"fullName":"extractBluf handles a BLUF block that runs to end-of-file (no trailing heading)","status":"passed","title":"handles a BLUF block that runs to end-of-file (no trailing heading)","duration":0.440936000000022,"failureMessages":[],"location":{"line":88,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf returns no violations when no BLUF heading is present","status":"passed","title":"returns no violations when no BLUF heading is present","duration":1.0765250000000037,"failureMessages":[],"location":{"line":99,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf returns no violations when BLUF is within bounds and carries an anchor","status":"passed","title":"returns no violations when BLUF is within bounds and carries an anchor","duration":1.1941959999999767,"failureMessages":[],"location":{"line":103,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags a BLUF that is too short with the `bluf-too-short` code","status":"passed","title":"flags a BLUF that is too short with the `bluf-too-short` code","duration":1.2135719999999992,"failureMessages":[],"location":{"line":112,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags a BLUF that exceeds the maximum prose length","status":"passed","title":"flags a BLUF that exceeds the maximum prose length","duration":0.6902120000000309,"failureMessages":[],"location":{"line":122,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBluf"],"fullName":"checkBluf flags missing evidence anchor when prose has no dok_id / URL / vote id","status":"passed","title":"flags missing evidence anchor when prose has no dok_id / URL / vote id","duration":0.4896370000000161,"failureMessages":[],"location":{"line":132,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity returns no violations for empty text","status":"passed","title":"returns no violations for empty text","duration":1.1097280000000183,"failureMessages":[],"location":{"line":148,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity flags prose with words but zero evidence anchors","status":"passed","title":"flags prose with words but zero evidence anchors","duration":0.9794540000000325,"failureMessages":[],"location":{"line":152,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity passes when density is within the default 200 words-per-anchor budget","status":"passed","title":"passes when density is within the default 200 words-per-anchor budget","duration":0.4327599999999734,"failureMessages":[],"location":{"line":161,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity flags density that exceeds the default 200 words-per-anchor threshold","status":"passed","title":"flags density that exceeds the default 200 words-per-anchor threshold","duration":0.6402779999999666,"failureMessages":[],"location":{"line":166,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity honours the per-article-type threshold from reference-quality-thresholds.json","status":"passed","title":"honours the per-article-type threshold from reference-quality-thresholds.json","duration":1.3751050000000191,"failureMessages":[],"location":{"line":174,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkCitationDensity"],"fullName":"checkCitationDensity falls back to the default threshold for unknown article types","status":"passed","title":"falls back to the default threshold for unknown article types","duration":0.6928670000000352,"failureMessages":[],"location":{"line":185,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance returns [] when no `retrieved_at:` lines are present","status":"passed","title":"returns [] when no `retrieved_at:` lines are present","duration":0.5374970000000303,"failureMessages":[],"location":{"line":198,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance returns [] when all provenance vintages are within 6 months","status":"passed","title":"returns [] when all provenance vintages are within 6 months","duration":0.8643280000000004,"failureMessages":[],"location":{"line":202,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance emits `stale-economic-provenance` when vintage exceeds 6 months without annotation","status":"passed","title":"emits `stale-economic-provenance` when vintage exceeds 6 months without annotation","duration":0.7343849999999748,"failureMessages":[],"location":{"line":208,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance does not flag stale vintage when an annotation comment is on the preceding line","status":"passed","title":"does not flag stale vintage when an annotation comment is on the preceding line","duration":0.45905900000002475,"failureMessages":[],"location":{"line":219,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkStaleProvenance"],"fullName":"checkStaleProvenance lists up to two stale vintages in the message sample","status":"passed","title":"lists up to two stale vintages in the message sample","duration":0.7874040000000377,"failureMessages":[],"location":{"line":224,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases"],"fullName":"checkBannedPhrases returns [] when no banned phrases are present","status":"passed","title":"returns [] when no banned phrases are present","duration":1.227749000000017,"failureMessages":[],"location":{"line":253,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases"],"fullName":"checkBannedPhrases emits `banned-phrase-detected` when at least one phrase appears in the text","status":"passed","title":"emits `banned-phrase-detected` when at least one phrase appears in the text","duration":1.0484329999999886,"failureMessages":[],"location":{"line":260,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) emits `missing-banned-phrase-list` when the canonical JSON cannot be found","status":"passed","title":"emits `missing-banned-phrase-list` when the canonical JSON cannot be found","duration":0.9930390000000102,"failureMessages":[],"location":{"line":301,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) treats a malformed JSON file as a missing list (returns null)","status":"passed","title":"treats a malformed JSON file as a missing list (returns null)","duration":0.9265950000000203,"failureMessages":[],"location":{"line":314,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) treats a JSON file without `allPhrases` as a missing list","status":"passed","title":"treats a JSON file without `allPhrases` as a missing list","duration":0.8390210000000025,"failureMessages":[],"location":{"line":326,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBannedPhrases (missing canonical file)"],"fullName":"checkBannedPhrases (missing canonical file) deduplicates entries (case-insensitive) and skips blanks / non-strings","status":"passed","title":"deduplicates entries (case-insensitive) and skips blanks / non-strings","duration":1.0503770000000259,"failureMessages":[],"location":{"line":338,"column":3},"meta":{},"tags":[]}],"startTime":1787953787360,"endTime":1787953787386.0503,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/article/rules.test.ts"},{"assertionResults":[{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses 2026-02-14-test-en.html → en","status":"passed","title":"parses 2026-02-14-test-en.html → en","duration":3.665734000000043,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses 2026-04-09-committee-de.html → de","status":"passed","title":"parses 2026-04-09-committee-de.html → de","duration":0.5561519999999973,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses anything-fr.html → fr","status":"passed","title":"parses anything-fr.html → fr","duration":0.4253770000000259,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses weekly-es.html → es","status":"passed","title":"parses weekly-es.html → es","duration":0.2817380000000185,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses rtl-ar.html → ar","status":"passed","title":"parses rtl-ar.html → ar","duration":0.4490610000000288,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses rtl-he.html → he","status":"passed","title":"parses rtl-he.html → he","duration":0.364612999999963,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-ja.html → ja","status":"passed","title":"parses cjk-ja.html → ja","duration":0.44487299999997276,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-ko.html → ko","status":"passed","title":"parses cjk-ko.html → ko","duration":0.2626319999999964,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses cjk-zh.html → zh","status":"passed","title":"parses cjk-zh.html → zh","duration":0.293309000000022,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-da.html → da","status":"passed","title":"parses nordic-da.html → da","duration":0.29927000000003545,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-no.html → no","status":"passed","title":"parses nordic-no.html → no","duration":0.49425500000000966,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses nordic-fi.html → fi","status":"passed","title":"parses nordic-fi.html → fi","duration":0.2642640000000256,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses euro-nl.html → nl","status":"passed","title":"parses euro-nl.html → nl","duration":0.2965650000000437,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode parses svensk-sv.html → sv","status":"passed","title":"parses svensk-sv.html → sv","duration":0.26316300000002,"failureMessages":[],"location":{"line":40,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode returns null when filename has no trailing language suffix","status":"passed","title":"returns null when filename has no trailing language suffix","duration":0.3959509999999682,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getLanguageCode"],"fullName":"getLanguageCode rejects suffixes longer than two letters","status":"passed","title":"rejects suffixes longer than two letters","duration":0.38187499999997954,"failureMessages":[],"location":{"line":50,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG maps Norwegian filename suffix \"no\" to BCP-47 \"nb\" (preferred)","status":"passed","title":"maps Norwegian filename suffix \"no\" to BCP-47 \"nb\" (preferred)","duration":0.4178719999999885,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG maps every other language suffix to itself","status":"passed","title":"maps every other language suffix to itself","duration":0.8536080000000084,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["BCP47_TAG"],"fullName":"BCP47_TAG covers all 14 supported languages","status":"passed","title":"covers all 14 supported languages","duration":0.7412380000000098,"failureMessages":[],"location":{"line":73,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps Norwegian to nb_NO (not no_NO)","status":"passed","title":"maps Norwegian to nb_NO (not no_NO)","duration":0.4681860000000029,"failureMessages":[],"location":{"line":85,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps en to en_US","status":"passed","title":"maps en to en_US","duration":0.4925519999999892,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps sv to sv_SE","status":"passed","title":"maps sv to sv_SE","duration":0.3975849999999923,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps da to da_DK","status":"passed","title":"maps da to da_DK","duration":0.4456239999999525,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps fi to fi_FI","status":"passed","title":"maps fi to fi_FI","duration":0.3724480000000199,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps de to de_DE","status":"passed","title":"maps de to de_DE","duration":0.4339819999999577,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps fr to fr_FR","status":"passed","title":"maps fr to fr_FR","duration":0.3751320000000078,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps es to es_ES","status":"passed","title":"maps es to es_ES","duration":0.44222800000000007,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps nl to nl_NL","status":"passed","title":"maps nl to nl_NL","duration":0.4711529999999584,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ar to ar_SA","status":"passed","title":"maps ar to ar_SA","duration":0.3975940000000264,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps he to he_IL","status":"passed","title":"maps he to he_IL","duration":0.454830999999956,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ja to ja_JP","status":"passed","title":"maps ja to ja_JP","duration":0.6392460000000142,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps ko to ko_KR","status":"passed","title":"maps ko to ko_KR","duration":0.7275220000000218,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["OG_LOCALE_EXPECTED"],"fullName":"OG_LOCALE_EXPECTED maps zh to zh_CN","status":"passed","title":"maps zh to zh_CN","duration":0.5198430000000371,"failureMessages":[],"location":{"line":103,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["NON_SWEDISH_LANGS"],"fullName":"NON_SWEDISH_LANGS does not include Swedish","status":"passed","title":"does not include Swedish","duration":0.5298020000000179,"failureMessages":[],"location":{"line":109,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["NON_SWEDISH_LANGS"],"fullName":"NON_SWEDISH_LANGS includes the 13 non-Swedish supported languages","status":"passed","title":"includes the 13 non-Swedish supported languages","duration":1.4127960000000144,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]}],"startTime":1787953908628,"endTime":1787953908648.4128,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/language.test.ts"},{"assertionResults":[{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker detects English files as non-Swedish targets","status":"passed","title":"detects English files as non-Swedish targets","duration":6.513847999999996,"failureMessages":[],"location":{"line":50,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker skips Swedish files","status":"passed","title":"skips Swedish files","duration":1.1738579999999956,"failureMessages":[],"location":{"line":62,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker ignores files without a language code","status":"passed","title":"ignores files without a language code","duration":0.8005190000000084,"failureMessages":[],"location":{"line":73,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Language code detection + file walker"],"fullName":"validateNewsTranslations — orchestrator integration spine Language code detection + file walker recurses into subdirectories","status":"passed","title":"recurses into subdirectories","duration":0.9265250000000265,"failureMessages":[],"location":{"line":79,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes exits 1 when data-translate markers remain","status":"passed","title":"exits 1 when data-translate markers remain","duration":1.1089069999999879,"failureMessages":[],"location":{"line":96,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes exits 0 for fully translated articles","status":"passed","title":"exits 0 for fully translated articles","duration":0.7940570000000093,"failureMessages":[],"location":{"line":107,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Untranslated marker exit codes"],"fullName":"validateNewsTranslations — orchestrator integration spine Untranslated marker exit codes extracts a sample marker count when markers remain","status":"passed","title":"extracts a sample marker count when markers remain","duration":0.9262949999999819,"failureMessages":[],"location":{"line":117,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) passes Norwegian articles with consistent lang=\"nb\"","status":"passed","title":"passes Norwegian articles with consistent lang=\"nb\"","duration":1.7382949999999937,"failureMessages":[],"location":{"line":133,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) fails Norwegian articles that still use lang=\"no\"","status":"passed","title":"fails Norwegian articles that still use lang=\"no\"","duration":1.1317090000000007,"failureMessages":[],"location":{"line":145,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","BCP-47 consistency (nb vs legacy no migration)"],"fullName":"validateNewsTranslations — orchestrator integration spine BCP-47 consistency (nb vs legacy no migration) fails Arabic articles missing dir=\"rtl\"","status":"passed","title":"fails Arabic articles missing dir=\"rtl\"","duration":1.4655850000000328,"failureMessages":[],"location":{"line":158,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Content leakage detection (soft warning)"],"fullName":"validateNewsTranslations — orchestrator integration spine Content leakage detection (soft warning) warns on EN paragraph leakage in non-EN articles without failing","status":"passed","title":"warns on EN paragraph leakage in non-EN articles without failing","duration":1.4602449999999862,"failureMessages":[],"location":{"line":172,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","Content leakage detection (soft warning)"],"fullName":"validateNewsTranslations — orchestrator integration spine Content leakage detection (soft warning) warns on banned English phrases in translations","status":"passed","title":"warns on banned English phrases in translations","duration":0.9985389999999938,"failureMessages":[],"location":{"line":190,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","AI_MUST_REPLACE marker detection (restored regression)"],"fullName":"validateNewsTranslations — orchestrator integration spine AI_MUST_REPLACE marker detection (restored regression) fails with exit 1 when an AI_MUST_REPLACE comment remains","status":"passed","title":"fails with exit 1 when an AI_MUST_REPLACE comment remains","duration":1.4575099999999566,"failureMessages":[],"location":{"line":206,"column":5},"meta":{},"tags":[]},{"ancestorTitles":["validateNewsTranslations — orchestrator integration spine","AI_MUST_REPLACE marker detection (restored regression)"],"fullName":"validateNewsTranslations — orchestrator integration spine AI_MUST_REPLACE marker detection (restored regression) reports distinct sample marker names","status":"passed","title":"reports distinct sample marker names","duration":0.863476999999989,"failureMessages":[],"location":{"line":221,"column":5},"meta":{},"tags":[]}],"startTime":1787953832465,"endTime":1787953832486.8635,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/orchestrator.test.ts"},{"assertionResults":[{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles finds top-level HTML files","status":"passed","title":"finds top-level HTML files","duration":5.358584000000008,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles recurses into subdirectories","status":"passed","title":"recurses into subdirectories","duration":1.279115000000047,"failureMessages":[],"location":{"line":44,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles ignores non-HTML files","status":"passed","title":"ignores non-HTML files","duration":1.39358900000002,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["getAllHtmlFiles"],"fullName":"getAllHtmlFiles returns an empty array (and logs) for a missing directory","status":"passed","title":"returns an empty array (and logs) for a missing directory","duration":0.6805550000000267,"failureMessages":[],"location":{"line":65,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns the EN sibling path when it exists","status":"passed","title":"returns the EN sibling path when it exists","duration":0.7296959999999899,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns null when the EN sibling is missing","status":"passed","title":"returns null when the EN sibling is missing","duration":0.7496240000000398,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath returns null when the filename has no language suffix","status":"passed","title":"returns null when the filename has no language suffix","duration":0.5825010000000361,"failureMessages":[],"location":{"line":98,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["deriveEnSourcePath"],"fullName":"deriveEnSourcePath derives EN sibling regardless of source language (fr, ja, ar)","status":"passed","title":"derives EN sibling regardless of source language (fr, ja, ar)","duration":0.823421000000053,"failureMessages":[],"location":{"line":105,"column":3},"meta":{},"tags":[]}],"startTime":1787953901554,"endTime":1787953901565.8235,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/walker.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers returns null when no AI_MUST_REPLACE markers are present","status":"passed","title":"returns null when no AI_MUST_REPLACE markers are present","duration":4.322443000000021,"failureMessages":[],"location":{"line":34,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers detects a single AI_MUST_REPLACE comment","status":"passed","title":"detects a single AI_MUST_REPLACE comment","duration":2.1368610000000103,"failureMessages":[],"location":{"line":41,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers counts multiple markers and reports up to three distinct sample names","status":"passed","title":"counts multiple markers and reports up to three distinct sample names","duration":1.733746999999994,"failureMessages":[],"location":{"line":58,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers ignores AI_MUST_REPLACE text outside of HTML comments","status":"passed","title":"ignores AI_MUST_REPLACE text outside of HTML comments","duration":0.6151419999999916,"failureMessages":[],"location":{"line":80,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers records the filename even when the language suffix is missing","status":"passed","title":"records the filename even when the language suffix is missing","duration":0.6089699999999993,"failureMessages":[],"location":{"line":90,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForAIMustReplaceMarkers"],"fullName":"checkFileForAIMustReplaceMarkers throws a contextualised error when the file cannot be read","status":"passed","title":"throws a contextualised error when the file cannot be read","duration":1.3889609999999948,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]}],"startTime":1787953901995,"endTime":1787953902006.389,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/ai-must-replace.test.ts"},{"assertionResults":[{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration passes when html[lang]=\"nb\", og:locale=\"nb_NO\", inLanguage=\"nb\"","status":"passed","title":"passes when html[lang]=\"nb\", og:locale=\"nb_NO\", inLanguage=\"nb\"","duration":4.732761000000039,"failureMessages":[],"location":{"line":36,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags html[lang]=\"no\" as expected=\"nb\", actual=\"no\"","status":"passed","title":"flags html[lang]=\"no\" as expected=\"nb\", actual=\"no\"","duration":0.9353310000000192,"failureMessages":[],"location":{"line":46,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags inLanguage=\"no\" as expected=\"nb\", actual=\"no\"","status":"passed","title":"flags inLanguage=\"no\" as expected=\"nb\", actual=\"no\"","duration":0.5901759999999854,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — Norwegian nb/no migration"],"fullName":"validateBCP47Consistency — Norwegian nb/no migration flags og:locale=\"no_NO\" as expected=\"nb_NO\", actual=\"no_NO\"","status":"passed","title":"flags og:locale=\"no_NO\" as expected=\"nb_NO\", actual=\"no_NO\"","duration":0.5747860000000173,"failureMessages":[],"location":{"line":68,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute flags Arabic articles missing dir=\"rtl\"","status":"passed","title":"flags Arabic articles missing dir=\"rtl\"","duration":0.9245809999999892,"failureMessages":[],"location":{"line":91,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute flags Hebrew articles missing dir=\"rtl\"","status":"passed","title":"flags Hebrew articles missing dir=\"rtl\"","duration":0.7497440000000211,"failureMessages":[],"location":{"line":102,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — RTL dir attribute"],"fullName":"validateBCP47Consistency — RTL dir attribute passes Arabic articles that declare dir=\"rtl\"","status":"passed","title":"passes Arabic articles that declare dir=\"rtl\"","duration":0.5707089999999653,"failureMessages":[],"location":{"line":113,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles passes consistent English articles","status":"passed","title":"passes consistent English articles","duration":0.6079280000000153,"failureMessages":[],"location":{"line":135,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles reports html[lang] mismatch when the tag disagrees with the filename","status":"passed","title":"reports html[lang] mismatch when the tag disagrees with the filename","duration":0.9226370000000088,"failureMessages":[],"location":{"line":145,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["validateBCP47Consistency — consistent non-Norwegian articles"],"fullName":"validateBCP47Consistency — consistent non-Norwegian articles does not report og:locale when the meta tag is absent","status":"passed","title":"does not report og:locale when the meta tag is absent","duration":0.819184000000007,"failureMessages":[],"location":{"line":156,"column":3},"meta":{},"tags":[]}],"startTime":1787953868766,"endTime":1787953868777.819,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/bcp47.test.ts"},{"assertionResults":[{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs returns only paragraphs longer than the minimum length","status":"passed","title":"returns only paragraphs longer than the minimum length","duration":5.10769300000004,"failureMessages":[],"location":{"line":24,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs strips inline tags inside paragraphs","status":"passed","title":"strips inline tags inside paragraphs","duration":0.6272239999999556,"failureMessages":[],"location":{"line":35,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs removes <script> and <style> blocks before extraction","status":"passed","title":"removes <script> and <style> blocks before extraction","duration":0.5482569999999782,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["extractBodyParagraphs"],"fullName":"extractBodyParagraphs collapses whitespace inside paragraphs","status":"passed","title":"collapses whitespace inside paragraphs","duration":0.44676700000002256,"failureMessages":[],"location":{"line":54,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null when fileLang is \"en\" (EN articles are not checked)","status":"passed","title":"returns null when fileLang is \"en\" (EN articles are not checked)","duration":1.0737010000000282,"failureMessages":[],"location":{"line":72,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects EN paragraph leakage when the same paragraph appears in EN and DE files","status":"passed","title":"detects EN paragraph leakage when the same paragraph appears in EN and DE files","duration":1.214033000000029,"failureMessages":[],"location":{"line":82,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects Swedish leakage phrases in non-SV articles","status":"passed","title":"detects Swedish leakage phrases in non-SV articles","duration":1.081865999999991,"failureMessages":[],"location":{"line":95,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage detects banned English boilerplate phrases in translations","status":"passed","title":"detects banned English boilerplate phrases in translations","duration":0.7180850000000305,"failureMessages":[],"location":{"line":111,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null for fully translated DE articles with no leakage","status":"passed","title":"returns null for fully translated DE articles with no leakage","duration":0.8411550000000148,"failureMessages":[],"location":{"line":128,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage returns null when the translated body has no paragraphs above the minimum length","status":"passed","title":"returns null when the translated body has no paragraphs above the minimum length","duration":0.5762290000000121,"failureMessages":[],"location":{"line":143,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkBodyContentLeakage"],"fullName":"checkBodyContentLeakage handles a missing EN source file gracefully (phrase rules still run)","status":"passed","title":"handles a missing EN source file gracefully (phrase rules still run)","duration":0.7344549999999685,"failureMessages":[],"location":{"line":150,"column":3},"meta":{},"tags":[]}],"startTime":1787953855856,"endTime":1787953855869.7344,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/body-leakage.test.ts"},{"assertionResults":[{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns passed=true when no markers are present","status":"passed","title":"returns passed=true when no markers are present","duration":4.171379999999999,"failureMessages":[],"location":{"line":32,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent counts every data-translate=\"true\" occurrence","status":"passed","title":"counts every data-translate=\"true\" occurrence","duration":0.9191710000000057,"failureMessages":[],"location":{"line":42,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns up to three sample Swedish snippets from the markers","status":"passed","title":"returns up to three sample Swedish snippets from the markers","duration":1.5466260000000034,"failureMessages":[],"location":{"line":57,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent returns an error record when the file cannot be read","status":"passed","title":"returns an error record when the file cannot be read","duration":0.6128070000000321,"failureMessages":[],"location":{"line":75,"column":3},"meta":{},"tags":[]},{"ancestorTitles":["checkFileForUntranslatedContent"],"fullName":"checkFileForUntranslatedContent does not match standalone strings without the full attribute","status":"passed","title":"does not match standalone strings without the full attribute","duration":0.5411129999999957,"failureMessages":[],"location":{"line":83,"column":3},"meta":{},"tags":[]}],"startTime":1787953912651,"endTime":1787953912659.541,"status":"passed","message":"","name":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/tests/validators/news-translations/rules/untranslated.test.ts"}],"coverageMap":{"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/analysis-gate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/analysis-gate.ts","statementMap":{"0":{"start":{"line":71,"column":36},"end":{"line":71,"column":null}},"1":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"2":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"3":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"4":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"6":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"7":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"8":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"9":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"10":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"11":{"start":{"line":84,"column":23},"end":{"line":84,"column":null}},"12":{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},"13":{"start":{"line":85,"column":2},"end":{"line":89,"column":null}}},"fnMap":{"0":{"name":"validateAnalysisGate","decl":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"loc":{"start":{"line":70,"column":33},"end":{"line":90,"column":null}},"line":70},"1":{"name":"(anonymous_1)","decl":{"start":{"line":84,"column":30},"end":{"line":84,"column":38}},"loc":{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},"line":84}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":180,"13":3},"f":{"0":3,"1":180},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":14,"seen":{"f:68:22:68:Infinity":0,"s:71:36:71:Infinity":0,"s:73:2:73:Infinity":1,"s:74:2:74:Infinity":2,"s:75:2:75:Infinity":3,"s:76:2:76:Infinity":4,"s:77:2:77:Infinity":5,"s:78:2:78:Infinity":6,"s:79:2:79:Infinity":7,"s:80:2:80:Infinity":8,"s:81:2:81:Infinity":9,"s:82:2:82:Infinity":10,"s:84:23:84:Infinity":11,"f:84:30:84:38":1,"s:84:44:84:53":12,"s:85:2:89:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/artifact-existence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/artifact-existence.ts","statementMap":{"0":{"start":{"line":20,"column":37},"end":{"line":20,"column":null}},"1":{"start":{"line":21,"column":2},"end":{"line":45,"column":null}},"2":{"start":{"line":22,"column":21},"end":{"line":22,"column":null}},"3":{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},"4":{"start":{"line":24,"column":6},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},"6":{"start":{"line":31,"column":6},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":6},"end":{"line":43,"column":null}},"8":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkArtifactExistence","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":39}},"loc":{"start":{"line":19,"column":79},"end":{"line":47,"column":null}},"line":19}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":44,"column":null}},{"start":{"line":30,"column":11},"end":{"line":44,"column":null}}],"line":23},"1":{"loc":{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":11},"end":{"line":44,"column":null}},{"start":{"line":37,"column":11},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":161,"3":161,"4":47,"5":114,"6":1,"7":113,"8":7},"f":{"0":7},"b":{"0":[47,114],"1":[1,113]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":9,"seen":{"f:19:16:19:39":0,"s:20:37:20:Infinity":0,"s:21:2:45:Infinity":1,"s:22:21:22:Infinity":2,"b:23:4:44:Infinity:30:11:44:Infinity":0,"s:23:4:44:Infinity":3,"s:24:6:29:Infinity":4,"b:30:11:44:Infinity:37:11:44:Infinity":1,"s:30:11:44:Infinity":5,"s:31:6:36:Infinity":6,"s:38:6:43:Infinity":7,"s:46:2:46:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/coalition-mathematics.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/coalition-mathematics.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":19},"end":{"line":28,"column":null}},"6":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"7":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":43,"column":null}},"9":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkCoalitionMathematics","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":47,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},{"start":{"line":37,"column":9},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":2,"8":4,"9":6},"f":{"0":7},"b":{"0":[1,6],"1":[2,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":10,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:28:19:28:Infinity":5,"b:30:2:44:Infinity:37:9:44:Infinity":1,"s:30:2:44:Infinity":6,"s:31:4:36:Infinity":7,"s:38:4:43:Infinity":8,"s:46:2:46:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/artifact-inventory.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/artifact-inventory.ts","statementMap":{"0":{"start":{"line":68,"column":65},"end":{"line":78,"column":null}},"1":{"start":{"line":85,"column":65},"end":{"line":88,"column":null}},"2":{"start":{"line":95,"column":65},"end":{"line":101,"column":null}},"3":{"start":{"line":108,"column":65},"end":{"line":116,"column":null}},"4":{"start":{"line":123,"column":69},"end":{"line":128,"column":null}},"5":{"start":{"line":131,"column":62},"end":{"line":133,"column":null}},"6":{"start":{"line":132,"column":36},"end":{"line":132,"column":46}},"7":{"start":{"line":136,"column":61},"end":{"line":138,"column":null}},"8":{"start":{"line":137,"column":39},"end":{"line":137,"column":56}},"9":{"start":{"line":137,"column":69},"end":{"line":137,"column":79}},"10":{"start":{"line":141,"column":59},"end":{"line":143,"column":null}},"11":{"start":{"line":142,"column":39},"end":{"line":142,"column":54}},"12":{"start":{"line":142,"column":67},"end":{"line":142,"column":77}},"13":{"start":{"line":149,"column":52},"end":{"line":154,"column":null}},"14":{"start":{"line":160,"column":54},"end":{"line":173,"column":null}},"15":{"start":{"line":179,"column":53},"end":{"line":188,"column":null}},"16":{"start":{"line":194,"column":30},"end":{"line":194,"column":null}},"17":{"start":{"line":202,"column":2},"end":{"line":202,"column":null}},"18":{"start":{"line":210,"column":32},"end":{"line":212,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":132,"column":25},"end":{"line":132,"column":30}},"loc":{"start":{"line":132,"column":36},"end":{"line":132,"column":46}},"line":132},"1":{"name":"(anonymous_1)","decl":{"start":{"line":137,"column":25},"end":{"line":137,"column":33}},"loc":{"start":{"line":137,"column":39},"end":{"line":137,"column":56}},"line":137},"2":{"name":"(anonymous_2)","decl":{"start":{"line":137,"column":58},"end":{"line":137,"column":63}},"loc":{"start":{"line":137,"column":69},"end":{"line":137,"column":79}},"line":137},"3":{"name":"(anonymous_3)","decl":{"start":{"line":142,"column":25},"end":{"line":142,"column":33}},"loc":{"start":{"line":142,"column":39},"end":{"line":142,"column":54}},"line":142},"4":{"name":"(anonymous_4)","decl":{"start":{"line":142,"column":56},"end":{"line":142,"column":61}},"loc":{"start":{"line":142,"column":67},"end":{"line":142,"column":77}},"line":142},"5":{"name":"escapeRegexLiteral","decl":{"start":{"line":201,"column":9},"end":{"line":201,"column":28}},"loc":{"start":{"line":201,"column":47},"end":{"line":203,"column":null}},"line":201}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":23,"4":23,"5":23,"6":529,"7":23,"8":529,"9":368,"10":23,"11":529,"12":506,"13":23,"14":23,"15":23,"16":23,"17":184,"18":23},"f":{"0":529,"1":529,"2":368,"3":529,"4":506,"5":184},"b":{},"meta":{"lastBranch":0,"lastFunction":6,"lastStatement":19,"seen":{"s:68:65:78:Infinity":0,"s:85:65:88:Infinity":1,"s:95:65:101:Infinity":2,"s:108:65:116:Infinity":3,"s:123:69:128:Infinity":4,"s:131:62:133:Infinity":5,"f:132:25:132:30":0,"s:132:36:132:46":6,"s:136:61:138:Infinity":7,"f:137:25:137:33":1,"s:137:39:137:56":8,"f:137:58:137:63":2,"s:137:69:137:79":9,"s:141:59:143:Infinity":10,"f:142:25:142:33":3,"s:142:39:142:54":11,"f:142:56:142:61":4,"s:142:67:142:77":12,"s:149:52:154:Infinity":13,"s:160:54:173:Infinity":14,"s:179:53:188:Infinity":15,"s:194:30:194:Infinity":16,"f:201:9:201:28":5,"s:202:2:202:Infinity":17,"s:210:32:212:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/comparative-international.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/comparative-international.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":29,"column":28},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":27},"end":{"line":31,"column":null}},"7":{"start":{"line":33,"column":20},"end":{"line":38,"column":null}},"8":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"9":{"start":{"line":34,"column":27},"end":{"line":34,"column":null}},"10":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"11":{"start":{"line":35,"column":52},"end":{"line":35,"column":null}},"12":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"13":{"start":{"line":36,"column":67},"end":{"line":36,"column":null}},"14":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"15":{"start":{"line":40,"column":24},"end":{"line":40,"column":null}},"16":{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},"17":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"18":{"start":{"line":50,"column":4},"end":{"line":55,"column":null}},"19":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"checkComparativeInternational","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":59,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":40},"end":{"line":33,"column":48}},"loc":{"start":{"line":33,"column":57},"end":{"line":38,"column":3}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":27},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":27},"end":{"line":30,"column":null}},{"start":{"line":31,"column":4},"end":{"line":31,"column":null}}],"line":30},"2":{"loc":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":35},"4":{"loc":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"5":{"loc":{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":56,"column":null}},{"start":{"line":49,"column":9},"end":{"line":56,"column":null}}],"line":42},"6":{"loc":{"start":{"line":42,"column":6},"end":{"line":42,"column":43}},"type":"binary-expr","locations":[{"start":{"line":42,"column":6},"end":{"line":42,"column":27}},{"start":{"line":42,"column":27},"end":{"line":42,"column":43}}],"line":42}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":7,"8":36,"9":20,"10":16,"11":4,"12":12,"13":4,"14":8,"15":7,"16":7,"17":1,"18":5,"19":6},"f":{"0":7,"1":36},"b":{"0":[1,6],"1":[6,4],"2":[20,16],"3":[4,12],"4":[4,8],"5":[1,5],"6":[7,2]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":20,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:29:28:29:Infinity":5,"s:30:27:31:Infinity":6,"b:30:27:30:Infinity:31:4:31:Infinity":1,"s:33:20:38:Infinity":7,"f:33:40:33:48":1,"b:34:4:34:Infinity:undefined:undefined:undefined:undefined":2,"s:34:4:34:Infinity":8,"s:34:27:34:Infinity":9,"b:35:4:35:Infinity:undefined:undefined:undefined:undefined":3,"s:35:4:35:Infinity":10,"s:35:52:35:Infinity":11,"b:36:4:36:Infinity:undefined:undefined:undefined:undefined":4,"s:36:4:36:Infinity":12,"s:36:67:36:Infinity":13,"s:37:4:37:Infinity":14,"s:40:24:40:Infinity":15,"b:42:2:56:Infinity:49:9:56:Infinity":5,"s:42:2:56:Infinity":16,"b:42:6:42:27:42:27:42:43":6,"s:43:4:48:Infinity":17,"s:50:4:55:Infinity":18,"s:58:2:58:Infinity":19}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/evidence-citations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/evidence-citations.ts","statementMap":{"0":{"start":{"line":24,"column":37},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}}},"fnMap":{"0":{"name":"checkEvidenceCitations","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":23,"column":30},"end":{"line":30,"column":null}},"line":23}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"f:21:22:21:Infinity":0,"s:24:37:24:Infinity":0,"s:26:2:26:Infinity":1,"s:27:2:27:Infinity":2,"s:29:2:29:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/devils-advocate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/devils-advocate.ts","statementMap":{"0":{"start":{"line":28,"column":37},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":19},"end":{"line":29,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"3":{"start":{"line":30,"column":29},"end":{"line":30,"column":null}},"4":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"5":{"start":{"line":33,"column":20},"end":{"line":35,"column":null}},"6":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":44,"column":null}},"9":{"start":{"line":46,"column":4},"end":{"line":51,"column":null}},"10":{"start":{"line":57,"column":33},"end":{"line":60,"column":null}},"11":{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},"12":{"start":{"line":62,"column":4},"end":{"line":67,"column":null}},"13":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"14":{"start":{"line":71,"column":24},"end":{"line":74,"column":null}},"15":{"start":{"line":75,"column":17},"end":{"line":77,"column":null}},"16":{"start":{"line":77,"column":22},"end":{"line":77,"column":59}},"17":{"start":{"line":78,"column":23},"end":{"line":78,"column":null}},"18":{"start":{"line":78,"column":44},"end":{"line":78,"column":57}},"19":{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},"20":{"start":{"line":80,"column":4},"end":{"line":85,"column":null}},"21":{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},"22":{"start":{"line":87,"column":4},"end":{"line":92,"column":null}},"23":{"start":{"line":94,"column":4},"end":{"line":99,"column":null}},"24":{"start":{"line":102,"column":2},"end":{"line":102,"column":null}}},"fnMap":{"0":{"name":"checkDevilsAdvocate","decl":{"start":{"line":25,"column":22},"end":{"line":25,"column":null}},"loc":{"start":{"line":27,"column":30},"end":{"line":103,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":77,"column":5},"end":{"line":77,"column":13}},"loc":{"start":{"line":77,"column":22},"end":{"line":77,"column":59}},"line":77},"2":{"name":"(anonymous_2)","decl":{"start":{"line":78,"column":30},"end":{"line":78,"column":36}},"loc":{"start":{"line":78,"column":44},"end":{"line":78,"column":57}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":30},"1":{"loc":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":28},"end":{"line":36,"column":47}},{"start":{"line":36,"column":47},"end":{"line":36,"column":null}}],"line":36},"2":{"loc":{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":52,"column":null}},{"start":{"line":45,"column":9},"end":{"line":52,"column":null}}],"line":38},"3":{"loc":{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":61},"4":{"loc":{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":100,"column":null}},{"start":{"line":86,"column":9},"end":{"line":100,"column":null}}],"line":79},"5":{"loc":{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":9},"end":{"line":100,"column":null}},{"start":{"line":93,"column":9},"end":{"line":100,"column":null}}],"line":86}},"s":{"0":8,"1":8,"2":8,"3":2,"4":6,"5":6,"6":6,"7":8,"8":0,"9":6,"10":6,"11":6,"12":1,"13":1,"14":5,"15":5,"16":34,"17":5,"18":14,"19":5,"20":0,"21":5,"22":1,"23":4,"24":5},"f":{"0":8,"1":34,"2":14},"b":{"0":[2,6],"1":[6,0],"2":[0,6],"3":[1,5],"4":[0,5],"5":[1,4]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":25,"seen":{"f:25:22:25:Infinity":0,"s:28:37:28:Infinity":0,"s:29:19:29:Infinity":1,"b:30:2:30:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:30:Infinity":2,"s:30:29:30:Infinity":3,"s:32:18:32:Infinity":4,"s:33:20:35:Infinity":5,"s:36:16:36:Infinity":6,"b:36:28:36:47:36:47:36:Infinity":1,"b:38:2:52:Infinity:45:9:52:Infinity":2,"s:38:2:52:Infinity":7,"s:39:4:44:Infinity":8,"s:46:4:51:Infinity":9,"s:57:33:60:Infinity":10,"b:61:2:69:Infinity:undefined:undefined:undefined:undefined":3,"s:61:2:69:Infinity":11,"s:62:4:67:Infinity":12,"s:68:4:68:Infinity":13,"s:71:24:74:Infinity":14,"s:75:17:77:Infinity":15,"f:77:5:77:13":1,"s:77:22:77:59":16,"s:78:23:78:Infinity":17,"f:78:30:78:36":2,"s:78:44:78:57":18,"b:79:2:100:Infinity:86:9:100:Infinity":4,"s:79:2:100:Infinity":19,"s:80:4:85:Infinity":20,"b:86:9:100:Infinity:93:9:100:Infinity":5,"s:86:9:100:Infinity":21,"s:87:4:92:Infinity":22,"s:94:4:99:Infinity":23,"s:102:2:102:Infinity":24}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief-h1.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief-h1.ts","statementMap":{"0":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"2":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"3":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"5":{"start":{"line":28,"column":14},"end":{"line":28,"column":null}},"6":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"7":{"start":{"line":34,"column":80},"end":{"line":39,"column":null}},"8":{"start":{"line":41,"column":73},"end":{"line":58,"column":null}},"9":{"start":{"line":61,"column":2},"end":{"line":70,"column":null}},"10":{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},"11":{"start":{"line":63,"column":6},"end":{"line":68,"column":null}},"12":{"start":{"line":74,"column":18},"end":{"line":78,"column":null}},"13":{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},"14":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":95,"column":18},"end":{"line":95,"column":null}},"16":{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},"17":{"start":{"line":97,"column":27},"end":{"line":102,"column":null}},"18":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"19":{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},"20":{"start":{"line":104,"column":6},"end":{"line":110,"column":null}},"21":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"22":{"start":{"line":114,"column":2},"end":{"line":124,"column":null}},"23":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"24":{"start":{"line":116,"column":6},"end":{"line":121,"column":null}},"25":{"start":{"line":122,"column":6},"end":{"line":122,"column":null}},"26":{"start":{"line":125,"column":20},"end":{"line":125,"column":null}},"27":{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},"28":{"start":{"line":127,"column":4},"end":{"line":133,"column":null}},"29":{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},"30":{"start":{"line":139,"column":4},"end":{"line":145,"column":null}},"31":{"start":{"line":158,"column":19},"end":{"line":158,"column":null}},"32":{"start":{"line":159,"column":20},"end":{"line":159,"column":null}},"33":{"start":{"line":160,"column":22},"end":{"line":160,"column":null}},"34":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"35":{"start":{"line":161,"column":74},"end":{"line":161,"column":null}},"36":{"start":{"line":162,"column":2},"end":{"line":203,"column":null}},"37":{"start":{"line":163,"column":25},"end":{"line":168,"column":null}},"38":{"start":{"line":164,"column":21},"end":{"line":164,"column":36}},"39":{"start":{"line":165,"column":18},"end":{"line":165,"column":24}},"40":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"41":{"start":{"line":169,"column":10},"end":{"line":177,"column":null}},"42":{"start":{"line":170,"column":6},"end":{"line":177,"column":null}},"43":{"start":{"line":178,"column":24},"end":{"line":178,"column":null}},"44":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"45":{"start":{"line":179,"column":33},"end":{"line":179,"column":null}},"46":{"start":{"line":180,"column":4},"end":{"line":200,"column":null}},"47":{"start":{"line":181,"column":27},"end":{"line":181,"column":null}},"48":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"49":{"start":{"line":182,"column":37},"end":{"line":182,"column":null}},"50":{"start":{"line":183,"column":37},"end":{"line":183,"column":null}},"51":{"start":{"line":184,"column":6},"end":{"line":188,"column":null}},"52":{"start":{"line":185,"column":8},"end":{"line":185,"column":null}},"53":{"start":{"line":187,"column":8},"end":{"line":187,"column":null}},"54":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"55":{"start":{"line":189,"column":22},"end":{"line":189,"column":null}},"56":{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},"57":{"start":{"line":191,"column":8},"end":{"line":197,"column":null}},"58":{"start":{"line":198,"column":8},"end":{"line":198,"column":null}}},"fnMap":{"0":{"name":"extractExecutiveBriefH1","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":40}},"loc":{"start":{"line":23,"column":72},"end":{"line":31,"column":null}},"line":23},"1":{"name":"checkH1Placeholders","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":36}},"loc":{"start":{"line":60,"column":82},"end":{"line":71,"column":null}},"line":60},"2":{"name":"checkH1Boilerplate","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":35}},"loc":{"start":{"line":73,"column":81},"end":{"line":88,"column":null}},"line":73},"3":{"name":"checkH1RendererCollapse","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"loc":{"start":{"line":94,"column":8},"end":{"line":147,"column":null}},"line":94},"4":{"name":"(anonymous_4)","decl":{"start":{"line":97,"column":35},"end":{"line":97,"column":null}},"loc":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"line":99},"5":{"name":"checkH1AcrossDaysUniqueness","decl":{"start":{"line":149,"column":16},"end":{"line":149,"column":null}},"loc":{"start":{"line":154,"column":8},"end":{"line":204,"column":null}},"line":154},"6":{"name":"(anonymous_6)","decl":{"start":{"line":164,"column":7},"end":{"line":164,"column":15}},"loc":{"start":{"line":164,"column":21},"end":{"line":164,"column":36}},"line":164},"7":{"name":"(anonymous_7)","decl":{"start":{"line":165,"column":7},"end":{"line":165,"column":12}},"loc":{"start":{"line":165,"column":18},"end":{"line":165,"column":24}},"line":165},"8":{"name":"(anonymous_8)","decl":{"start":{"line":166,"column":7},"end":{"line":166,"column":15}},"loc":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"line":166},"9":{"name":"(anonymous_9)","decl":{"start":{"line":169,"column":10},"end":{"line":169,"column":25}},"loc":{"start":{"line":170,"column":6},"end":{"line":177,"column":null}},"line":170}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"2":{"loc":{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":79},"4":{"loc":{"start":{"line":79,"column":6},"end":{"line":79,"column":55}},"type":"binary-expr","locations":[{"start":{"line":79,"column":6},"end":{"line":79,"column":39}},{"start":{"line":79,"column":39},"end":{"line":79,"column":55}}],"line":79},"5":{"loc":{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":96},"6":{"loc":{"start":{"line":99,"column":8},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},{"start":{"line":100,"column":8},"end":{"line":100,"column":null}},{"start":{"line":101,"column":8},"end":{"line":101,"column":null}}],"line":99},"7":{"loc":{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":4},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":103},"8":{"loc":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":115},"9":{"loc":{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":2},"end":{"line":146,"column":null}},{"start":{"line":134,"column":9},"end":{"line":146,"column":null}}],"line":126},"10":{"loc":{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":9},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":134},"11":{"loc":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"12":{"loc":{"start":{"line":161,"column":6},"end":{"line":161,"column":74}},"type":"binary-expr","locations":[{"start":{"line":161,"column":6},"end":{"line":161,"column":50}},{"start":{"line":161,"column":50},"end":{"line":161,"column":74}}],"line":161},"13":{"loc":{"start":{"line":166,"column":21},"end":{"line":166,"column":69}},"type":"binary-expr","locations":[{"start":{"line":166,"column":21},"end":{"line":166,"column":54}},{"start":{"line":166,"column":54},"end":{"line":166,"column":69}}],"line":166},"14":{"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":179},"15":{"loc":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"16":{"loc":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},{"start":{},"end":{}}],"line":189},"17":{"loc":{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},"type":"if","locations":[{"start":{"line":190,"column":6},"end":{"line":199,"column":null}},{"start":{},"end":{}}],"line":190}},"s":{"0":27,"1":27,"2":21,"3":6,"4":6,"5":6,"6":3,"7":4,"8":4,"9":18,"10":72,"11":5,"12":18,"13":18,"14":1,"15":18,"16":18,"17":2,"18":1,"19":2,"20":1,"21":2,"22":16,"23":59,"24":3,"25":3,"26":16,"27":16,"28":1,"29":15,"30":1,"31":18,"32":18,"33":18,"34":18,"35":16,"36":2,"37":2,"38":4,"39":4,"40":4,"41":2,"42":4,"43":2,"44":2,"45":0,"46":2,"47":2,"48":2,"49":0,"50":2,"51":2,"52":2,"53":0,"54":2,"55":0,"56":2,"57":1,"58":1},"f":{"0":27,"1":18,"2":18,"3":18,"4":1,"5":18,"6":4,"7":4,"8":4,"9":4},"b":{"0":[21,6],"1":[3,3],"2":[5,67],"3":[1,17],"4":[18,17],"5":[2,16],"6":[1,1,1],"7":[1,1],"8":[3,56],"9":[1,15],"10":[1,14],"11":[16,2],"12":[18,2],"13":[4,4],"14":[0,2],"15":[0,2],"16":[0,2],"17":[1,1]},"meta":{"lastBranch":18,"lastFunction":10,"lastStatement":59,"seen":{"f:23:16:23:40":0,"s:24:21:24:Infinity":0,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":1,"s:25:18:25:Infinity":2,"s:27:17:27:Infinity":3,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":1,"s:28:2:28:Infinity":4,"s:28:14:28:Infinity":5,"s:30:2:30:Infinity":6,"s:34:80:39:Infinity":7,"s:41:73:58:Infinity":8,"f:60:16:60:36":1,"s:61:2:70:Infinity":9,"b:62:4:69:Infinity:undefined:undefined:undefined:undefined":2,"s:62:4:69:Infinity":10,"s:63:6:68:Infinity":11,"f:73:16:73:35":2,"s:74:18:78:Infinity":12,"b:79:2:87:Infinity:undefined:undefined:undefined:undefined":3,"s:79:2:87:Infinity":13,"b:79:6:79:39:79:39:79:55":4,"s:80:4:86:Infinity":14,"f:90:16:90:Infinity":3,"s:95:18:95:Infinity":15,"b:96:2:113:Infinity:undefined:undefined:undefined:undefined":5,"s:96:2:113:Infinity":16,"s:97:27:102:Infinity":17,"f:97:35:97:Infinity":4,"s:99:8:101:Infinity":18,"b:99:8:99:Infinity:100:8:100:Infinity:101:8:101:Infinity":6,"b:103:4:111:Infinity:undefined:undefined:undefined:undefined":7,"s:103:4:111:Infinity":19,"s:104:6:110:Infinity":20,"s:112:4:112:Infinity":21,"s:114:2:124:Infinity":22,"b:115:4:123:Infinity:undefined:undefined:undefined:undefined":8,"s:115:4:123:Infinity":23,"s:116:6:121:Infinity":24,"s:122:6:122:Infinity":25,"s:125:20:125:Infinity":26,"b:126:2:146:Infinity:134:9:146:Infinity":9,"s:126:2:146:Infinity":27,"s:127:4:133:Infinity":28,"b:134:9:146:Infinity:undefined:undefined:undefined:undefined":10,"s:134:9:146:Infinity":29,"s:139:4:145:Infinity":30,"f:149:16:149:Infinity":5,"s:158:19:158:Infinity":31,"s:159:20:159:Infinity":32,"s:160:22:160:Infinity":33,"b:161:2:161:Infinity:undefined:undefined:undefined:undefined":11,"s:161:2:161:Infinity":34,"b:161:6:161:50:161:50:161:74":12,"s:161:74:161:Infinity":35,"s:162:2:203:Infinity":36,"s:163:25:168:Infinity":37,"f:164:7:164:15":6,"s:164:21:164:36":38,"f:165:7:165:12":7,"s:165:18:165:24":39,"f:166:7:166:15":8,"s:166:21:166:69":40,"b:166:21:166:54:166:54:166:69":13,"s:169:10:177:Infinity":41,"f:169:10:169:25":9,"s:170:6:177:Infinity":42,"s:178:24:178:Infinity":43,"b:179:4:179:Infinity:undefined:undefined:undefined:undefined":14,"s:179:4:179:Infinity":44,"s:179:33:179:Infinity":45,"s:180:4:200:Infinity":46,"s:181:27:181:Infinity":47,"b:182:6:182:Infinity:undefined:undefined:undefined:undefined":15,"s:182:6:182:Infinity":48,"s:182:37:182:Infinity":49,"s:183:37:183:Infinity":50,"s:184:6:188:Infinity":51,"s:185:8:185:Infinity":52,"s:187:8:187:Infinity":53,"b:189:6:189:Infinity:undefined:undefined:undefined:undefined":16,"s:189:6:189:Infinity":54,"s:189:22:189:Infinity":55,"b:190:6:199:Infinity:undefined:undefined:undefined:undefined":17,"s:190:6:199:Infinity":56,"s:191:8:197:Infinity":57,"s:198:8:198:Infinity":58}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-d-structure.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-d-structure.ts","statementMap":{"0":{"start":{"line":21,"column":37},"end":{"line":21,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}}},"fnMap":{"0":{"name":"checkFamilyDStructure","decl":{"start":{"line":18,"column":22},"end":{"line":18,"column":null}},"loc":{"start":{"line":20,"column":30},"end":{"line":27,"column":null}},"line":20}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"f:18:22:18:Infinity":0,"s:21:37:21:Infinity":0,"s:23:2:23:Infinity":1,"s:24:2:24:Infinity":2,"s:26:2:26:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/executive-brief.ts","statementMap":{"0":{"start":{"line":41,"column":37},"end":{"line":41,"column":null}},"1":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"2":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"3":{"start":{"line":43,"column":29},"end":{"line":43,"column":null}},"4":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"5":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"7":{"start":{"line":49,"column":4},"end":{"line":54,"column":null}},"8":{"start":{"line":57,"column":23},"end":{"line":57,"column":null}},"9":{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},"10":{"start":{"line":59,"column":4},"end":{"line":64,"column":null}},"11":{"start":{"line":70,"column":30},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":20},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":13},"end":{"line":72,"column":null}},"14":{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},"15":{"start":{"line":74,"column":4},"end":{"line":80,"column":null}},"16":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"17":{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},"18":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"19":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"20":{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},"21":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"22":{"start":{"line":93,"column":4},"end":{"line":98,"column":null}},"23":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"checkExecutiveBrief","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":40,"column":30},"end":{"line":102,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":91,"column":12},"end":{"line":91,"column":20}},"loc":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"line":91}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":71,"column":20},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":20},"end":{"line":71,"column":75}},{"start":{"line":71,"column":75},"end":{"line":71,"column":null}}],"line":71},"4":{"loc":{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":86,"column":null}},{"start":{"line":81,"column":9},"end":{"line":86,"column":null}}],"line":73},"5":{"loc":{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":88},"6":{"loc":{"start":{"line":89,"column":4},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},{"start":{"line":91,"column":4},"end":{"line":91,"column":null}}],"line":89},"7":{"loc":{"start":{"line":91,"column":26},"end":{"line":91,"column":74}},"type":"binary-expr","locations":[{"start":{"line":91,"column":26},"end":{"line":91,"column":39}},{"start":{"line":91,"column":39},"end":{"line":91,"column":74}}],"line":91}},"s":{"0":21,"1":21,"2":21,"3":1,"4":20,"5":20,"6":20,"7":1,"8":20,"9":20,"10":1,"11":20,"12":20,"13":21,"14":21,"15":2,"16":18,"17":18,"18":18,"19":18,"20":20,"21":14,"22":6,"23":20},"f":{"0":21,"1":14},"b":{"0":[1,20],"1":[1,19],"2":[1,19],"3":[20,0],"4":[2,18],"5":[6,14],"6":[20,19,18],"7":[14,14]},"meta":{"lastBranch":8,"lastFunction":2,"lastStatement":24,"seen":{"f:38:22:38:Infinity":0,"s:41:37:41:Infinity":0,"s:42:19:42:Infinity":1,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":2,"s:43:29:43:Infinity":3,"s:45:18:45:Infinity":4,"s:47:18:47:Infinity":5,"b:48:2:55:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:55:Infinity":6,"s:49:4:54:Infinity":7,"s:57:23:57:Infinity":8,"b:58:2:65:Infinity:undefined:undefined:undefined:undefined":2,"s:58:2:65:Infinity":9,"s:59:4:64:Infinity":10,"s:70:30:70:Infinity":11,"s:71:20:71:Infinity":12,"b:71:20:71:75:71:75:71:Infinity":3,"s:72:13:72:Infinity":13,"b:73:2:86:Infinity:81:9:86:Infinity":4,"s:73:2:86:Infinity":14,"s:74:4:80:Infinity":15,"s:82:4:82:Infinity":16,"s:83:4:83:Infinity":17,"s:84:4:84:Infinity":18,"s:85:4:85:Infinity":19,"b:88:2:99:Infinity:undefined:undefined:undefined:undefined":5,"s:88:2:99:Infinity":20,"b:89:4:89:Infinity:90:4:90:Infinity:91:4:91:Infinity":6,"f:91:12:91:20":1,"s:91:26:91:74":21,"b:91:26:91:39:91:39:91:74":7,"s:93:4:98:Infinity":22,"s:101:2:101:Infinity":23}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-c-structure.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/family-c-structure.ts","statementMap":{"0":{"start":{"line":26,"column":37},"end":{"line":26,"column":null}},"1":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"4":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"5":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"7":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}}},"fnMap":{"0":{"name":"checkFamilyCStructure","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":25,"column":30},"end":{"line":36,"column":null}},"line":25}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5},"f":{"0":5},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":8,"seen":{"f:23:22:23:Infinity":0,"s:26:37:26:Infinity":0,"s:28:2:28:Infinity":1,"s:29:2:29:Infinity":2,"s:30:2:30:Infinity":3,"s:31:2:31:Infinity":4,"s:32:2:32:Infinity":5,"s:33:2:33:Infinity":6,"s:35:2:35:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/forward-indicators.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/forward-indicators.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"6":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"7":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},"9":{"start":{"line":33,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"11":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"checkForwardIndicators","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":49,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":26},"end":{"line":30,"column":43}},{"start":{"line":30,"column":43},"end":{"line":30,"column":null}}],"line":30},"2":{"loc":{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":46,"column":null}},{"start":{"line":39,"column":9},"end":{"line":46,"column":null}}],"line":32}},"s":{"0":8,"1":8,"2":8,"3":1,"4":7,"5":7,"6":7,"7":7,"8":8,"9":2,"10":5,"11":7},"f":{"0":8},"b":{"0":[1,7],"1":[7,0],"2":[2,5]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":12,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:28:22:28:Infinity":5,"s:29:18:29:Infinity":6,"s:30:16:30:Infinity":7,"b:30:26:30:43:30:43:30:Infinity":1,"b:32:2:46:Infinity:39:9:46:Infinity":2,"s:32:2:46:Infinity":8,"s:33:4:38:Infinity":9,"s:40:4:45:Infinity":10,"s:48:2:48:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/intelligence-assessment.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/intelligence-assessment.ts","statementMap":{"0":{"start":{"line":23,"column":37},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"3":{"start":{"line":25,"column":29},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"5":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":18},"end":{"line":30,"column":null}},"7":{"start":{"line":30,"column":55},"end":{"line":30,"column":75}},"8":{"start":{"line":31,"column":18},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},"10":{"start":{"line":33,"column":4},"end":{"line":38,"column":null}},"11":{"start":{"line":41,"column":22},"end":{"line":43,"column":null}},"12":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"13":{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},"14":{"start":{"line":46,"column":4},"end":{"line":51,"column":null}},"15":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"16":{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},"17":{"start":{"line":56,"column":4},"end":{"line":61,"column":null}},"18":{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},"19":{"start":{"line":65,"column":4},"end":{"line":70,"column":null}},"20":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}}},"fnMap":{"0":{"name":"checkIntelligenceAssessment","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":22,"column":30},"end":{"line":74,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":38},"end":{"line":30,"column":46}},"loc":{"start":{"line":30,"column":55},"end":{"line":30,"column":75}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":25},"1":{"loc":{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":32},"2":{"loc":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":34},"end":{"line":44,"column":55}},{"start":{"line":44,"column":55},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":45},"4":{"loc":{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"5":{"loc":{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":64},"6":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":48}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":22}},{"start":{"line":64,"column":22},"end":{"line":64,"column":40}},{"start":{"line":64,"column":40},"end":{"line":64,"column":48}}],"line":64}},"s":{"0":7,"1":7,"2":7,"3":2,"4":5,"5":5,"6":5,"7":49,"8":5,"9":5,"10":1,"11":5,"12":5,"13":7,"14":0,"15":5,"16":5,"17":0,"18":5,"19":4,"20":5},"f":{"0":7,"1":49},"b":{"0":[2,5],"1":[1,4],"2":[5,0],"3":[0,7],"4":[0,5],"5":[4,1],"6":[5,4,4]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":21,"seen":{"f:20:22:20:Infinity":0,"s:23:37:23:Infinity":0,"s:24:19:24:Infinity":1,"b:25:2:25:Infinity:undefined:undefined:undefined:undefined":0,"s:25:2:25:Infinity":2,"s:25:29:25:Infinity":3,"s:27:18:27:Infinity":4,"s:29:20:29:Infinity":5,"s:30:18:30:Infinity":6,"f:30:38:30:46":1,"s:30:55:30:75":7,"s:31:18:31:Infinity":8,"b:32:2:39:Infinity:undefined:undefined:undefined:undefined":1,"s:32:2:39:Infinity":9,"s:33:4:38:Infinity":10,"s:41:22:43:Infinity":11,"s:44:20:44:Infinity":12,"b:44:34:44:55:44:55:44:Infinity":2,"b:45:2:52:Infinity:undefined:undefined:undefined:undefined":3,"s:45:2:52:Infinity":13,"s:46:4:51:Infinity":14,"s:54:17:54:Infinity":15,"b:55:2:62:Infinity:undefined:undefined:undefined:undefined":4,"s:55:2:62:Infinity":16,"s:56:4:61:Infinity":17,"b:64:2:71:Infinity:undefined:undefined:undefined:undefined":5,"s:64:2:71:Infinity":18,"b:64:6:64:22:64:22:64:40:64:40:64:48":6,"s:65:4:70:Infinity":19,"s:73:2:73:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/mermaid-diagrams.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/mermaid-diagrams.ts","statementMap":{"0":{"start":{"line":24,"column":37},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":63,"column":null}},"2":{"start":{"line":27,"column":21},"end":{"line":27,"column":null}},"3":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"4":{"start":{"line":28,"column":31},"end":{"line":28,"column":null}},"5":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"6":{"start":{"line":32,"column":23},"end":{"line":32,"column":null}},"7":{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},"8":{"start":{"line":34,"column":6},"end":{"line":39,"column":null}},"9":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"10":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"11":{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},"12":{"start":{"line":49,"column":6},"end":{"line":54,"column":null}},"13":{"start":{"line":56,"column":6},"end":{"line":61,"column":null}},"14":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"checkMermaidDiagrams","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":23,"column":30},"end":{"line":66,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},{"start":{"line":46,"column":6},"end":{"line":46,"column":null}}],"line":44},"3":{"loc":{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":4},"end":{"line":62,"column":null}},{"start":{"line":55,"column":11},"end":{"line":62,"column":null}}],"line":48}},"s":{"0":7,"1":7,"2":112,"3":112,"4":76,"5":36,"6":36,"7":36,"8":1,"9":1,"10":35,"11":112,"12":1,"13":34,"14":7},"f":{"0":7},"b":{"0":[76,36],"1":[1,35],"2":[35,2,1],"3":[1,34]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":15,"seen":{"f:21:22:21:Infinity":0,"s:24:37:24:Infinity":0,"s:26:2:63:Infinity":1,"s:27:21:27:Infinity":2,"b:28:4:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:4:28:Infinity":3,"s:28:31:28:Infinity":4,"s:30:20:30:Infinity":5,"s:32:23:32:Infinity":6,"b:33:4:41:Infinity:undefined:undefined:undefined:undefined":1,"s:33:4:41:Infinity":7,"s:34:6:39:Infinity":8,"s:40:6:40:Infinity":9,"s:44:6:46:Infinity":10,"b:44:6:44:Infinity:45:6:45:Infinity:46:6:46:Infinity":2,"b:48:4:62:Infinity:55:11:62:Infinity":3,"s:48:4:62:Infinity":11,"s:49:6:54:Infinity":12,"s:56:6:61:Infinity":13,"s:65:2:65:Infinity":14}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/methodology-reflection.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/methodology-reflection.ts","statementMap":{"0":{"start":{"line":29,"column":37},"end":{"line":29,"column":null}},"1":{"start":{"line":30,"column":19},"end":{"line":30,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"3":{"start":{"line":31,"column":29},"end":{"line":31,"column":null}},"4":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"5":{"start":{"line":35,"column":28},"end":{"line":38,"column":null}},"6":{"start":{"line":39,"column":28},"end":{"line":42,"column":null}},"7":{"start":{"line":43,"column":23},"end":{"line":43,"column":null}},"8":{"start":{"line":47,"column":35},"end":{"line":58,"column":null}},"9":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"10":{"start":{"line":48,"column":38},"end":{"line":48,"column":null}},"11":{"start":{"line":49,"column":18},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":4},"end":{"line":56,"column":null}},"13":{"start":{"line":61,"column":25},"end":{"line":63,"column":null}},"14":{"start":{"line":63,"column":22},"end":{"line":63,"column":59}},"15":{"start":{"line":64,"column":33},"end":{"line":64,"column":null}},"16":{"start":{"line":64,"column":62},"end":{"line":64,"column":75}},"17":{"start":{"line":65,"column":34},"end":{"line":67,"column":null}},"18":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"19":{"start":{"line":68,"column":32},"end":{"line":68,"column":null}},"20":{"start":{"line":72,"column":45},"end":{"line":74,"column":null}},"21":{"start":{"line":76,"column":76},"end":{"line":134,"column":null}},"22":{"start":{"line":136,"column":26},"end":{"line":138,"column":null}},"23":{"start":{"line":137,"column":29},"end":{"line":137,"column":37}},"24":{"start":{"line":138,"column":24},"end":{"line":138,"column":29}},"25":{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},"26":{"start":{"line":141,"column":4},"end":{"line":146,"column":null}},"27":{"start":{"line":148,"column":4},"end":{"line":153,"column":null}},"28":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"29":{"start":{"line":164,"column":26},"end":{"line":164,"column":null}},"30":{"start":{"line":165,"column":26},"end":{"line":167,"column":null}},"31":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"32":{"start":{"line":168,"column":29},"end":{"line":168,"column":null}},"33":{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},"34":{"start":{"line":170,"column":18},"end":{"line":173,"column":null}},"35":{"start":{"line":173,"column":21},"end":{"line":173,"column":46}},"36":{"start":{"line":174,"column":4},"end":{"line":176,"column":null}},"37":{"start":{"line":175,"column":6},"end":{"line":175,"column":null}},"38":{"start":{"line":178,"column":27},"end":{"line":180,"column":null}},"39":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"40":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"41":{"start":{"line":181,"column":37},"end":{"line":181,"column":null}},"42":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"43":{"start":{"line":182,"column":32},"end":{"line":182,"column":null}},"44":{"start":{"line":183,"column":2},"end":{"line":194,"column":null}},"45":{"start":{"line":184,"column":18},"end":{"line":184,"column":null}},"46":{"start":{"line":184,"column":57},"end":{"line":184,"column":65}},"47":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"48":{"start":{"line":186,"column":21},"end":{"line":186,"column":null}},"49":{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},"50":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"51":{"start":{"line":195,"column":2},"end":{"line":195,"column":null}}},"fnMap":{"0":{"name":"checkMethodologyReflection","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":null}},"loc":{"start":{"line":28,"column":30},"end":{"line":157,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":47,"column":60},"end":{"line":47,"column":66}},"loc":{"start":{"line":47,"column":75},"end":{"line":58,"column":3}},"line":47},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":13}},"loc":{"start":{"line":63,"column":22},"end":{"line":63,"column":59}},"line":63},"3":{"name":"(anonymous_3)","decl":{"start":{"line":64,"column":48},"end":{"line":64,"column":54}},"loc":{"start":{"line":64,"column":62},"end":{"line":64,"column":75}},"line":64},"4":{"name":"(anonymous_4)","decl":{"start":{"line":65,"column":49},"end":{"line":65,"column":55}},"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"line":66},"5":{"name":"(anonymous_5)","decl":{"start":{"line":137,"column":5},"end":{"line":137,"column":13}},"loc":{"start":{"line":137,"column":29},"end":{"line":137,"column":37}},"line":137},"6":{"name":"(anonymous_6)","decl":{"start":{"line":138,"column":5},"end":{"line":138,"column":10}},"loc":{"start":{"line":138,"column":24},"end":{"line":138,"column":29}},"line":138},"7":{"name":"checkConfidencePosteriorColumn","decl":{"start":{"line":163,"column":9},"end":{"line":163,"column":40}},"loc":{"start":{"line":163,"column":76},"end":{"line":196,"column":null}},"line":163},"8":{"name":"(anonymous_8)","decl":{"start":{"line":165,"column":42},"end":{"line":165,"column":null}},"loc":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"line":166},"9":{"name":"(anonymous_9)","decl":{"start":{"line":173,"column":7},"end":{"line":173,"column":12}},"loc":{"start":{"line":173,"column":21},"end":{"line":173,"column":46}},"line":173},"10":{"name":"(anonymous_10)","decl":{"start":{"line":174,"column":33},"end":{"line":174,"column":44}},"loc":{"start":{"line":175,"column":6},"end":{"line":175,"column":null}},"line":175},"11":{"name":"(anonymous_11)","decl":{"start":{"line":178,"column":43},"end":{"line":178,"column":51}},"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"line":179},"12":{"name":"(anonymous_12)","decl":{"start":{"line":184,"column":46},"end":{"line":184,"column":51}},"loc":{"start":{"line":184,"column":57},"end":{"line":184,"column":65}},"line":184}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":31},"1":{"loc":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":51,"column":6},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},{"start":{"line":54,"column":6},"end":{"line":54,"column":null}},{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{"line":56,"column":6},"end":{"line":56,"column":null}}],"line":51},"3":{"loc":{"start":{"line":91,"column":8},"end":{"line":93,"column":null}},"type":"binary-expr","locations":[{"start":{"line":91,"column":8},"end":{"line":91,"column":null}},{"start":{"line":92,"column":8},"end":{"line":92,"column":null}},{"start":{"line":93,"column":8},"end":{"line":93,"column":null}}],"line":91},"4":{"loc":{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":154,"column":null}},{"start":{"line":147,"column":9},"end":{"line":154,"column":null}}],"line":140},"5":{"loc":{"start":{"line":166,"column":14},"end":{"line":166,"column":null}},"type":"binary-expr","locations":[{"start":{"line":166,"column":14},"end":{"line":166,"column":45}},{"start":{"line":166,"column":45},"end":{"line":166,"column":null}}],"line":166},"6":{"loc":{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},"type":"if","locations":[{"start":{"line":169,"column":2},"end":{"line":177,"column":null}},{"start":{},"end":{}}],"line":169},"7":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"8":{"loc":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"9":{"loc":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":17},"end":{"line":185,"column":48}},{"start":{"line":185,"column":48},"end":{"line":185,"column":null}}],"line":185},"10":{"loc":{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":187,"column":4},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":187},"11":{"loc":{"start":{"line":188,"column":6},"end":{"line":190,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":6},"end":{"line":188,"column":null}},{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},{"start":{"line":190,"column":6},"end":{"line":190,"column":null}}],"line":188}},"s":{"0":13,"1":13,"2":13,"3":2,"4":11,"5":11,"6":11,"7":11,"8":11,"9":13,"10":5,"11":8,"12":8,"13":11,"14":65,"15":11,"16":26,"17":11,"18":26,"19":11,"20":11,"21":11,"22":13,"23":132,"24":26,"25":13,"26":6,"27":5,"28":11,"29":11,"30":11,"31":11,"32":11,"33":11,"34":9,"35":45,"36":9,"37":36,"38":11,"39":56,"40":11,"41":2,"42":9,"43":0,"44":9,"45":24,"46":120,"47":24,"48":24,"49":24,"50":2,"51":7},"f":{"0":13,"1":13,"2":65,"3":26,"4":26,"5":132,"6":26,"7":11,"8":11,"9":45,"10":36,"11":56,"12":120},"b":{"0":[2,11],"1":[5,8],"2":[8,8,8,8,8,8],"3":[11,9,8],"4":[6,5],"5":[11,9],"6":[9,2],"7":[2,9],"8":[0,9],"9":[24,0],"10":[2,22],"11":[24,23,22]},"meta":{"lastBranch":12,"lastFunction":13,"lastStatement":52,"seen":{"f:26:22:26:Infinity":0,"s:29:37:29:Infinity":0,"s:30:19:30:Infinity":1,"b:31:2:31:Infinity:undefined:undefined:undefined:undefined":0,"s:31:2:31:Infinity":2,"s:31:29:31:Infinity":3,"s:33:18:33:Infinity":4,"s:35:28:38:Infinity":5,"s:39:28:42:Infinity":6,"s:43:23:43:Infinity":7,"s:47:35:58:Infinity":8,"f:47:60:47:66":1,"b:48:4:48:Infinity:undefined:undefined:undefined:undefined":1,"s:48:4:48:Infinity":9,"s:48:38:48:Infinity":10,"s:49:18:49:Infinity":11,"s:50:4:56:Infinity":12,"b:51:6:51:Infinity:52:6:52:Infinity:53:6:53:Infinity:54:6:54:Infinity:55:6:55:Infinity:56:6:56:Infinity":2,"s:61:25:63:Infinity":13,"f:63:5:63:13":2,"s:63:22:63:59":14,"s:64:33:64:Infinity":15,"f:64:48:64:54":3,"s:64:62:64:75":16,"s:65:34:67:Infinity":17,"f:65:49:65:55":4,"s:66:4:66:Infinity":18,"s:68:32:68:Infinity":19,"s:72:45:74:Infinity":20,"s:76:76:134:Infinity":21,"b:91:8:91:Infinity:92:8:92:Infinity:93:8:93:Infinity":3,"s:136:26:138:Infinity":22,"f:137:5:137:13":5,"s:137:29:137:37":23,"f:138:5:138:10":6,"s:138:24:138:29":24,"b:140:2:154:Infinity:147:9:154:Infinity":4,"s:140:2:154:Infinity":25,"s:141:4:146:Infinity":26,"s:148:4:153:Infinity":27,"s:156:2:156:Infinity":28,"f:163:9:163:40":7,"s:164:26:164:Infinity":29,"s:165:26:167:Infinity":30,"f:165:42:165:Infinity":8,"s:166:14:166:Infinity":31,"b:166:14:166:45:166:45:166:Infinity":5,"s:168:29:168:Infinity":32,"b:169:2:177:Infinity:undefined:undefined:undefined:undefined":6,"s:169:2:177:Infinity":33,"s:170:18:173:Infinity":34,"f:173:7:173:12":9,"s:173:21:173:46":35,"s:174:4:176:Infinity":36,"f:174:33:174:44":10,"s:175:6:175:Infinity":37,"s:178:27:180:Infinity":38,"f:178:43:178:51":11,"s:179:4:179:Infinity":39,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":7,"s:181:2:181:Infinity":40,"s:181:37:181:Infinity":41,"b:182:2:182:Infinity:undefined:undefined:undefined:undefined":8,"s:182:2:182:Infinity":42,"s:182:32:182:Infinity":43,"s:183:2:194:Infinity":44,"s:184:18:184:Infinity":45,"f:184:46:184:51":12,"s:184:57:184:65":46,"s:185:17:185:Infinity":47,"b:185:17:185:48:185:48:185:Infinity":9,"s:186:21:186:Infinity":48,"b:187:4:193:Infinity:undefined:undefined:undefined:undefined":10,"s:187:4:193:Infinity":49,"b:188:6:188:Infinity:189:6:189:Infinity:190:6:190:Infinity":11,"s:192:6:192:Infinity":50,"s:195:2:195:Infinity":51}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/no-stubs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/no-stubs.ts","statementMap":{"0":{"start":{"line":27,"column":37},"end":{"line":27,"column":null}},"1":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":44,"column":null}},"3":{"start":{"line":32,"column":21},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"5":{"start":{"line":34,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},"7":{"start":{"line":36,"column":8},"end":{"line":41,"column":null}},"8":{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},"9":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"10":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}}},"fnMap":{"0":{"name":"checkNoStubs","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":35}},"loc":{"start":{"line":26,"column":84},"end":{"line":55,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":6},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":35},"1":{"loc":{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":46}},"s":{"0":8,"1":8,"2":8,"3":100,"4":100,"5":100,"6":400,"7":6,"8":8,"9":4,"10":8},"f":{"0":8},"b":{"0":[6,394],"1":[4,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":11,"seen":{"f:26:22:26:35":0,"s:27:37:27:Infinity":0,"s:29:18:29:Infinity":1,"s:31:2:44:Infinity":2,"s:32:21:32:Infinity":3,"s:33:20:33:Infinity":4,"s:34:4:43:Infinity":5,"b:35:6:42:Infinity:undefined:undefined:undefined:undefined":0,"s:35:6:42:Infinity":6,"s:36:8:41:Infinity":7,"b:46:2:52:Infinity:undefined:undefined:undefined:undefined":1,"s:46:2:52:Infinity":8,"s:47:4:51:Infinity":9,"s:54:2:54:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pass2-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pass2-evidence.ts","statementMap":{"0":{"start":{"line":25,"column":40},"end":{"line":25,"column":null}},"1":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":79,"column":null}},"4":{"start":{"line":39,"column":21},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"6":{"start":{"line":40,"column":31},"end":{"line":40,"column":null}},"7":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"8":{"start":{"line":44,"column":22},"end":{"line":44,"column":null}},"9":{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},"10":{"start":{"line":46,"column":34},"end":{"line":49,"column":null}},"11":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"12":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"13":{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":26},"end":{"line":57,"column":null}},"16":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"17":{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},"18":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"19":{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},"20":{"start":{"line":65,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":72,"column":6},"end":{"line":77,"column":null}},"22":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}}},"fnMap":{"0":{"name":"checkPass2Evidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":82,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":6},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":59,"column":10},"end":{"line":59,"column":80}},"type":"binary-expr","locations":[{"start":{"line":59,"column":10},"end":{"line":59,"column":29}},{"start":{"line":59,"column":29},"end":{"line":59,"column":80}}],"line":59},"6":{"loc":{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":78,"column":null}},{"start":{"line":71,"column":11},"end":{"line":78,"column":null}}],"line":64}},"s":{"0":2,"1":7,"2":7,"3":7,"4":154,"5":154,"6":107,"7":47,"8":47,"9":47,"10":47,"11":47,"12":45,"13":47,"14":2,"15":2,"16":2,"17":2,"18":0,"19":47,"20":2,"21":45,"22":7},"f":{"0":7},"b":{"0":[107,47],"1":[47,0],"2":[45,2],"3":[2,45],"4":[0,2],"5":[2,2],"6":[2,45]},"meta":{"lastBranch":7,"lastFunction":1,"lastStatement":23,"seen":{"s:25:40:25:Infinity":0,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":1,"s:36:19:36:Infinity":2,"s:38:2:79:Infinity":3,"s:39:21:39:Infinity":4,"b:40:4:40:Infinity:undefined:undefined:undefined:undefined":0,"s:40:4:40:Infinity":5,"s:40:31:40:Infinity":6,"s:42:20:42:Infinity":7,"s:44:22:44:Infinity":8,"b:45:4:53:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:53:Infinity":9,"s:46:34:49:Infinity":10,"b:50:6:52:Infinity:undefined:undefined:undefined:undefined":2,"s:50:6:52:Infinity":11,"s:51:8:51:Infinity":12,"b:55:4:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:4:62:Infinity":13,"s:56:23:56:Infinity":14,"s:57:26:57:Infinity":15,"s:58:22:58:Infinity":16,"b:59:6:61:Infinity:undefined:undefined:undefined:undefined":4,"s:59:6:61:Infinity":17,"b:59:10:59:29:59:29:59:80":5,"s:60:8:60:Infinity":18,"b:64:4:78:Infinity:71:11:78:Infinity":6,"s:64:4:78:Infinity":19,"s:65:6:70:Infinity":20,"s:72:6:77:Infinity":21,"s:81:2:81:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pir-status.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/pir-status.ts","statementMap":{"0":{"start":{"line":37,"column":27},"end":{"line":39,"column":null}},"1":{"start":{"line":41,"column":32},"end":{"line":43,"column":null}},"2":{"start":{"line":45,"column":23},"end":{"line":45,"column":null}},"3":{"start":{"line":51,"column":37},"end":{"line":51,"column":null}},"4":{"start":{"line":52,"column":19},"end":{"line":52,"column":null}},"5":{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},"6":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"7":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":74,"column":null}},"9":{"start":{"line":65,"column":16},"end":{"line":65,"column":null}},"10":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"11":{"start":{"line":68,"column":4},"end":{"line":72,"column":null}},"12":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"13":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"14":{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},"15":{"start":{"line":79,"column":4},"end":{"line":83,"column":null}},"16":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"17":{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},"18":{"start":{"line":88,"column":4},"end":{"line":92,"column":null}},"19":{"start":{"line":95,"column":2},"end":{"line":97,"column":null}},"20":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"21":{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},"22":{"start":{"line":100,"column":4},"end":{"line":104,"column":null}},"23":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"24":{"start":{"line":111,"column":25},"end":{"line":111,"column":null}},"25":{"start":{"line":112,"column":2},"end":{"line":120,"column":null}},"26":{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},"27":{"start":{"line":114,"column":6},"end":{"line":118,"column":null}},"28":{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},"29":{"start":{"line":123,"column":4},"end":{"line":127,"column":null}},"30":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"31":{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},"32":{"start":{"line":135,"column":4},"end":{"line":139,"column":null}},"33":{"start":{"line":142,"column":2},"end":{"line":150,"column":null}},"34":{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},"35":{"start":{"line":144,"column":6},"end":{"line":148,"column":null}},"36":{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},"37":{"start":{"line":153,"column":4},"end":{"line":157,"column":null}},"38":{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},"39":{"start":{"line":161,"column":4},"end":{"line":165,"column":null}},"40":{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},"41":{"start":{"line":169,"column":4},"end":{"line":173,"column":null}},"42":{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},"43":{"start":{"line":176,"column":4},"end":{"line":180,"column":null}}},"fnMap":{"0":{"name":"checkPirStatus","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":37}},"loc":{"start":{"line":50,"column":86},"end":{"line":108,"column":null}},"line":50},"1":{"name":"validateTopLevel","decl":{"start":{"line":110,"column":9},"end":{"line":110,"column":26}},"loc":{"start":{"line":110,"column":81},"end":{"line":129,"column":null}},"line":110},"2":{"name":"validatePirEntry","decl":{"start":{"line":131,"column":9},"end":{"line":131,"column":26}},"loc":{"start":{"line":131,"column":75},"end":{"line":182,"column":null}},"line":131}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":54},"1":{"loc":{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":2},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":78},"2":{"loc":{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":87},"3":{"loc":{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":105,"column":null}},{"start":{},"end":{}}],"line":99},"4":{"loc":{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":4},"end":{"line":119,"column":null}},{"start":{},"end":{}}],"line":113},"5":{"loc":{"start":{"line":113,"column":8},"end":{"line":113,"column":78}},"type":"binary-expr","locations":[{"start":{"line":113,"column":8},"end":{"line":113,"column":28}},{"start":{"line":113,"column":28},"end":{"line":113,"column":78}}],"line":113},"6":{"loc":{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":2},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":122},"7":{"loc":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"type":"binary-expr","locations":[{"start":{"line":132,"column":14},"end":{"line":132,"column":28}},{"start":{"line":132,"column":28},"end":{"line":132,"column":null}}],"line":132},"8":{"loc":{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":134},"9":{"loc":{"start":{"line":134,"column":6},"end":{"line":134,"column":55}},"type":"binary-expr","locations":[{"start":{"line":134,"column":6},"end":{"line":134,"column":21}},{"start":{"line":134,"column":21},"end":{"line":134,"column":55}}],"line":134},"10":{"loc":{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":4},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":143},"11":{"loc":{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":158,"column":null}},{"start":{},"end":{}}],"line":152},"12":{"loc":{"start":{"line":152,"column":6},"end":{"line":152,"column":57}},"type":"binary-expr","locations":[{"start":{"line":152,"column":6},"end":{"line":152,"column":20}},{"start":{"line":152,"column":20},"end":{"line":152,"column":57}}],"line":152},"13":{"loc":{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":2},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":160},"14":{"loc":{"start":{"line":160,"column":6},"end":{"line":160,"column":70}},"type":"binary-expr","locations":[{"start":{"line":160,"column":6},"end":{"line":160,"column":24}},{"start":{"line":160,"column":24},"end":{"line":160,"column":70}}],"line":160},"15":{"loc":{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":2},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":168},"16":{"loc":{"start":{"line":168,"column":6},"end":{"line":168,"column":56}},"type":"binary-expr","locations":[{"start":{"line":168,"column":6},"end":{"line":168,"column":35}},{"start":{"line":168,"column":35},"end":{"line":168,"column":56}}],"line":168},"17":{"loc":{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":175},"18":{"loc":{"start":{"line":175,"column":6},"end":{"line":175,"column":69}},"type":"binary-expr","locations":[{"start":{"line":175,"column":6},"end":{"line":175,"column":35}},{"start":{"line":175,"column":35},"end":{"line":175,"column":69}}],"line":175}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":12,"6":2,"7":2,"8":10,"9":10,"10":10,"11":1,"12":1,"13":9,"14":9,"15":0,"16":0,"17":9,"18":1,"19":9,"20":7,"21":9,"22":4,"23":9,"24":9,"25":9,"26":54,"27":0,"28":9,"29":1,"30":7,"31":7,"32":1,"33":7,"34":21,"35":1,"36":7,"37":1,"38":7,"39":1,"40":7,"41":1,"42":7,"43":1},"f":{"0":12,"1":9,"2":7},"b":{"0":[2,10],"1":[0,9],"2":[1,8],"3":[4,5],"4":[0,54],"5":[54,54],"6":[1,8],"7":[7,0],"8":[1,6],"9":[7,7],"10":[1,20],"11":[1,6],"12":[7,7],"13":[1,6],"14":[7,7],"15":[1,6],"16":[7,2],"17":[1,6],"18":[7,5]},"meta":{"lastBranch":19,"lastFunction":3,"lastStatement":44,"seen":{"s:37:27:39:Infinity":0,"s:41:32:43:Infinity":1,"s:45:23:45:Infinity":2,"f:50:22:50:37":0,"s:51:37:51:Infinity":3,"s:52:19:52:Infinity":4,"b:54:2:61:Infinity:undefined:undefined:undefined:undefined":0,"s:54:2:61:Infinity":5,"s:55:4:59:Infinity":6,"s:60:4:60:Infinity":7,"s:64:2:74:Infinity":8,"s:65:16:65:Infinity":9,"s:66:4:66:Infinity":10,"s:68:4:72:Infinity":11,"s:73:4:73:Infinity":12,"s:76:2:76:Infinity":13,"b:78:2:85:Infinity:undefined:undefined:undefined:undefined":1,"s:78:2:85:Infinity":14,"s:79:4:83:Infinity":15,"s:84:4:84:Infinity":16,"b:87:2:93:Infinity:undefined:undefined:undefined:undefined":2,"s:87:2:93:Infinity":17,"s:88:4:92:Infinity":18,"s:95:2:97:Infinity":19,"s:96:4:96:Infinity":20,"b:99:2:105:Infinity:undefined:undefined:undefined:undefined":3,"s:99:2:105:Infinity":21,"s:100:4:104:Infinity":22,"s:107:2:107:Infinity":23,"f:110:9:110:26":1,"s:111:25:111:Infinity":24,"s:112:2:120:Infinity":25,"b:113:4:119:Infinity:undefined:undefined:undefined:undefined":4,"s:113:4:119:Infinity":26,"b:113:8:113:28:113:28:113:78":5,"s:114:6:118:Infinity":27,"b:122:2:128:Infinity:undefined:undefined:undefined:undefined":6,"s:122:2:128:Infinity":28,"s:123:4:127:Infinity":29,"f:131:9:131:26":2,"s:132:14:132:Infinity":30,"b:132:14:132:28:132:28:132:Infinity":7,"b:134:2:140:Infinity:undefined:undefined:undefined:undefined":8,"s:134:2:140:Infinity":31,"b:134:6:134:21:134:21:134:55":9,"s:135:4:139:Infinity":32,"s:142:2:150:Infinity":33,"b:143:4:149:Infinity:undefined:undefined:undefined:undefined":10,"s:143:4:149:Infinity":34,"s:144:6:148:Infinity":35,"b:152:2:158:Infinity:undefined:undefined:undefined:undefined":11,"s:152:2:158:Infinity":36,"b:152:6:152:20:152:20:152:57":12,"s:153:4:157:Infinity":37,"b:160:2:166:Infinity:undefined:undefined:undefined:undefined":13,"s:160:2:166:Infinity":38,"b:160:6:160:24:160:24:160:70":14,"s:161:4:165:Infinity":39,"b:168:2:174:Infinity:undefined:undefined:undefined:undefined":15,"s:168:2:174:Infinity":40,"b:168:6:168:35:168:35:168:56":16,"s:169:4:173:Infinity":41,"b:175:2:181:Infinity:undefined:undefined:undefined:undefined":17,"s:175:2:181:Infinity":42,"b:175:6:175:35:175:35:175:69":18,"s:176:4:180:Infinity":43}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/per-document-coverage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/per-document-coverage.ts","statementMap":{"0":{"start":{"line":27,"column":37},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"4":{"start":{"line":34,"column":18},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"6":{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"9":{"start":{"line":46,"column":23},"end":{"line":46,"column":null}},"10":{"start":{"line":47,"column":2},"end":{"line":57,"column":null}},"11":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"12":{"start":{"line":49,"column":4},"end":{"line":56,"column":null}},"13":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"14":{"start":{"line":66,"column":24},"end":{"line":66,"column":null}},"15":{"start":{"line":67,"column":18},"end":{"line":67,"column":null}},"16":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"17":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"18":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"19":{"start":{"line":77,"column":19},"end":{"line":82,"column":null}},"20":{"start":{"line":83,"column":2},"end":{"line":86,"column":null}},"21":{"start":{"line":84,"column":14},"end":{"line":84,"column":null}},"22":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}}},"fnMap":{"0":{"name":"checkPerDocumentCoverage","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":null}},"loc":{"start":{"line":26,"column":30},"end":{"line":60,"column":null}},"line":26},"1":{"name":"extractDokIds","decl":{"start":{"line":65,"column":16},"end":{"line":65,"column":30}},"loc":{"start":{"line":65,"column":57},"end":{"line":70,"column":null}},"line":65},"2":{"name":"hasDocumentAnalysis","decl":{"start":{"line":76,"column":9},"end":{"line":76,"column":29}},"loc":{"start":{"line":76,"column":75},"end":{"line":87,"column":null}},"line":76},"3":{"name":"(anonymous_3)","decl":{"start":{"line":83,"column":18},"end":{"line":83,"column":24}},"loc":{"start":{"line":83,"column":30},"end":{"line":86,"column":3}},"line":83}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"1":{"loc":{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":37},"2":{"loc":{"start":{"line":52,"column":15},"end":{"line":54,"column":null}},"type":"cond-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":null}},{"start":{"line":54,"column":10},"end":{"line":54,"column":null}}],"line":52},"3":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"4":{"loc":{"start":{"line":85,"column":11},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":11},"end":{"line":85,"column":28}},{"start":{"line":85,"column":28},"end":{"line":85,"column":null}}],"line":85}},"s":{"0":7,"1":7,"2":7,"3":2,"4":5,"5":5,"6":5,"7":1,"8":1,"9":4,"10":4,"11":9,"12":9,"13":4,"14":9,"15":9,"16":9,"17":3,"18":6,"19":9,"20":9,"21":22,"22":22},"f":{"0":7,"1":9,"2":9,"3":22},"b":{"0":[2,5],"1":[1,4],"2":[7,2],"3":[3,6],"4":[22,7]},"meta":{"lastBranch":5,"lastFunction":4,"lastStatement":23,"seen":{"f:24:22:24:Infinity":0,"s:27:37:27:Infinity":0,"s:28:23:28:Infinity":1,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:32:Infinity":2,"s:31:4:31:Infinity":3,"s:34:18:34:Infinity":4,"s:35:17:35:Infinity":5,"b:37:2:44:Infinity:undefined:undefined:undefined:undefined":1,"s:37:2:44:Infinity":6,"s:38:4:42:Infinity":7,"s:43:4:43:Infinity":8,"s:46:23:46:Infinity":9,"s:47:2:57:Infinity":10,"s:48:18:48:Infinity":11,"s:49:4:56:Infinity":12,"b:53:10:53:Infinity:54:10:54:Infinity":2,"s:59:2:59:Infinity":13,"f:65:16:65:30":1,"s:66:24:66:Infinity":14,"s:67:18:67:Infinity":15,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":3,"s:68:2:68:Infinity":16,"s:68:16:68:Infinity":17,"s:69:2:69:Infinity":18,"f:76:9:76:29":2,"s:77:19:82:Infinity":19,"s:83:2:86:Infinity":20,"f:83:18:83:24":3,"s:84:14:84:Infinity":21,"s:85:4:85:Infinity":22,"b:85:11:85:28:85:28:85:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/scenario-analysis.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/scenario-analysis.ts","statementMap":{"0":{"start":{"line":22,"column":37},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":19},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":24,"column":29},"end":{"line":24,"column":null}},"4":{"start":{"line":26,"column":18},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":26},"end":{"line":27,"column":null}},"6":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"7":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"8":{"start":{"line":31,"column":4},"end":{"line":36,"column":null}},"9":{"start":{"line":38,"column":4},"end":{"line":43,"column":null}},"10":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"checkScenarioAnalysis","decl":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"loc":{"start":{"line":21,"column":30},"end":{"line":47,"column":null}},"line":21}},"branchMap":{"0":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":24},"1":{"loc":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"type":"cond-expr","locations":[{"start":{"line":28,"column":34},"end":{"line":28,"column":59}},{"start":{"line":28,"column":59},"end":{"line":28,"column":null}}],"line":28},"2":{"loc":{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":44,"column":null}},{"start":{"line":37,"column":9},"end":{"line":44,"column":null}}],"line":30}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":7,"8":2,"9":4,"10":6},"f":{"0":7},"b":{"0":[1,6],"1":[6,0],"2":[2,4]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":11,"seen":{"f:19:22:19:Infinity":0,"s:22:37:22:Infinity":0,"s:23:19:23:Infinity":1,"b:24:2:24:Infinity:undefined:undefined:undefined:undefined":0,"s:24:2:24:Infinity":2,"s:24:29:24:Infinity":3,"s:26:18:26:Infinity":4,"s:27:26:27:Infinity":5,"s:28:16:28:Infinity":6,"b:28:34:28:59:28:59:28:Infinity":1,"b:30:2:44:Infinity:37:9:44:Infinity":2,"s:30:2:44:Infinity":7,"s:31:4:36:Infinity":8,"s:38:4:43:Infinity":9,"s:46:2:46:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/significance-scoring.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/significance-scoring.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":25,"column":24},"end":{"line":25,"column":null}},"2":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":37,"column":29},"end":{"line":37,"column":null}},"6":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"7":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"8":{"start":{"line":41,"column":18},"end":{"line":41,"column":null}},"9":{"start":{"line":42,"column":22},"end":{"line":42,"column":null}},"10":{"start":{"line":44,"column":2},"end":{"line":96,"column":null}},"11":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"12":{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},"13":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"14":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"15":{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},"16":{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},"17":{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},"18":{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},"19":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"20":{"start":{"line":56,"column":44},"end":{"line":56,"column":null}},"21":{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},"22":{"start":{"line":58,"column":8},"end":{"line":63,"column":null}},"23":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"24":{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},"25":{"start":{"line":69,"column":6},"end":{"line":69,"column":null}},"26":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"27":{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},"28":{"start":{"line":74,"column":6},"end":{"line":79,"column":null}},"29":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"30":{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},"31":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"32":{"start":{"line":84,"column":35},"end":{"line":84,"column":null}},"33":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"34":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"35":{"start":{"line":86,"column":31},"end":{"line":86,"column":null}},"36":{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},"37":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"38":{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},"39":{"start":{"line":99,"column":4},"end":{"line":104,"column":null}},"40":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}}},"fnMap":{"0":{"name":"checkSignificanceScoringEvidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":108,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":50,"column":8},"end":{"line":50,"column":44}},"type":"binary-expr","locations":[{"start":{"line":50,"column":8},"end":{"line":50,"column":21}},{"start":{"line":50,"column":21},"end":{"line":50,"column":44}}],"line":50},"4":{"loc":{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":55},"5":{"loc":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":6},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":57},"7":{"loc":{"start":{"line":57,"column":10},"end":{"line":57,"column":70}},"type":"binary-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":40}},{"start":{"line":57,"column":40},"end":{"line":57,"column":70}}],"line":57},"8":{"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":68},"9":{"loc":{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":73},"10":{"loc":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"type":"binary-expr","locations":[{"start":{"line":73,"column":8},"end":{"line":73,"column":50}},{"start":{"line":73,"column":50},"end":{"line":73,"column":80}}],"line":73},"11":{"loc":{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":83},"12":{"loc":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"13":{"loc":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"14":{"loc":{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":6},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":87},"15":{"loc":{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":2},"end":{"line":105,"column":null}},{"start":{},"end":{}}],"line":98}},"s":{"0":3,"1":3,"2":8,"3":8,"4":8,"5":3,"6":5,"7":5,"8":5,"9":5,"10":5,"11":47,"12":2,"13":2,"14":2,"15":45,"16":2,"17":2,"18":43,"19":6,"20":4,"21":2,"22":0,"23":2,"24":37,"25":14,"26":14,"27":23,"28":2,"29":2,"30":21,"31":8,"32":2,"33":6,"34":6,"35":2,"36":4,"37":0,"38":5,"39":3,"40":5},"f":{"0":8},"b":{"0":[3,5],"1":[2,45],"2":[2,43],"3":[45,8],"4":[6,37],"5":[4,2],"6":[0,2],"7":[2,2],"8":[14,23],"9":[2,21],"10":[23,10],"11":[8,13],"12":[2,6],"13":[2,4],"14":[0,4],"15":[3,2]},"meta":{"lastBranch":16,"lastFunction":1,"lastStatement":41,"seen":{"s:23:2:23:Infinity":0,"s:25:24:25:Infinity":1,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":2,"s:36:19:36:Infinity":3,"b:37:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:2:37:Infinity":4,"s:37:29:37:Infinity":5,"s:39:18:39:Infinity":6,"s:40:16:40:Infinity":7,"s:41:18:41:Infinity":8,"s:42:22:42:Infinity":9,"s:44:2:96:Infinity":10,"b:45:4:49:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:49:Infinity":11,"s:46:6:46:Infinity":12,"s:47:6:47:Infinity":13,"s:48:6:48:Infinity":14,"b:50:4:53:Infinity:undefined:undefined:undefined:undefined":2,"s:50:4:53:Infinity":15,"b:50:8:50:21:50:21:50:44":3,"s:51:6:51:Infinity":16,"s:52:6:52:Infinity":17,"b:55:4:66:Infinity:undefined:undefined:undefined:undefined":4,"s:55:4:66:Infinity":18,"b:56:6:56:Infinity:undefined:undefined:undefined:undefined":5,"s:56:6:56:Infinity":19,"s:56:44:56:Infinity":20,"b:57:6:64:Infinity:undefined:undefined:undefined:undefined":6,"s:57:6:64:Infinity":21,"b:57:10:57:40:57:40:57:70":7,"s:58:8:63:Infinity":22,"s:65:6:65:Infinity":23,"b:68:4:71:Infinity:undefined:undefined:undefined:undefined":8,"s:68:4:71:Infinity":24,"s:69:6:69:Infinity":25,"s:70:6:70:Infinity":26,"b:73:4:81:Infinity:undefined:undefined:undefined:undefined":9,"s:73:4:81:Infinity":27,"b:73:8:73:50:73:50:73:80":10,"s:74:6:79:Infinity":28,"s:80:6:80:Infinity":29,"b:83:4:95:Infinity:undefined:undefined:undefined:undefined":11,"s:83:4:95:Infinity":30,"b:84:6:84:Infinity:undefined:undefined:undefined:undefined":12,"s:84:6:84:Infinity":31,"s:84:35:84:Infinity":32,"s:85:6:85:Infinity":33,"b:86:6:86:Infinity:undefined:undefined:undefined:undefined":13,"s:86:6:86:Infinity":34,"s:86:31:86:Infinity":35,"b:87:6:94:Infinity:undefined:undefined:undefined:undefined":14,"s:87:6:94:Infinity":36,"s:88:8:93:Infinity":37,"b:98:2:105:Infinity:undefined:undefined:undefined:undefined":15,"s:98:2:105:Infinity":38,"s:99:4:104:Infinity":39,"s:107:2:107:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/swot-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/swot-evidence.ts","statementMap":{"0":{"start":{"line":26,"column":24},"end":{"line":26,"column":null}},"1":{"start":{"line":35,"column":37},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"3":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"4":{"start":{"line":37,"column":29},"end":{"line":37,"column":null}},"5":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"6":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":22},"end":{"line":42,"column":null}},"9":{"start":{"line":44,"column":2},"end":{"line":87,"column":null}},"10":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"11":{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},"12":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"13":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"14":{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},"15":{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},"16":{"start":{"line":52,"column":6},"end":{"line":52,"column":null}},"17":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"18":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"19":{"start":{"line":55,"column":25},"end":{"line":55,"column":null}},"20":{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},"21":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"22":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"23":{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},"24":{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},"25":{"start":{"line":64,"column":8},"end":{"line":69,"column":null}},"26":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"27":{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},"28":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"29":{"start":{"line":75,"column":35},"end":{"line":75,"column":null}},"30":{"start":{"line":76,"column":6},"end":{"line":76,"column":null}},"31":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"32":{"start":{"line":77,"column":31},"end":{"line":77,"column":null}},"33":{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},"34":{"start":{"line":79,"column":8},"end":{"line":84,"column":null}},"35":{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},"36":{"start":{"line":90,"column":4},"end":{"line":95,"column":null}},"37":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"checkSwotEvidence","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":34,"column":30},"end":{"line":99,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":4},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":50},"3":{"loc":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":57},"5":{"loc":{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":62},"6":{"loc":{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":6},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":63},"7":{"loc":{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":74},"8":{"loc":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":75},"9":{"loc":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":77},"10":{"loc":{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":6},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":78},"11":{"loc":{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":89}},"s":{"0":3,"1":8,"2":8,"3":8,"4":3,"5":5,"6":5,"7":5,"8":5,"9":5,"10":73,"11":14,"12":14,"13":14,"14":59,"15":5,"16":5,"17":5,"18":54,"19":5,"20":49,"21":17,"22":17,"23":32,"24":22,"25":2,"26":22,"27":10,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":5,"36":3,"37":5},"f":{"0":8},"b":{"0":[3,5],"1":[14,59],"2":[5,54],"3":[5,49],"4":[17,32],"5":[22,10],"6":[2,20],"7":[0,10],"8":[0,0],"9":[0,0],"10":[0,0],"11":[3,2]},"meta":{"lastBranch":12,"lastFunction":1,"lastStatement":38,"seen":{"s:26:24:26:Infinity":0,"f:32:22:32:Infinity":0,"s:35:37:35:Infinity":1,"s:36:19:36:Infinity":2,"b:37:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:2:37:Infinity":3,"s:37:29:37:Infinity":4,"s:39:18:39:Infinity":5,"s:40:16:40:Infinity":6,"s:41:23:41:Infinity":7,"s:42:22:42:Infinity":8,"s:44:2:87:Infinity":9,"b:45:4:49:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:49:Infinity":10,"s:46:6:46:Infinity":11,"s:47:6:47:Infinity":12,"s:48:6:48:Infinity":13,"b:50:4:54:Infinity:undefined:undefined:undefined:undefined":2,"s:50:4:54:Infinity":14,"s:51:6:51:Infinity":15,"s:52:6:52:Infinity":16,"s:53:6:53:Infinity":17,"b:55:4:55:Infinity:undefined:undefined:undefined:undefined":3,"s:55:4:55:Infinity":18,"s:55:25:55:Infinity":19,"b:57:4:60:Infinity:undefined:undefined:undefined:undefined":4,"s:57:4:60:Infinity":20,"s:58:6:58:Infinity":21,"s:59:6:59:Infinity":22,"b:62:4:72:Infinity:undefined:undefined:undefined:undefined":5,"s:62:4:72:Infinity":23,"b:63:6:70:Infinity:undefined:undefined:undefined:undefined":6,"s:63:6:70:Infinity":24,"s:64:8:69:Infinity":25,"s:71:6:71:Infinity":26,"b:74:4:86:Infinity:undefined:undefined:undefined:undefined":7,"s:74:4:86:Infinity":27,"b:75:6:75:Infinity:undefined:undefined:undefined:undefined":8,"s:75:6:75:Infinity":28,"s:75:35:75:Infinity":29,"s:76:6:76:Infinity":30,"b:77:6:77:Infinity:undefined:undefined:undefined:undefined":9,"s:77:6:77:Infinity":31,"s:77:31:77:Infinity":32,"b:78:6:85:Infinity:undefined:undefined:undefined:undefined":10,"s:78:6:85:Infinity":33,"s:79:8:84:Infinity":34,"b:89:2:96:Infinity:undefined:undefined:undefined:undefined":11,"s:89:2:96:Infinity":35,"s:90:4:95:Infinity":36,"s:98:2:98:Infinity":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/statskontoret-evidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-checks/statskontoret-evidence.ts","statementMap":{"0":{"start":{"line":26,"column":37},"end":{"line":26,"column":null}},"1":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"2":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":28,"column":29},"end":{"line":28,"column":null}},"4":{"start":{"line":30,"column":18},"end":{"line":30,"column":null}},"5":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},"7":{"start":{"line":34,"column":4},"end":{"line":39,"column":null}},"8":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"9":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"10":{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},"11":{"start":{"line":47,"column":4},"end":{"line":52,"column":null}},"12":{"start":{"line":54,"column":4},"end":{"line":59,"column":null}},"13":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}}},"fnMap":{"0":{"name":"checkStatskontoretEvidence","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":25,"column":30},"end":{"line":63,"column":null}},"line":25}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":60,"column":null}},{"start":{"line":53,"column":9},"end":{"line":60,"column":null}}],"line":46}},"s":{"0":7,"1":7,"2":7,"3":1,"4":6,"5":6,"6":6,"7":3,"8":3,"9":3,"10":3,"11":1,"12":2,"13":3},"f":{"0":7},"b":{"0":[1,6],"1":[3,3],"2":[1,2]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":14,"seen":{"f:23:22:23:Infinity":0,"s:26:37:26:Infinity":0,"s:27:19:27:Infinity":1,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:28:Infinity":2,"s:28:29:28:Infinity":3,"s:30:18:30:Infinity":4,"s:32:24:32:Infinity":5,"b:33:2:41:Infinity:undefined:undefined:undefined:undefined":1,"s:33:2:41:Infinity":6,"s:34:4:39:Infinity":7,"s:40:4:40:Infinity":8,"s:44:4:44:Infinity":9,"b:46:2:60:Infinity:53:9:60:Infinity":2,"s:46:2:60:Infinity":10,"s:47:4:52:Infinity":11,"s:54:4:59:Infinity":12,"s:62:2:62:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/file-walkers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/file-walkers.ts","statementMap":{"0":{"start":{"line":25,"column":28},"end":{"line":25,"column":null}},"1":{"start":{"line":26,"column":21},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":18},"end":{"line":28,"column":null}},"5":{"start":{"line":29,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"7":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"8":{"start":{"line":32,"column":6},"end":{"line":32,"column":null}},"9":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"10":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"11":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}}},"fnMap":{"0":{"name":"collectMdFilesRecursive","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":24,"column":21},"end":{"line":38,"column":null}},"line":24}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":21},"end":{"line":26,"column":null}},"type":"cond-expr","locations":[{"start":{"line":26,"column":30},"end":{"line":26,"column":54}},{"start":{"line":26,"column":54},"end":{"line":26,"column":null}}],"line":26},"1":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},{"start":{},"end":{}}],"line":27},"2":{"loc":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":29},"end":{"line":30,"column":57}},{"start":{"line":30,"column":57},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},{"start":{"line":33,"column":11},"end":{"line":35,"column":null}}],"line":31},"4":{"loc":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33}},"s":{"0":19,"1":19,"2":19,"3":1,"4":18,"5":18,"6":117,"7":117,"8":7,"9":110,"10":106,"11":18},"f":{"0":19},"b":{"0":[8,11],"1":[1,18],"2":[54,63],"3":[7,110],"4":[106,4]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":12,"seen":{"f:21:22:21:Infinity":0,"s:25:28:25:Infinity":0,"s:26:21:26:Infinity":1,"b:26:30:26:54:26:54:26:Infinity":0,"b:27:2:27:Infinity:undefined:undefined:undefined:undefined":1,"s:27:2:27:Infinity":2,"s:27:31:27:Infinity":3,"s:28:18:28:Infinity":4,"s:29:2:36:Infinity":5,"s:30:20:30:Infinity":6,"b:30:29:30:57:30:57:30:Infinity":2,"b:31:4:35:Infinity:33:11:35:Infinity":3,"s:31:4:35:Infinity":7,"s:32:6:32:Infinity":8,"b:33:11:35:Infinity:undefined:undefined:undefined:undefined":4,"s:33:11:35:Infinity":9,"s:34:6:34:Infinity":10,"s:37:2:37:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/markdown-helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/agentic/gate-shared/markdown-helpers.ts","statementMap":{"0":{"start":{"line":17,"column":25},"end":{"line":17,"column":null}},"1":{"start":{"line":20,"column":28},"end":{"line":20,"column":null}},"2":{"start":{"line":23,"column":28},"end":{"line":23,"column":null}},"3":{"start":{"line":26,"column":30},"end":{"line":26,"column":null}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"6":{"start":{"line":38,"column":2},"end":{"line":50,"column":null}},"7":{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},"8":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"9":{"start":{"line":41,"column":6},"end":{"line":41,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"11":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"12":{"start":{"line":45,"column":8},"end":{"line":45,"column":null}},"13":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"15":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"16":{"start":{"line":63,"column":2},"end":{"line":69,"column":null}},"17":{"start":{"line":64,"column":25},"end":{"line":64,"column":null}},"18":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"19":{"start":{"line":65,"column":23},"end":{"line":65,"column":null}},"20":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"21":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"22":{"start":{"line":68,"column":28},"end":{"line":68,"column":null}},"23":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"24":{"start":{"line":79,"column":16},"end":{"line":79,"column":null}},"25":{"start":{"line":80,"column":18},"end":{"line":80,"column":null}},"26":{"start":{"line":81,"column":30},"end":{"line":81,"column":null}},"27":{"start":{"line":82,"column":2},"end":{"line":93,"column":null}},"28":{"start":{"line":83,"column":25},"end":{"line":83,"column":null}},"29":{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},"30":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"31":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"32":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"33":{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},"34":{"start":{"line":88,"column":8},"end":{"line":88,"column":null}},"35":{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},"36":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"37":{"start":{"line":92,"column":19},"end":{"line":92,"column":null}},"38":{"start":{"line":94,"column":2},"end":{"line":94,"column":null}}},"fnMap":{"0":{"name":"stripHeadingMarkup","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":58},"end":{"line":53,"column":null}},"line":34},"1":{"name":"hasHeading","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":27}},"loc":{"start":{"line":62,"column":70},"end":{"line":71,"column":null}},"line":62},"2":{"name":"extractSection","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":31}},"loc":{"start":{"line":78,"column":80},"end":{"line":95,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":43},"2":{"loc":{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":6},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":44},"3":{"loc":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"4":{"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"5":{"loc":{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":84},"6":{"loc":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"7":{"loc":{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":6},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":87},"8":{"loc":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92}},"s":{"0":10,"1":10,"2":10,"3":10,"4":29,"5":29,"6":29,"7":1453,"8":8,"9":8,"10":1445,"11":51,"12":8,"13":51,"14":1394,"15":29,"16":110,"17":1753,"18":1753,"19":1305,"20":448,"21":448,"22":91,"23":19,"24":42,"25":42,"26":42,"27":42,"28":675,"29":675,"30":159,"31":159,"32":29,"33":130,"34":35,"35":35,"36":611,"37":611,"38":42},"f":{"0":29,"1":110,"2":42},"b":{"0":[8,1445],"1":[51,1394],"2":[8,43],"3":[1305,448],"4":[91,357],"5":[159,516],"6":[29,130],"7":[35,95],"8":[196,415]},"meta":{"lastBranch":9,"lastFunction":3,"lastStatement":39,"seen":{"s:17:25:17:Infinity":0,"s:20:28:20:Infinity":1,"s:23:28:23:Infinity":2,"s:26:30:26:Infinity":3,"f:34:16:34:35":0,"s:35:13:35:Infinity":4,"s:36:18:36:Infinity":5,"s:38:2:50:Infinity":6,"b:39:4:42:Infinity:undefined:undefined:undefined:undefined":0,"s:39:4:42:Infinity":7,"s:40:6:40:Infinity":8,"s:41:6:41:Infinity":9,"b:43:4:48:Infinity:undefined:undefined:undefined:undefined":1,"s:43:4:48:Infinity":10,"b:44:6:46:Infinity:undefined:undefined:undefined:undefined":2,"s:44:6:46:Infinity":11,"s:45:8:45:Infinity":12,"s:47:6:47:Infinity":13,"s:49:4:49:Infinity":14,"s:52:2:52:Infinity":15,"f:62:16:62:27":1,"s:63:2:69:Infinity":16,"s:64:25:64:Infinity":17,"b:65:4:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:4:65:Infinity":18,"s:65:23:65:Infinity":19,"s:67:17:67:Infinity":20,"b:68:4:68:Infinity:undefined:undefined:undefined:undefined":4,"s:68:4:68:Infinity":21,"s:68:28:68:Infinity":22,"s:70:2:70:Infinity":23,"f:78:16:78:31":2,"s:79:16:79:Infinity":24,"s:80:18:80:Infinity":25,"s:81:30:81:Infinity":26,"s:82:2:93:Infinity":27,"s:83:25:83:Infinity":28,"b:84:4:91:Infinity:undefined:undefined:undefined:undefined":5,"s:84:4:91:Infinity":29,"s:85:19:85:Infinity":30,"b:86:6:86:Infinity:undefined:undefined:undefined:undefined":6,"s:86:6:86:Infinity":31,"s:86:21:86:Infinity":32,"b:87:6:90:Infinity:undefined:undefined:undefined:undefined":7,"s:87:6:90:Infinity":33,"s:88:8:88:Infinity":34,"s:89:8:89:Infinity":35,"b:92:4:92:Infinity:undefined:undefined:undefined:undefined":8,"s:92:4:92:Infinity":36,"s:92:19:92:Infinity":37,"s:94:2:94:Infinity":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/classifier.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/classifier.ts","statementMap":{"0":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"1":{"start":{"line":66,"column":12},"end":{"line":66,"column":null}},"2":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"3":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"4":{"start":{"line":70,"column":2},"end":{"line":75,"column":null}},"5":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"6":{"start":{"line":87,"column":33},"end":{"line":87,"column":null}},"7":{"start":{"line":88,"column":14},"end":{"line":88,"column":null}},"8":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"9":{"start":{"line":89,"column":27},"end":{"line":89,"column":null}},"10":{"start":{"line":90,"column":21},"end":{"line":94,"column":null}},"11":{"start":{"line":95,"column":2},"end":{"line":97,"column":null}},"12":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"13":{"start":{"line":96,"column":26},"end":{"line":96,"column":null}},"14":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"15":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"16":{"start":{"line":115,"column":47},"end":{"line":115,"column":null}},"17":{"start":{"line":117,"column":25},"end":{"line":117,"column":null}},"18":{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},"19":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"20":{"start":{"line":121,"column":4},"end":{"line":124,"column":null}},"21":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"22":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"23":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"24":{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},"25":{"start":{"line":133,"column":19},"end":{"line":133,"column":null}},"26":{"start":{"line":134,"column":30},"end":{"line":136,"column":null}},"27":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"28":{"start":{"line":137,"column":32},"end":{"line":139,"column":null}},"29":{"start":{"line":138,"column":13},"end":{"line":138,"column":null}},"30":{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},"31":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"32":{"start":{"line":142,"column":6},"end":{"line":147,"column":null}},"33":{"start":{"line":151,"column":2},"end":{"line":151,"column":null}},"34":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"35":{"start":{"line":159,"column":24},"end":{"line":163,"column":null}}},"fnMap":{"0":{"name":"parseArticleFilename","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":37}},"loc":{"start":{"line":64,"column":74},"end":{"line":76,"column":null}},"line":64},"1":{"name":"findAnalysisSource","decl":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"loc":{"start":{"line":86,"column":17},"end":{"line":99,"column":null}},"line":86},"2":{"name":"classify","decl":{"start":{"line":109,"column":16},"end":{"line":109,"column":null}},"loc":{"start":{"line":113,"column":24},"end":{"line":152,"column":null}},"line":113},"3":{"name":"(anonymous_3)","decl":{"start":{"line":134,"column":50},"end":{"line":134,"column":null}},"loc":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"line":135},"4":{"name":"(anonymous_4)","decl":{"start":{"line":137,"column":52},"end":{"line":137,"column":null}},"loc":{"start":{"line":138,"column":13},"end":{"line":138,"column":null}},"line":138},"5":{"name":"isKnownLang","decl":{"start":{"line":155,"column":16},"end":{"line":155,"column":28}},"loc":{"start":{"line":155,"column":60},"end":{"line":157,"column":null}},"line":155}},"branchMap":{"0":{"loc":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":67},"1":{"loc":{"start":{"line":72,"column":10},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":10},"end":{"line":72,"column":18}},{"start":{"line":72,"column":18},"end":{"line":72,"column":null}}],"line":72},"2":{"loc":{"start":{"line":73,"column":15},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":23}},{"start":{"line":73,"column":23},"end":{"line":73,"column":null}}],"line":73},"3":{"loc":{"start":{"line":74,"column":11},"end":{"line":74,"column":21}},"type":"binary-expr","locations":[{"start":{"line":74,"column":11},"end":{"line":74,"column":19}},{"start":{"line":74,"column":19},"end":{"line":74,"column":21}}],"line":74},"4":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"5":{"loc":{"start":{"line":87,"column":6},"end":{"line":87,"column":33}},"type":"binary-expr","locations":[{"start":{"line":87,"column":6},"end":{"line":87,"column":18}},{"start":{"line":87,"column":18},"end":{"line":87,"column":33}}],"line":87},"6":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"7":{"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"8":{"loc":{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":119},"9":{"loc":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":127},"10":{"loc":{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":2},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":132},"11":{"loc":{"start":{"line":135,"column":13},"end":{"line":135,"column":null}},"type":"binary-expr","locations":[{"start":{"line":135,"column":13},"end":{"line":135,"column":51}},{"start":{"line":135,"column":51},"end":{"line":135,"column":null}}],"line":135},"12":{"loc":{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":148,"column":null}},{"start":{},"end":{}}],"line":140},"13":{"loc":{"start":{"line":140,"column":8},"end":{"line":140,"column":50}},"type":"binary-expr","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":29}},{"start":{"line":140,"column":29},"end":{"line":140,"column":50}}],"line":140},"14":{"loc":{"start":{"line":145,"column":11},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":31},"end":{"line":145,"column":53}},{"start":{"line":145,"column":53},"end":{"line":145,"column":null}}],"line":145},"15":{"loc":{"start":{"line":146,"column":11},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":54},"end":{"line":146,"column":62}},{"start":{"line":146,"column":62},"end":{"line":146,"column":null}}],"line":146},"16":{"loc":{"start":{"line":146,"column":11},"end":{"line":146,"column":54}},"type":"binary-expr","locations":[{"start":{"line":146,"column":11},"end":{"line":146,"column":32}},{"start":{"line":146,"column":32},"end":{"line":146,"column":54}}],"line":146},"17":{"loc":{"start":{"line":147,"column":11},"end":{"line":147,"column":51}},"type":"cond-expr","locations":[{"start":{"line":147,"column":33},"end":{"line":147,"column":48}},{"start":{"line":147,"column":48},"end":{"line":147,"column":51}}],"line":147}},"s":{"0":30,"1":30,"2":30,"3":1,"4":29,"5":19,"6":0,"7":19,"8":19,"9":15,"10":4,"11":4,"12":4,"13":4,"14":0,"15":17,"16":17,"17":17,"18":17,"19":3,"20":3,"21":17,"22":14,"23":14,"24":17,"25":9,"26":9,"27":20,"28":9,"29":20,"30":9,"31":9,"32":9,"33":17,"34":19,"35":2},"f":{"0":30,"1":19,"2":17,"3":20,"4":20,"5":19},"b":{"0":[1,29],"1":[29,0],"2":[30,0],"3":[30,0],"4":[0,19],"5":[19,19],"6":[15,4],"7":[4,0],"8":[3,14],"9":[14,3],"10":[9,8],"11":[20,12],"12":[9,0],"13":[9,1],"14":[8,1],"15":[0,9],"16":[9,8],"17":[1,8]},"meta":{"lastBranch":18,"lastFunction":6,"lastStatement":36,"seen":{"f:64:16:64:37":0,"s:65:15:65:Infinity":0,"s:66:12:66:Infinity":1,"b:67:2:69:Infinity:undefined:undefined:undefined:undefined":0,"s:67:2:69:Infinity":2,"s:68:4:68:Infinity":3,"s:70:2:75:Infinity":4,"b:72:10:72:18:72:18:72:Infinity":1,"b:73:15:73:23:73:23:73:Infinity":2,"b:74:11:74:19:74:19:74:21":3,"f:83:16:83:Infinity":1,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":4,"s:87:2:87:Infinity":5,"b:87:6:87:18:87:18:87:33":5,"s:87:33:87:Infinity":6,"s:88:14:88:Infinity":7,"b:89:2:89:Infinity:undefined:undefined:undefined:undefined":6,"s:89:2:89:Infinity":8,"s:89:27:89:Infinity":9,"s:90:21:94:Infinity":10,"s:95:2:97:Infinity":11,"b:96:4:96:Infinity:undefined:undefined:undefined:undefined":7,"s:96:4:96:Infinity":12,"s:96:26:96:Infinity":13,"s:98:2:98:Infinity":14,"f:109:16:109:Infinity":2,"s:114:24:114:Infinity":15,"s:115:47:115:Infinity":16,"s:117:25:117:Infinity":17,"b:119:2:125:Infinity:undefined:undefined:undefined:undefined":8,"s:119:2:125:Infinity":18,"s:120:4:120:Infinity":19,"s:121:4:124:Infinity":20,"b:127:2:130:Infinity:undefined:undefined:undefined:undefined":9,"s:127:2:130:Infinity":21,"s:128:4:128:Infinity":22,"s:129:4:129:Infinity":23,"b:132:2:149:Infinity:undefined:undefined:undefined:undefined":10,"s:132:2:149:Infinity":24,"s:133:19:133:Infinity":25,"s:134:30:136:Infinity":26,"f:134:50:134:Infinity":3,"s:135:13:135:Infinity":27,"b:135:13:135:51:135:51:135:Infinity":11,"s:137:32:139:Infinity":28,"f:137:52:137:Infinity":4,"s:138:13:138:Infinity":29,"b:140:4:148:Infinity:undefined:undefined:undefined:undefined":12,"s:140:4:148:Infinity":30,"b:140:8:140:29:140:29:140:50":13,"s:141:6:141:Infinity":31,"s:142:6:147:Infinity":32,"b:145:31:145:53:145:53:145:Infinity":14,"b:146:54:146:62:146:62:146:Infinity":15,"b:146:11:146:32:146:32:146:54":16,"b:147:33:147:48:147:48:147:51":17,"s:151:2:151:Infinity":33,"f:155:16:155:28":5,"s:156:2:156:Infinity":34,"s:159:24:163:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/contract-checker.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/contract-checker.ts","statementMap":{"0":{"start":{"line":52,"column":33},"end":{"line":57,"column":null}},"1":{"start":{"line":60,"column":31},"end":{"line":65,"column":null}},"2":{"start":{"line":68,"column":31},"end":{"line":73,"column":null}},"3":{"start":{"line":76,"column":58},"end":{"line":92,"column":null}},"4":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"5":{"start":{"line":102,"column":55},"end":{"line":111,"column":null}},"6":{"start":{"line":115,"column":61},"end":{"line":128,"column":null}},"7":{"start":{"line":131,"column":27},"end":{"line":131,"column":null}},"8":{"start":{"line":137,"column":33},"end":{"line":137,"column":null}},"9":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"10":{"start":{"line":147,"column":38},"end":{"line":147,"column":null}},"11":{"start":{"line":152,"column":37},"end":{"line":152,"column":null}},"12":{"start":{"line":184,"column":14},"end":{"line":184,"column":null}},"13":{"start":{"line":185,"column":2},"end":{"line":185,"column":null}},"14":{"start":{"line":198,"column":42},"end":{"line":198,"column":null}},"15":{"start":{"line":199,"column":17},"end":{"line":199,"column":null}},"16":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"17":{"start":{"line":202,"column":22},"end":{"line":202,"column":null}},"18":{"start":{"line":204,"column":19},"end":{"line":204,"column":null}},"19":{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},"20":{"start":{"line":206,"column":4},"end":{"line":211,"column":null}},"21":{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},"22":{"start":{"line":214,"column":6},"end":{"line":219,"column":null}},"23":{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},"24":{"start":{"line":222,"column":6},"end":{"line":227,"column":null}},"25":{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},"26":{"start":{"line":232,"column":4},"end":{"line":237,"column":null}},"27":{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},"28":{"start":{"line":241,"column":4},"end":{"line":246,"column":null}},"29":{"start":{"line":249,"column":2},"end":{"line":259,"column":null}},"30":{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},"31":{"start":{"line":251,"column":6},"end":{"line":256,"column":null}},"32":{"start":{"line":257,"column":6},"end":{"line":257,"column":null}},"33":{"start":{"line":261,"column":22},"end":{"line":261,"column":null}},"34":{"start":{"line":262,"column":18},"end":{"line":262,"column":null}},"35":{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},"36":{"start":{"line":265,"column":4},"end":{"line":270,"column":null}},"37":{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},"38":{"start":{"line":273,"column":6},"end":{"line":278,"column":null}},"39":{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},"40":{"start":{"line":281,"column":6},"end":{"line":286,"column":null}},"41":{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},"42":{"start":{"line":290,"column":6},"end":{"line":295,"column":null}},"43":{"start":{"line":296,"column":23},"end":{"line":296,"column":null}},"44":{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},"45":{"start":{"line":298,"column":8},"end":{"line":303,"column":null}},"46":{"start":{"line":307,"column":4},"end":{"line":317,"column":null}},"47":{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},"48":{"start":{"line":309,"column":8},"end":{"line":314,"column":null}},"49":{"start":{"line":315,"column":8},"end":{"line":315,"column":null}},"50":{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},"51":{"start":{"line":320,"column":6},"end":{"line":325,"column":null}},"52":{"start":{"line":329,"column":2},"end":{"line":333,"column":null}},"53":{"start":{"line":336,"column":24},"end":{"line":341,"column":null}}},"fnMap":{"0":{"name":"visualLength","decl":{"start":{"line":97,"column":9},"end":{"line":97,"column":22}},"loc":{"start":{"line":97,"column":44},"end":{"line":99,"column":null}},"line":97},"1":{"name":"windowFor","decl":{"start":{"line":183,"column":16},"end":{"line":183,"column":26}},"loc":{"start":{"line":183,"column":52},"end":{"line":186,"column":null}},"line":183},"2":{"name":"checkAgainstContract","decl":{"start":{"line":194,"column":16},"end":{"line":194,"column":null}},"loc":{"start":{"line":197,"column":18},"end":{"line":334,"column":null}},"line":197}},"branchMap":{"0":{"loc":{"start":{"line":185,"column":9},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":9},"end":{"line":185,"column":30}},{"start":{"line":185,"column":30},"end":{"line":185,"column":null}}],"line":185},"1":{"loc":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"type":"binary-expr","locations":[{"start":{"line":201,"column":16},"end":{"line":201,"column":30}},{"start":{"line":201,"column":30},"end":{"line":201,"column":null}}],"line":201},"2":{"loc":{"start":{"line":202,"column":22},"end":{"line":202,"column":null}},"type":"binary-expr","locations":[{"start":{"line":202,"column":22},"end":{"line":202,"column":42}},{"start":{"line":202,"column":42},"end":{"line":202,"column":null}}],"line":202},"3":{"loc":{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},"type":"if","locations":[{"start":{"line":205,"column":2},"end":{"line":229,"column":null}},{"start":{"line":212,"column":9},"end":{"line":229,"column":null}}],"line":205},"4":{"loc":{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":213,"column":4},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":213},"5":{"loc":{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":221,"column":4},"end":{"line":228,"column":null}},{"start":{},"end":{}}],"line":221},"6":{"loc":{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},"type":"if","locations":[{"start":{"line":231,"column":2},"end":{"line":238,"column":null}},{"start":{},"end":{}}],"line":231},"7":{"loc":{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":247,"column":null}},{"start":{},"end":{}}],"line":240},"8":{"loc":{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},"type":"if","locations":[{"start":{"line":250,"column":4},"end":{"line":258,"column":null}},{"start":{},"end":{}}],"line":250},"9":{"loc":{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},"type":"if","locations":[{"start":{"line":264,"column":2},"end":{"line":327,"column":null}},{"start":{"line":271,"column":9},"end":{"line":327,"column":null}}],"line":264},"10":{"loc":{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},"type":"if","locations":[{"start":{"line":272,"column":4},"end":{"line":279,"column":null}},{"start":{},"end":{}}],"line":272},"11":{"loc":{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":4},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":280},"12":{"loc":{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},"type":"if","locations":[{"start":{"line":289,"column":4},"end":{"line":305,"column":null}},{"start":{},"end":{}}],"line":289},"13":{"loc":{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},"type":"if","locations":[{"start":{"line":297,"column":6},"end":{"line":304,"column":null}},{"start":{},"end":{}}],"line":297},"14":{"loc":{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},"type":"if","locations":[{"start":{"line":308,"column":6},"end":{"line":316,"column":null}},{"start":{},"end":{}}],"line":308},"15":{"loc":{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":4},"end":{"line":326,"column":null}},{"start":{},"end":{}}],"line":319}},"s":{"0":3,"1":3,"2":3,"3":3,"4":426,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":61,"13":61,"14":44,"15":44,"16":44,"17":44,"18":44,"19":44,"20":3,"21":41,"22":11,"23":41,"24":10,"25":44,"26":8,"27":44,"28":11,"29":44,"30":334,"31":3,"32":3,"33":44,"34":44,"35":44,"36":3,"37":41,"38":13,"39":41,"40":1,"41":41,"42":1,"43":1,"44":1,"45":1,"46":41,"47":465,"48":3,"49":3,"50":41,"51":1,"52":44,"53":3},"f":{"0":426,"1":61,"2":44},"b":{"0":[61,1],"1":[44,0],"2":[44,0],"3":[3,41],"4":[11,30],"5":[10,31],"6":[8,36],"7":[11,33],"8":[3,331],"9":[3,41],"10":[13,28],"11":[1,40],"12":[1,40],"13":[1,0],"14":[3,462],"15":[1,40]},"meta":{"lastBranch":16,"lastFunction":3,"lastStatement":54,"seen":{"s:52:33:57:Infinity":0,"s:60:31:65:Infinity":1,"s:68:31:73:Infinity":2,"s:76:58:92:Infinity":3,"f:97:9:97:22":0,"s:98:2:98:Infinity":4,"s:102:55:111:Infinity":5,"s:115:61:128:Infinity":6,"s:131:27:131:Infinity":7,"s:137:33:137:Infinity":8,"s:142:2:142:Infinity":9,"s:147:38:147:Infinity":10,"s:152:37:152:Infinity":11,"f:183:16:183:26":1,"s:184:14:184:Infinity":12,"s:185:2:185:Infinity":13,"b:185:9:185:30:185:30:185:Infinity":0,"f:194:16:194:Infinity":2,"s:198:42:198:Infinity":14,"s:199:17:199:Infinity":15,"s:201:16:201:Infinity":16,"b:201:16:201:30:201:30:201:Infinity":1,"s:202:22:202:Infinity":17,"b:202:22:202:42:202:42:202:Infinity":2,"s:204:19:204:Infinity":18,"b:205:2:229:Infinity:212:9:229:Infinity":3,"s:205:2:229:Infinity":19,"s:206:4:211:Infinity":20,"b:213:4:220:Infinity:undefined:undefined:undefined:undefined":4,"s:213:4:220:Infinity":21,"s:214:6:219:Infinity":22,"b:221:4:228:Infinity:undefined:undefined:undefined:undefined":5,"s:221:4:228:Infinity":23,"s:222:6:227:Infinity":24,"b:231:2:238:Infinity:undefined:undefined:undefined:undefined":6,"s:231:2:238:Infinity":25,"s:232:4:237:Infinity":26,"b:240:2:247:Infinity:undefined:undefined:undefined:undefined":7,"s:240:2:247:Infinity":27,"s:241:4:246:Infinity":28,"s:249:2:259:Infinity":29,"b:250:4:258:Infinity:undefined:undefined:undefined:undefined":8,"s:250:4:258:Infinity":30,"s:251:6:256:Infinity":31,"s:257:6:257:Infinity":32,"s:261:22:261:Infinity":33,"s:262:18:262:Infinity":34,"b:264:2:327:Infinity:271:9:327:Infinity":9,"s:264:2:327:Infinity":35,"s:265:4:270:Infinity":36,"b:272:4:279:Infinity:undefined:undefined:undefined:undefined":10,"s:272:4:279:Infinity":37,"s:273:6:278:Infinity":38,"b:280:4:287:Infinity:undefined:undefined:undefined:undefined":11,"s:280:4:287:Infinity":39,"s:281:6:286:Infinity":40,"b:289:4:305:Infinity:undefined:undefined:undefined:undefined":12,"s:289:4:305:Infinity":41,"s:290:6:295:Infinity":42,"s:296:23:296:Infinity":43,"b:297:6:304:Infinity:undefined:undefined:undefined:undefined":13,"s:297:6:304:Infinity":44,"s:298:8:303:Infinity":45,"s:307:4:317:Infinity":46,"b:308:6:316:Infinity:undefined:undefined:undefined:undefined":14,"s:308:6:316:Infinity":47,"s:309:8:314:Infinity":48,"s:315:8:315:Infinity":49,"b:319:4:326:Infinity:undefined:undefined:undefined:undefined":15,"s:319:4:326:Infinity":50,"s:320:6:325:Infinity":51,"s:329:2:333:Infinity":52,"s:336:24:341:Infinity":53}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/html-inspector.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/html-inspector.ts","statementMap":{"0":{"start":{"line":59,"column":16},"end":{"line":63,"column":null}},"1":{"start":{"line":69,"column":40},"end":{"line":76,"column":null}},"2":{"start":{"line":77,"column":2},"end":{"line":89,"column":null}},"3":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"4":{"start":{"line":79,"column":15},"end":{"line":79,"column":null}},"5":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"6":{"start":{"line":80,"column":15},"end":{"line":80,"column":null}},"7":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"8":{"start":{"line":81,"column":28},"end":{"line":81,"column":null}},"9":{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},"10":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"11":{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},"12":{"start":{"line":85,"column":10},"end":{"line":85,"column":null}},"13":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"14":{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},"15":{"start":{"line":98,"column":4},"end":{"line":98,"column":null}},"16":{"start":{"line":100,"column":2},"end":{"line":100,"column":null}},"17":{"start":{"line":107,"column":2},"end":{"line":113,"column":null}},"18":{"start":{"line":118,"column":12},"end":{"line":118,"column":null}},"19":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"20":{"start":{"line":127,"column":14},"end":{"line":127,"column":null}},"21":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"22":{"start":{"line":136,"column":14},"end":{"line":136,"column":null}},"23":{"start":{"line":137,"column":20},"end":{"line":137,"column":null}},"24":{"start":{"line":139,"column":2},"end":{"line":152,"column":null}},"25":{"start":{"line":140,"column":18},"end":{"line":140,"column":null}},"26":{"start":{"line":141,"column":20},"end":{"line":141,"column":null}},"27":{"start":{"line":142,"column":17},"end":{"line":142,"column":null}},"28":{"start":{"line":143,"column":21},"end":{"line":143,"column":null}},"29":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"30":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"31":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"32":{"start":{"line":146,"column":25},"end":{"line":146,"column":null}},"33":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"34":{"start":{"line":149,"column":18},"end":{"line":149,"column":null}},"35":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"36":{"start":{"line":150,"column":25},"end":{"line":150,"column":null}},"37":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"38":{"start":{"line":157,"column":40},"end":{"line":157,"column":null}},"39":{"start":{"line":158,"column":17},"end":{"line":158,"column":null}},"40":{"start":{"line":160,"column":2},"end":{"line":162,"column":null}},"41":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"42":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"43":{"start":{"line":171,"column":12},"end":{"line":171,"column":null}},"44":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"45":{"start":{"line":172,"column":10},"end":{"line":172,"column":null}},"46":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"47":{"start":{"line":174,"column":2},"end":{"line":174,"column":null}},"48":{"start":{"line":182,"column":19},"end":{"line":182,"column":null}},"49":{"start":{"line":183,"column":28},"end":{"line":183,"column":null}},"50":{"start":{"line":185,"column":2},"end":{"line":195,"column":null}},"51":{"start":{"line":186,"column":18},"end":{"line":186,"column":null}},"52":{"start":{"line":187,"column":10},"end":{"line":187,"column":null}},"53":{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},"54":{"start":{"line":188,"column":40},"end":{"line":188,"column":null}},"55":{"start":{"line":189,"column":17},"end":{"line":189,"column":null}},"56":{"start":{"line":190,"column":4},"end":{"line":194,"column":null}},"57":{"start":{"line":191,"column":6},"end":{"line":191,"column":null}},"58":{"start":{"line":196,"column":2},"end":{"line":196,"column":null}},"59":{"start":{"line":203,"column":2},"end":{"line":206,"column":null}},"60":{"start":{"line":204,"column":18},"end":{"line":204,"column":null}},"61":{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},"62":{"start":{"line":205,"column":15},"end":{"line":205,"column":null}},"63":{"start":{"line":207,"column":2},"end":{"line":207,"column":null}},"64":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"65":{"start":{"line":214,"column":45},"end":{"line":214,"column":null}},"66":{"start":{"line":215,"column":32},"end":{"line":215,"column":null}},"67":{"start":{"line":216,"column":17},"end":{"line":216,"column":null}},"68":{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},"69":{"start":{"line":218,"column":4},"end":{"line":218,"column":null}},"70":{"start":{"line":220,"column":2},"end":{"line":220,"column":null}},"71":{"start":{"line":221,"column":2},"end":{"line":226,"column":null}},"72":{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},"73":{"start":{"line":223,"column":17},"end":{"line":223,"column":null}},"74":{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},"75":{"start":{"line":224,"column":56},"end":{"line":224,"column":null}},"76":{"start":{"line":227,"column":2},"end":{"line":227,"column":null}},"77":{"start":{"line":236,"column":15},"end":{"line":236,"column":null}},"78":{"start":{"line":237,"column":2},"end":{"line":237,"column":null}},"79":{"start":{"line":246,"column":15},"end":{"line":246,"column":null}},"80":{"start":{"line":247,"column":16},"end":{"line":247,"column":null}},"81":{"start":{"line":249,"column":18},"end":{"line":249,"column":null}},"82":{"start":{"line":250,"column":23},"end":{"line":250,"column":null}},"83":{"start":{"line":252,"column":26},"end":{"line":252,"column":null}},"84":{"start":{"line":253,"column":18},"end":{"line":253,"column":null}},"85":{"start":{"line":254,"column":24},"end":{"line":254,"column":null}},"86":{"start":{"line":255,"column":23},"end":{"line":255,"column":null}},"87":{"start":{"line":256,"column":29},"end":{"line":256,"column":null}},"88":{"start":{"line":258,"column":25},"end":{"line":258,"column":null}},"89":{"start":{"line":259,"column":36},"end":{"line":259,"column":null}},"90":{"start":{"line":260,"column":28},"end":{"line":260,"column":null}},"91":{"start":{"line":262,"column":23},"end":{"line":262,"column":null}},"92":{"start":{"line":263,"column":24},"end":{"line":265,"column":null}},"93":{"start":{"line":267,"column":2},"end":{"line":280,"column":null}},"94":{"start":{"line":283,"column":24},"end":{"line":289,"column":null}}},"fnMap":{"0":{"name":"htmlDecode","decl":{"start":{"line":68,"column":9},"end":{"line":68,"column":20}},"loc":{"start":{"line":68,"column":39},"end":{"line":90,"column":null}},"line":68},"1":{"name":"(anonymous_1)","decl":{"start":{"line":77,"column":19},"end":{"line":77,"column":null}},"loc":{"start":{"line":78,"column":57},"end":{"line":89,"column":5}},"line":78},"2":{"name":"decodeCodePoint","decl":{"start":{"line":92,"column":9},"end":{"line":92,"column":25}},"loc":{"start":{"line":92,"column":66},"end":{"line":101,"column":null}},"line":92},"3":{"name":"stripTags","decl":{"start":{"line":106,"column":9},"end":{"line":106,"column":19}},"loc":{"start":{"line":106,"column":45},"end":{"line":114,"column":null}},"line":106},"4":{"name":"match1","decl":{"start":{"line":117,"column":9},"end":{"line":117,"column":16}},"loc":{"start":{"line":117,"column":50},"end":{"line":120,"column":null}},"line":117},"5":{"name":"extractMetaContent","decl":{"start":{"line":122,"column":9},"end":{"line":122,"column":null}},"loc":{"start":{"line":126,"column":10},"end":{"line":129,"column":null}},"line":126},"6":{"name":"parseAllMetaTags","decl":{"start":{"line":135,"column":9},"end":{"line":135,"column":26}},"loc":{"start":{"line":135,"column":61},"end":{"line":154,"column":null}},"line":135},"7":{"name":"parseAttributes","decl":{"start":{"line":156,"column":9},"end":{"line":156,"column":25}},"loc":{"start":{"line":156,"column":62},"end":{"line":164,"column":null}},"line":156},"8":{"name":"extractHtmlLang","decl":{"start":{"line":170,"column":9},"end":{"line":170,"column":25}},"loc":{"start":{"line":170,"column":47},"end":{"line":175,"column":null}},"line":170},"9":{"name":"parseAllJsonLdBlocks","decl":{"start":{"line":181,"column":9},"end":{"line":181,"column":30}},"loc":{"start":{"line":181,"column":64},"end":{"line":197,"column":null}},"line":181},"10":{"name":"readJsonLdFieldFromBlocks","decl":{"start":{"line":199,"column":9},"end":{"line":199,"column":null}},"loc":{"start":{"line":202,"column":10},"end":{"line":208,"column":null}},"line":202},"11":{"name":"readJsonLdField","decl":{"start":{"line":210,"column":9},"end":{"line":210,"column":null}},"loc":{"start":{"line":213,"column":10},"end":{"line":228,"column":null}},"line":213},"12":{"name":"inspectHtmlFile","decl":{"start":{"line":235,"column":16},"end":{"line":235,"column":32}},"loc":{"start":{"line":235,"column":67},"end":{"line":238,"column":null}},"line":235},"13":{"name":"inspectHtmlContent","decl":{"start":{"line":245,"column":16},"end":{"line":245,"column":35}},"loc":{"start":{"line":245,"column":89},"end":{"line":281,"column":null}},"line":245}},"branchMap":{"0":{"loc":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79},"1":{"loc":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"2":{"loc":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":81},"3":{"loc":{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":6},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":82},"4":{"loc":{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":84},"5":{"loc":{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":93},"6":{"loc":{"start":{"line":94,"column":4},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{"line":96,"column":5},"end":{"line":96,"column":24}},{"start":{"line":96,"column":24},"end":{"line":96,"column":null}}],"line":94},"7":{"loc":{"start":{"line":119,"column":9},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":13},"end":{"line":119,"column":45}},{"start":{"line":119,"column":45},"end":{"line":119,"column":null}}],"line":119},"8":{"loc":{"start":{"line":119,"column":24},"end":{"line":119,"column":34}},"type":"binary-expr","locations":[{"start":{"line":119,"column":24},"end":{"line":119,"column":32}},{"start":{"line":119,"column":32},"end":{"line":119,"column":34}}],"line":119},"9":{"loc":{"start":{"line":128,"column":9},"end":{"line":128,"column":null}},"type":"binary-expr","locations":[{"start":{"line":128,"column":9},"end":{"line":128,"column":70}},{"start":{"line":128,"column":70},"end":{"line":128,"column":null}}],"line":128},"10":{"loc":{"start":{"line":141,"column":31},"end":{"line":141,"column":50}},"type":"binary-expr","locations":[{"start":{"line":141,"column":31},"end":{"line":141,"column":48}},{"start":{"line":141,"column":48},"end":{"line":141,"column":50}}],"line":141},"11":{"loc":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":144},"12":{"loc":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":146},"13":{"loc":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},{"start":{},"end":{}}],"line":148},"14":{"loc":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},{"start":{},"end":{}}],"line":150},"15":{"loc":{"start":{"line":161,"column":33},"end":{"line":161,"column":null}},"type":"binary-expr","locations":[{"start":{"line":161,"column":33},"end":{"line":161,"column":41}},{"start":{"line":161,"column":41},"end":{"line":161,"column":49}},{"start":{"line":161,"column":49},"end":{"line":161,"column":57}},{"start":{"line":161,"column":57},"end":{"line":161,"column":null}}],"line":161},"16":{"loc":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":172},"17":{"loc":{"start":{"line":174,"column":20},"end":{"line":174,"column":36}},"type":"binary-expr","locations":[{"start":{"line":174,"column":20},"end":{"line":174,"column":34}},{"start":{"line":174,"column":34},"end":{"line":174,"column":36}}],"line":174},"18":{"loc":{"start":{"line":186,"column":45},"end":{"line":186,"column":56}},"type":"binary-expr","locations":[{"start":{"line":186,"column":45},"end":{"line":186,"column":53}},{"start":{"line":186,"column":53},"end":{"line":186,"column":56}}],"line":186},"19":{"loc":{"start":{"line":187,"column":18},"end":{"line":187,"column":34}},"type":"binary-expr","locations":[{"start":{"line":187,"column":18},"end":{"line":187,"column":32}},{"start":{"line":187,"column":32},"end":{"line":187,"column":34}}],"line":187},"20":{"loc":{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":188,"column":null}},{"start":{},"end":{}}],"line":188},"21":{"loc":{"start":{"line":189,"column":17},"end":{"line":189,"column":null}},"type":"binary-expr","locations":[{"start":{"line":189,"column":17},"end":{"line":189,"column":25}},{"start":{"line":189,"column":25},"end":{"line":189,"column":null}}],"line":189},"22":{"loc":{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},"type":"if","locations":[{"start":{"line":205,"column":4},"end":{"line":205,"column":null}},{"start":{},"end":{}}],"line":205},"23":{"loc":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"24":{"loc":{"start":{"line":214,"column":6},"end":{"line":214,"column":45}},"type":"binary-expr","locations":[{"start":{"line":214,"column":6},"end":{"line":214,"column":17}},{"start":{"line":214,"column":17},"end":{"line":214,"column":45}}],"line":214},"25":{"loc":{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},"type":"if","locations":[{"start":{"line":217,"column":2},"end":{"line":219,"column":null}},{"start":{},"end":{}}],"line":217},"26":{"loc":{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":4},"end":{"line":225,"column":null}},{"start":{},"end":{}}],"line":222},"27":{"loc":{"start":{"line":222,"column":8},"end":{"line":222,"column":36}},"type":"binary-expr","locations":[{"start":{"line":222,"column":8},"end":{"line":222,"column":13}},{"start":{"line":222,"column":13},"end":{"line":222,"column":36}}],"line":222},"28":{"loc":{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},"type":"if","locations":[{"start":{"line":224,"column":6},"end":{"line":224,"column":null}},{"start":{},"end":{}}],"line":224},"29":{"loc":{"start":{"line":224,"column":10},"end":{"line":224,"column":56}},"type":"binary-expr","locations":[{"start":{"line":224,"column":10},"end":{"line":224,"column":35}},{"start":{"line":224,"column":35},"end":{"line":224,"column":56}}],"line":224},"30":{"loc":{"start":{"line":245,"column":49},"end":{"line":245,"column":89}},"type":"default-arg","locations":[{"start":{"line":245,"column":68},"end":{"line":245,"column":89}}],"line":245},"31":{"loc":{"start":{"line":252,"column":26},"end":{"line":252,"column":null}},"type":"binary-expr","locations":[{"start":{"line":252,"column":26},"end":{"line":252,"column":61}},{"start":{"line":252,"column":61},"end":{"line":252,"column":null}}],"line":252},"32":{"loc":{"start":{"line":253,"column":18},"end":{"line":253,"column":null}},"type":"binary-expr","locations":[{"start":{"line":253,"column":18},"end":{"line":253,"column":54}},{"start":{"line":253,"column":54},"end":{"line":253,"column":null}}],"line":253},"33":{"loc":{"start":{"line":254,"column":24},"end":{"line":254,"column":null}},"type":"binary-expr","locations":[{"start":{"line":254,"column":24},"end":{"line":254,"column":66}},{"start":{"line":254,"column":66},"end":{"line":254,"column":null}}],"line":254},"34":{"loc":{"start":{"line":255,"column":23},"end":{"line":255,"column":null}},"type":"binary-expr","locations":[{"start":{"line":255,"column":23},"end":{"line":255,"column":60}},{"start":{"line":255,"column":60},"end":{"line":255,"column":null}}],"line":255},"35":{"loc":{"start":{"line":256,"column":29},"end":{"line":256,"column":null}},"type":"binary-expr","locations":[{"start":{"line":256,"column":29},"end":{"line":256,"column":72}},{"start":{"line":256,"column":72},"end":{"line":256,"column":null}}],"line":256},"36":{"loc":{"start":{"line":263,"column":24},"end":{"line":265,"column":null}},"type":"cond-expr","locations":[{"start":{"line":264,"column":6},"end":{"line":264,"column":null}},{"start":{"line":265,"column":6},"end":{"line":265,"column":null}}],"line":263},"37":{"loc":{"start":{"line":264,"column":16},"end":{"line":264,"column":37}},"type":"binary-expr","locations":[{"start":{"line":264,"column":16},"end":{"line":264,"column":35}},{"start":{"line":264,"column":35},"end":{"line":264,"column":37}}],"line":264}},"s":{"0":3,"1":93,"2":93,"3":11,"4":5,"5":6,"6":6,"7":3,"8":0,"9":3,"10":3,"11":3,"12":3,"13":0,"14":8,"15":3,"16":5,"17":21,"18":27,"19":27,"20":0,"21":0,"22":27,"23":27,"24":27,"25":31,"26":31,"27":31,"28":31,"29":31,"30":23,"31":23,"32":23,"33":31,"34":8,"35":8,"36":8,"37":27,"38":68,"39":68,"40":68,"41":97,"42":68,"43":27,"44":27,"45":0,"46":27,"47":27,"48":27,"49":27,"50":27,"51":10,"52":10,"53":10,"54":1,"55":9,"56":10,"57":10,"58":27,"59":81,"60":24,"61":24,"62":13,"63":68,"64":24,"65":0,"66":24,"67":24,"68":24,"69":3,"70":24,"71":24,"72":26,"73":26,"74":26,"75":13,"76":11,"77":10,"78":10,"79":27,"80":27,"81":27,"82":27,"83":27,"84":27,"85":27,"86":27,"87":27,"88":27,"89":27,"90":27,"91":27,"92":27,"93":27,"94":3},"f":{"0":93,"1":11,"2":8,"3":21,"4":27,"5":0,"6":27,"7":68,"8":27,"9":27,"10":81,"11":24,"12":10,"13":27},"b":{"0":[5,6],"1":[3,3],"2":[0,3],"3":[3,0],"4":[3,0],"5":[3,5],"6":[8,8,6,1],"7":[27,0],"8":[27,0],"9":[0,0],"10":[31,0],"11":[23,8],"12":[23,0],"13":[8,23],"14":[8,0],"15":[97,5,3,0],"16":[0,27],"17":[27,2],"18":[10,0],"19":[10,1],"20":[1,9],"21":[9,0],"22":[13,11],"23":[0,24],"24":[24,24],"25":[3,21],"26":[26,0],"27":[26,26],"28":[13,13],"29":[26,13],"30":[27],"31":[27,12],"32":[27,23],"33":[27,23],"34":[27,23],"35":[27,23],"36":[16,11],"37":[16,0]},"meta":{"lastBranch":38,"lastFunction":14,"lastStatement":95,"seen":{"s:59:16:63:Infinity":0,"f:68:9:68:20":0,"s:69:40:76:Infinity":1,"s:77:2:89:Infinity":2,"f:77:19:77:Infinity":1,"b:79:6:79:Infinity:undefined:undefined:undefined:undefined":0,"s:79:6:79:Infinity":3,"s:79:15:79:Infinity":4,"b:80:6:80:Infinity:undefined:undefined:undefined:undefined":1,"s:80:6:80:Infinity":5,"s:80:15:80:Infinity":6,"b:81:6:81:Infinity:undefined:undefined:undefined:undefined":2,"s:81:6:81:Infinity":7,"s:81:28:81:Infinity":8,"b:82:6:87:Infinity:undefined:undefined:undefined:undefined":3,"s:82:6:87:Infinity":9,"s:83:22:83:Infinity":10,"b:84:8:86:Infinity:undefined:undefined:undefined:undefined":4,"s:84:8:86:Infinity":11,"s:85:10:85:Infinity":12,"s:88:6:88:Infinity":13,"f:92:9:92:25":2,"b:93:2:99:Infinity:undefined:undefined:undefined:undefined":5,"s:93:2:99:Infinity":14,"b:94:4:94:Infinity:95:4:95:Infinity:96:5:96:24:96:24:96:Infinity":6,"s:98:4:98:Infinity":15,"s:100:2:100:Infinity":16,"f:106:9:106:19":3,"s:107:2:113:Infinity":17,"f:117:9:117:16":4,"s:118:12:118:Infinity":18,"s:119:2:119:Infinity":19,"b:119:13:119:45:119:45:119:Infinity":7,"b:119:24:119:32:119:32:119:34":8,"f:122:9:122:Infinity":5,"s:127:14:127:Infinity":20,"s:128:2:128:Infinity":21,"b:128:9:128:70:128:70:128:Infinity":9,"f:135:9:135:26":6,"s:136:14:136:Infinity":22,"s:137:20:137:Infinity":23,"s:139:2:152:Infinity":24,"s:140:18:140:Infinity":25,"s:141:20:141:Infinity":26,"b:141:31:141:48:141:48:141:50":10,"s:142:17:142:Infinity":27,"s:143:21:143:Infinity":28,"b:144:4:147:Infinity:undefined:undefined:undefined:undefined":11,"s:144:4:147:Infinity":29,"s:145:18:145:Infinity":30,"b:146:6:146:Infinity:undefined:undefined:undefined:undefined":12,"s:146:6:146:Infinity":31,"s:146:25:146:Infinity":32,"b:148:4:151:Infinity:undefined:undefined:undefined:undefined":13,"s:148:4:151:Infinity":33,"s:149:18:149:Infinity":34,"b:150:6:150:Infinity:undefined:undefined:undefined:undefined":14,"s:150:6:150:Infinity":35,"s:150:25:150:Infinity":36,"s:153:2:153:Infinity":37,"f:156:9:156:25":7,"s:157:40:157:Infinity":38,"s:158:17:158:Infinity":39,"s:160:2:162:Infinity":40,"s:161:4:161:Infinity":41,"b:161:33:161:41:161:41:161:49:161:49:161:57:161:57:161:Infinity":15,"s:163:2:163:Infinity":42,"f:170:9:170:25":8,"s:171:12:171:Infinity":43,"b:172:2:172:Infinity:undefined:undefined:undefined:undefined":16,"s:172:2:172:Infinity":44,"s:172:10:172:Infinity":45,"s:173:16:173:Infinity":46,"s:174:2:174:Infinity":47,"b:174:20:174:34:174:34:174:36":17,"f:181:9:181:30":9,"s:182:19:182:Infinity":48,"s:183:28:183:Infinity":49,"s:185:2:195:Infinity":50,"s:186:18:186:Infinity":51,"b:186:45:186:53:186:53:186:56":18,"s:187:10:187:Infinity":52,"b:187:18:187:32:187:32:187:34":19,"b:188:4:188:Infinity:undefined:undefined:undefined:undefined":20,"s:188:4:188:Infinity":53,"s:188:40:188:Infinity":54,"s:189:17:189:Infinity":55,"b:189:17:189:25:189:25:189:Infinity":21,"s:190:4:194:Infinity":56,"s:191:6:191:Infinity":57,"s:196:2:196:Infinity":58,"f:199:9:199:Infinity":10,"s:203:2:206:Infinity":59,"s:204:18:204:Infinity":60,"b:205:4:205:Infinity:undefined:undefined:undefined:undefined":22,"s:205:4:205:Infinity":61,"s:205:15:205:Infinity":62,"s:207:2:207:Infinity":63,"f:210:9:210:Infinity":11,"b:214:2:214:Infinity:undefined:undefined:undefined:undefined":23,"s:214:2:214:Infinity":64,"b:214:6:214:17:214:17:214:45":24,"s:214:45:214:Infinity":65,"s:215:32:215:Infinity":66,"s:216:17:216:Infinity":67,"b:217:2:219:Infinity:undefined:undefined:undefined:undefined":25,"s:217:2:219:Infinity":68,"s:218:4:218:Infinity":69,"s:220:2:220:Infinity":70,"s:221:2:226:Infinity":71,"b:222:4:225:Infinity:undefined:undefined:undefined:undefined":26,"s:222:4:225:Infinity":72,"b:222:8:222:13:222:13:222:36":27,"s:223:17:223:Infinity":73,"b:224:6:224:Infinity:undefined:undefined:undefined:undefined":28,"s:224:6:224:Infinity":74,"b:224:10:224:35:224:35:224:56":29,"s:224:56:224:Infinity":75,"s:227:2:227:Infinity":76,"f:235:16:235:32":12,"s:236:15:236:Infinity":77,"s:237:2:237:Infinity":78,"f:245:16:245:35":13,"b:245:68:245:89":30,"s:246:15:246:Infinity":79,"s:247:16:247:Infinity":80,"s:249:18:249:Infinity":81,"s:250:23:250:Infinity":82,"s:252:26:252:Infinity":83,"b:252:26:252:61:252:61:252:Infinity":31,"s:253:18:253:Infinity":84,"b:253:18:253:54:253:54:253:Infinity":32,"s:254:24:254:Infinity":85,"b:254:24:254:66:254:66:254:Infinity":33,"s:255:23:255:Infinity":86,"b:255:23:255:60:255:60:255:Infinity":34,"s:256:29:256:Infinity":87,"b:256:29:256:72:256:72:256:Infinity":35,"s:258:25:258:Infinity":88,"s:259:36:259:Infinity":89,"s:260:28:260:Infinity":90,"s:262:23:262:Infinity":91,"s:263:24:265:Infinity":92,"b:264:6:264:Infinity:265:6:265:Infinity":36,"b:264:16:264:35:264:35:264:37":37,"s:267:2:280:Infinity":93,"s:283:24:289:Infinity":94}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/report-writer.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-lib/report-writer.ts","statementMap":{"0":{"start":{"line":40,"column":27},"end":{"line":51,"column":null}},"1":{"start":{"line":69,"column":12},"end":{"line":69,"column":null}},"2":{"start":{"line":70,"column":23},"end":{"line":70,"column":null}},"3":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"4":{"start":{"line":71,"column":21},"end":{"line":71,"column":null}},"5":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"6":{"start":{"line":77,"column":2},"end":{"line":88,"column":null}},"7":{"start":{"line":107,"column":28},"end":{"line":107,"column":null}},"8":{"start":{"line":108,"column":16},"end":{"line":108,"column":null}},"9":{"start":{"line":109,"column":2},"end":{"line":140,"column":null}},"10":{"start":{"line":110,"column":23},"end":{"line":110,"column":null}},"11":{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},"12":{"start":{"line":112,"column":6},"end":{"line":123,"column":null}},"13":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"14":{"start":{"line":126,"column":4},"end":{"line":139,"column":null}},"15":{"start":{"line":127,"column":6},"end":{"line":138,"column":null}},"16":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"17":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}},"18":{"start":{"line":161,"column":13},"end":{"line":161,"column":null}},"19":{"start":{"line":162,"column":2},"end":{"line":171,"column":null}},"20":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"21":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"22":{"start":{"line":165,"column":4},"end":{"line":168,"column":null}},"23":{"start":{"line":166,"column":6},"end":{"line":166,"column":null}},"24":{"start":{"line":167,"column":6},"end":{"line":167,"column":null}},"25":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"26":{"start":{"line":172,"column":2},"end":{"line":172,"column":null}},"27":{"start":{"line":175,"column":24},"end":{"line":177,"column":null}}},"fnMap":{"0":{"name":"quoteField","decl":{"start":{"line":68,"column":16},"end":{"line":68,"column":27}},"loc":{"start":{"line":68,"column":69},"end":{"line":73,"column":null}},"line":68},"1":{"name":"serialiseRow","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":29}},"loc":{"start":{"line":76,"column":53},"end":{"line":89,"column":null}},"line":76},"2":{"name":"rowsForArticle","decl":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"loc":{"start":{"line":106,"column":24},"end":{"line":142,"column":null}},"line":106},"3":{"name":"writeReport","decl":{"start":{"line":156,"column":16},"end":{"line":156,"column":null}},"loc":{"start":{"line":159,"column":10},"end":{"line":173,"column":null}},"line":159}},"branchMap":{"0":{"loc":{"start":{"line":69,"column":12},"end":{"line":69,"column":null}},"type":"binary-expr","locations":[{"start":{"line":69,"column":12},"end":{"line":69,"column":21}},{"start":{"line":69,"column":21},"end":{"line":69,"column":null}}],"line":69},"1":{"loc":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":71},"2":{"loc":{"start":{"line":108,"column":16},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":50},"end":{"line":108,"column":73}},{"start":{"line":108,"column":73},"end":{"line":108,"column":null}}],"line":108},"3":{"loc":{"start":{"line":110,"column":23},"end":{"line":110,"column":null}},"type":"cond-expr","locations":[{"start":{"line":110,"column":30},"end":{"line":110,"column":75}},{"start":{"line":110,"column":75},"end":{"line":110,"column":null}}],"line":110},"4":{"loc":{"start":{"line":110,"column":30},"end":{"line":110,"column":75}},"type":"binary-expr","locations":[{"start":{"line":110,"column":30},"end":{"line":110,"column":70}},{"start":{"line":110,"column":70},"end":{"line":110,"column":75}}],"line":110},"5":{"loc":{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":111},"6":{"loc":{"start":{"line":114,"column":14},"end":{"line":114,"column":null}},"type":"binary-expr","locations":[{"start":{"line":114,"column":14},"end":{"line":114,"column":25}},{"start":{"line":114,"column":25},"end":{"line":114,"column":null}}],"line":114},"7":{"loc":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":19},"end":{"line":115,"column":35}},{"start":{"line":115,"column":35},"end":{"line":115,"column":null}}],"line":115},"8":{"loc":{"start":{"line":129,"column":14},"end":{"line":129,"column":null}},"type":"binary-expr","locations":[{"start":{"line":129,"column":14},"end":{"line":129,"column":25}},{"start":{"line":129,"column":25},"end":{"line":129,"column":null}}],"line":129},"9":{"loc":{"start":{"line":130,"column":19},"end":{"line":130,"column":null}},"type":"binary-expr","locations":[{"start":{"line":130,"column":19},"end":{"line":130,"column":35}},{"start":{"line":130,"column":35},"end":{"line":130,"column":null}}],"line":130},"10":{"loc":{"start":{"line":137,"column":16},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":137,"column":29},"end":{"line":137,"column":61}},{"start":{"line":137,"column":61},"end":{"line":137,"column":null}}],"line":137}},"s":{"0":1,"1":357,"2":357,"3":357,"4":334,"5":23,"6":35,"7":11,"8":11,"9":11,"10":15,"11":15,"12":1,"13":1,"14":14,"15":40,"16":11,"17":8,"18":8,"19":8,"20":8,"21":8,"22":8,"23":34,"24":34,"25":8,"26":8,"27":1},"f":{"0":357,"1":35,"2":11,"3":8},"b":{"0":[357,2],"1":[334,23],"2":[11,0],"3":[15,0],"4":[15,0],"5":[1,14],"6":[1,0],"7":[1,0],"8":[40,0],"9":[40,0],"10":[40,0]},"meta":{"lastBranch":11,"lastFunction":4,"lastStatement":28,"seen":{"s:40:27:51:Infinity":0,"f:68:16:68:27":0,"s:69:12:69:Infinity":1,"b:69:12:69:21:69:21:69:Infinity":0,"s:70:23:70:Infinity":2,"b:71:2:71:Infinity:undefined:undefined:undefined:undefined":1,"s:71:2:71:Infinity":3,"s:71:21:71:Infinity":4,"s:72:2:72:Infinity":5,"f:76:16:76:29":1,"s:77:2:88:Infinity":6,"f:102:16:102:Infinity":2,"s:107:28:107:Infinity":7,"s:108:16:108:Infinity":8,"b:108:50:108:73:108:73:108:Infinity":2,"s:109:2:140:Infinity":9,"s:110:23:110:Infinity":10,"b:110:30:110:75:110:75:110:Infinity":3,"b:110:30:110:70:110:70:110:75":4,"b:111:4:125:Infinity:undefined:undefined:undefined:undefined":5,"s:111:4:125:Infinity":11,"s:112:6:123:Infinity":12,"b:114:14:114:25:114:25:114:Infinity":6,"b:115:19:115:35:115:35:115:Infinity":7,"s:124:6:124:Infinity":13,"s:126:4:139:Infinity":14,"s:127:6:138:Infinity":15,"b:129:14:129:25:129:25:129:Infinity":8,"b:130:19:130:35:130:35:130:Infinity":9,"b:137:29:137:61:137:61:137:Infinity":10,"s:141:2:141:Infinity":16,"f:156:16:156:Infinity":3,"s:160:2:160:Infinity":17,"s:161:13:161:Infinity":18,"s:162:2:171:Infinity":19,"s:163:4:163:Infinity":20,"s:164:4:164:Infinity":21,"s:165:4:168:Infinity":22,"s:166:6:166:Infinity":23,"s:167:6:167:Infinity":24,"s:170:4:170:Infinity":25,"s:172:2:172:Infinity":26,"s:175:24:177:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-news-og-locale-alternate.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/backfill-news-og-locale-alternate.ts","statementMap":{"0":{"start":{"line":58,"column":61},"end":{"line":62,"column":null}},"1":{"start":{"line":64,"column":46},"end":{"line":67,"column":null}},"2":{"start":{"line":73,"column":6},"end":{"line":77,"column":null}},"3":{"start":{"line":74,"column":40},"end":{"line":74,"column":null}},"4":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"5":{"start":{"line":75,"column":29},"end":{"line":75,"column":null}},"6":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"7":{"start":{"line":95,"column":60},"end":{"line":98,"column":null}},"8":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"9":{"start":{"line":113,"column":32},"end":{"line":113,"column":null}},"10":{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},"11":{"start":{"line":141,"column":4},"end":{"line":141,"column":null}},"12":{"start":{"line":143,"column":16},"end":{"line":143,"column":null}},"13":{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},"14":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"15":{"start":{"line":147,"column":48},"end":{"line":147,"column":null}},"16":{"start":{"line":152,"column":26},"end":{"line":152,"column":null}},"17":{"start":{"line":153,"column":15},"end":{"line":153,"column":null}},"18":{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},"19":{"start":{"line":155,"column":4},"end":{"line":155,"column":null}},"20":{"start":{"line":157,"column":21},"end":{"line":157,"column":null}},"21":{"start":{"line":158,"column":24},"end":{"line":160,"column":null}},"22":{"start":{"line":161,"column":21},"end":{"line":164,"column":null}},"23":{"start":{"line":162,"column":19},"end":{"line":162,"column":29}},"24":{"start":{"line":163,"column":16},"end":{"line":163,"column":93}},"25":{"start":{"line":165,"column":15},"end":{"line":165,"column":null}},"26":{"start":{"line":166,"column":2},"end":{"line":166,"column":null}},"27":{"start":{"line":175,"column":18},"end":{"line":175,"column":null}},"28":{"start":{"line":176,"column":24},"end":{"line":176,"column":null}},"29":{"start":{"line":179,"column":4},"end":{"line":183,"column":null}},"30":{"start":{"line":180,"column":6},"end":{"line":180,"column":null}},"31":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"32":{"start":{"line":184,"column":4},"end":{"line":191,"column":null}},"33":{"start":{"line":185,"column":19},"end":{"line":185,"column":null}},"34":{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},"35":{"start":{"line":187,"column":8},"end":{"line":187,"column":null}},"36":{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},"37":{"start":{"line":189,"column":8},"end":{"line":189,"column":null}},"38":{"start":{"line":193,"column":2},"end":{"line":193,"column":null}},"39":{"start":{"line":194,"column":2},"end":{"line":194,"column":null}},"40":{"start":{"line":223,"column":16},"end":{"line":223,"column":null}},"41":{"start":{"line":224,"column":16},"end":{"line":224,"column":null}},"42":{"start":{"line":225,"column":19},"end":{"line":225,"column":null}},"43":{"start":{"line":226,"column":24},"end":{"line":226,"column":null}},"44":{"start":{"line":227,"column":19},"end":{"line":227,"column":null}},"45":{"start":{"line":228,"column":22},"end":{"line":228,"column":null}},"46":{"start":{"line":229,"column":2},"end":{"line":250,"column":null}},"47":{"start":{"line":230,"column":17},"end":{"line":230,"column":null}},"48":{"start":{"line":231,"column":19},"end":{"line":231,"column":null}},"49":{"start":{"line":232,"column":4},"end":{"line":249,"column":null}},"50":{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},"51":{"start":{"line":235,"column":10},"end":{"line":235,"column":null}},"52":{"start":{"line":237,"column":8},"end":{"line":237,"column":null}},"53":{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},"54":{"start":{"line":238,"column":31},"end":{"line":238,"column":null}},"55":{"start":{"line":239,"column":8},"end":{"line":239,"column":null}},"56":{"start":{"line":241,"column":8},"end":{"line":241,"column":null}},"57":{"start":{"line":242,"column":8},"end":{"line":242,"column":null}},"58":{"start":{"line":244,"column":8},"end":{"line":244,"column":null}},"59":{"start":{"line":245,"column":8},"end":{"line":245,"column":null}},"60":{"start":{"line":247,"column":8},"end":{"line":247,"column":null}},"61":{"start":{"line":248,"column":8},"end":{"line":248,"column":null}},"62":{"start":{"line":251,"column":2},"end":{"line":258,"column":null}},"63":{"start":{"line":264,"column":15},"end":{"line":264,"column":null}},"64":{"start":{"line":265,"column":17},"end":{"line":265,"column":null}},"65":{"start":{"line":266,"column":16},"end":{"line":266,"column":null}},"66":{"start":{"line":267,"column":19},"end":{"line":267,"column":null}},"67":{"start":{"line":269,"column":18},"end":{"line":269,"column":null}},"68":{"start":{"line":271,"column":2},"end":{"line":271,"column":null}},"69":{"start":{"line":272,"column":2},"end":{"line":272,"column":null}},"70":{"start":{"line":273,"column":2},"end":{"line":273,"column":null}},"71":{"start":{"line":274,"column":2},"end":{"line":274,"column":null}},"72":{"start":{"line":275,"column":2},"end":{"line":275,"column":null}},"73":{"start":{"line":276,"column":2},"end":{"line":276,"column":null}},"74":{"start":{"line":277,"column":2},"end":{"line":277,"column":null}},"75":{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},"76":{"start":{"line":280,"column":4},"end":{"line":282,"column":null}},"77":{"start":{"line":283,"column":4},"end":{"line":283,"column":null}},"78":{"start":{"line":284,"column":4},"end":{"line":284,"column":null}},"79":{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},"80":{"start":{"line":295,"column":2},"end":{"line":298,"column":null}},"81":{"start":{"line":296,"column":4},"end":{"line":296,"column":null}},"82":{"start":{"line":297,"column":4},"end":{"line":297,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":73,"column":6},"end":{"line":73,"column":69}},"loc":{"start":{"line":73,"column":69},"end":{"line":77,"column":1}},"line":73},"1":{"name":"backfillHtml","decl":{"start":{"line":139,"column":16},"end":{"line":139,"column":29}},"loc":{"start":{"line":139,"column":134},"end":{"line":167,"column":null}},"line":139},"2":{"name":"(anonymous_2)","decl":{"start":{"line":162,"column":5},"end":{"line":162,"column":13}},"loc":{"start":{"line":162,"column":19},"end":{"line":162,"column":29}},"line":162},"3":{"name":"(anonymous_3)","decl":{"start":{"line":163,"column":5},"end":{"line":163,"column":10}},"loc":{"start":{"line":163,"column":16},"end":{"line":163,"column":93}},"line":163},"4":{"name":"listNewsFiles","decl":{"start":{"line":174,"column":22},"end":{"line":174,"column":36}},"loc":{"start":{"line":174,"column":73},"end":{"line":195,"column":null}},"line":174},"5":{"name":"walk","decl":{"start":{"line":177,"column":17},"end":{"line":177,"column":22}},"loc":{"start":{"line":177,"column":50},"end":{"line":192,"column":null}},"line":177},"6":{"name":"runBackfill","decl":{"start":{"line":222,"column":22},"end":{"line":222,"column":34}},"loc":{"start":{"line":222,"column":96},"end":{"line":259,"column":null}},"line":222},"7":{"name":"main","decl":{"start":{"line":263,"column":15},"end":{"line":263,"column":37}},"loc":{"start":{"line":263,"column":37},"end":{"line":286,"column":null}},"line":263},"8":{"name":"(anonymous_8)","decl":{"start":{"line":295,"column":9},"end":{"line":295,"column":16}},"loc":{"start":{"line":295,"column":24},"end":{"line":298,"column":3}},"line":295}},"branchMap":{"0":{"loc":{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":140},"1":{"loc":{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":2},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":144},"2":{"loc":{"start":{"line":152,"column":26},"end":{"line":152,"column":null}},"type":"binary-expr","locations":[{"start":{"line":152,"column":26},"end":{"line":152,"column":63}},{"start":{"line":152,"column":63},"end":{"line":152,"column":null}}],"line":152},"3":{"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":156,"column":null}},{"start":{},"end":{}}],"line":154},"4":{"loc":{"start":{"line":158,"column":24},"end":{"line":160,"column":null}},"type":"cond-expr","locations":[{"start":{"line":159,"column":6},"end":{"line":159,"column":null}},{"start":{"line":160,"column":6},"end":{"line":160,"column":null}}],"line":158},"5":{"loc":{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":186,"column":6},"end":{"line":190,"column":null}},{"start":{"line":188,"column":13},"end":{"line":190,"column":null}}],"line":186},"6":{"loc":{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":13},"end":{"line":190,"column":null}},{"start":{},"end":{}}],"line":188},"7":{"loc":{"start":{"line":188,"column":17},"end":{"line":188,"column":65}},"type":"binary-expr","locations":[{"start":{"line":188,"column":17},"end":{"line":188,"column":35}},{"start":{"line":188,"column":35},"end":{"line":188,"column":65}}],"line":188},"8":{"loc":{"start":{"line":222,"column":52},"end":{"line":222,"column":96}},"type":"default-arg","locations":[{"start":{"line":222,"column":71},"end":{"line":222,"column":96}}],"line":222},"9":{"loc":{"start":{"line":232,"column":4},"end":{"line":249,"column":null}},"type":"switch","locations":[{"start":{"line":233,"column":6},"end":{"line":239,"column":null}},{"start":{"line":240,"column":6},"end":{"line":242,"column":null}},{"start":{"line":243,"column":6},"end":{"line":245,"column":null}},{"start":{"line":246,"column":6},"end":{"line":248,"column":null}}],"line":232},"10":{"loc":{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},"type":"if","locations":[{"start":{"line":234,"column":8},"end":{"line":236,"column":null}},{"start":{},"end":{}}],"line":234},"11":{"loc":{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},"type":"if","locations":[{"start":{"line":238,"column":8},"end":{"line":238,"column":null}},{"start":{},"end":{}}],"line":238},"12":{"loc":{"start":{"line":265,"column":17},"end":{"line":265,"column":null}},"type":"binary-expr","locations":[{"start":{"line":265,"column":17},"end":{"line":265,"column":42}},{"start":{"line":265,"column":42},"end":{"line":265,"column":null}}],"line":265},"13":{"loc":{"start":{"line":273,"column":68},"end":{"line":273,"column":107}},"type":"cond-expr","locations":[{"start":{"line":273,"column":77},"end":{"line":273,"column":103}},{"start":{"line":273,"column":103},"end":{"line":273,"column":107}}],"line":273},"14":{"loc":{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},"type":"if","locations":[{"start":{"line":279,"column":2},"end":{"line":285,"column":null}},{"start":{},"end":{}}],"line":279},"15":{"loc":{"start":{"line":279,"column":6},"end":{"line":279,"column":36}},"type":"binary-expr","locations":[{"start":{"line":279,"column":6},"end":{"line":279,"column":15}},{"start":{"line":279,"column":15},"end":{"line":279,"column":36}}],"line":279},"16":{"loc":{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},"type":"if","locations":[{"start":{"line":289,"column":0},"end":{"line":299,"column":null}},{"start":{},"end":{}}],"line":289},"17":{"loc":{"start":{"line":290,"column":2},"end":{"line":293,"column":null}},"type":"binary-expr","locations":[{"start":{"line":290,"column":2},"end":{"line":290,"column":null}},{"start":{"line":291,"column":2},"end":{"line":291,"column":null}},{"start":{"line":292,"column":2},"end":{"line":292,"column":null}},{"start":{"line":293,"column":2},"end":{"line":293,"column":null}}],"line":290}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":14,"6":1,"7":1,"8":1,"9":1,"10":27,"11":3,"12":24,"13":24,"14":1,"15":23,"16":23,"17":27,"18":27,"19":1,"20":22,"21":22,"22":27,"23":308,"24":286,"25":27,"26":27,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":1,"80":0,"81":0,"82":0},"f":{"0":1,"1":27,"2":308,"3":286,"4":0,"5":0,"6":0,"7":0,"8":0},"b":{"0":[3,24],"1":[1,23],"2":[23,20],"3":[1,26],"4":[3,19],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0],"9":[0,0,0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,1],"17":[1,1,1,1]},"meta":{"lastBranch":18,"lastFunction":9,"lastStatement":83,"seen":{"s:58:61:62:Infinity":0,"s:64:46:67:Infinity":1,"s:73:6:77:Infinity":2,"f:73:6:73:69":0,"s:74:40:74:Infinity":3,"s:75:2:75:Infinity":4,"s:75:29:75:Infinity":5,"s:76:2:76:Infinity":6,"s:95:60:98:Infinity":7,"s:110:2:110:Infinity":8,"s:113:32:113:Infinity":9,"f:139:16:139:29":1,"b:140:2:142:Infinity:undefined:undefined:undefined:undefined":0,"s:140:2:142:Infinity":10,"s:141:4:141:Infinity":11,"s:143:16:143:Infinity":12,"b:144:2:146:Infinity:undefined:undefined:undefined:undefined":1,"s:144:2:146:Infinity":13,"s:145:4:145:Infinity":14,"s:147:48:147:Infinity":15,"s:152:26:152:Infinity":16,"b:152:26:152:63:152:63:152:Infinity":2,"s:153:15:153:Infinity":17,"b:154:2:156:Infinity:undefined:undefined:undefined:undefined":3,"s:154:2:156:Infinity":18,"s:155:4:155:Infinity":19,"s:157:21:157:Infinity":20,"s:158:24:160:Infinity":21,"b:159:6:159:Infinity:160:6:160:Infinity":4,"s:161:21:164:Infinity":22,"f:162:5:162:13":2,"s:162:19:162:29":23,"f:163:5:163:10":3,"s:163:16:163:93":24,"s:165:15:165:Infinity":25,"s:166:2:166:Infinity":26,"f:174:22:174:36":4,"s:175:18:175:Infinity":27,"s:176:24:176:Infinity":28,"f:177:17:177:22":5,"s:179:4:183:Infinity":29,"s:180:6:180:Infinity":30,"s:182:6:182:Infinity":31,"s:184:4:191:Infinity":32,"s:185:19:185:Infinity":33,"b:186:6:190:Infinity:188:13:190:Infinity":5,"s:186:6:190:Infinity":34,"s:187:8:187:Infinity":35,"b:188:13:190:Infinity:undefined:undefined:undefined:undefined":6,"s:188:13:190:Infinity":36,"b:188:17:188:35:188:35:188:65":7,"s:189:8:189:Infinity":37,"s:193:2:193:Infinity":38,"s:194:2:194:Infinity":39,"f:222:22:222:34":6,"b:222:71:222:96":8,"s:223:16:223:Infinity":40,"s:224:16:224:Infinity":41,"s:225:19:225:Infinity":42,"s:226:24:226:Infinity":43,"s:227:19:227:Infinity":44,"s:228:22:228:Infinity":45,"s:229:2:250:Infinity":46,"s:230:17:230:Infinity":47,"s:231:19:231:Infinity":48,"b:233:6:239:Infinity:240:6:242:Infinity:243:6:245:Infinity:246:6:248:Infinity":9,"s:232:4:249:Infinity":49,"b:234:8:236:Infinity:undefined:undefined:undefined:undefined":10,"s:234:8:236:Infinity":50,"s:235:10:235:Infinity":51,"s:237:8:237:Infinity":52,"b:238:8:238:Infinity:undefined:undefined:undefined:undefined":11,"s:238:8:238:Infinity":53,"s:238:31:238:Infinity":54,"s:239:8:239:Infinity":55,"s:241:8:241:Infinity":56,"s:242:8:242:Infinity":57,"s:244:8:244:Infinity":58,"s:245:8:245:Infinity":59,"s:247:8:247:Infinity":60,"s:248:8:248:Infinity":61,"s:251:2:258:Infinity":62,"f:263:15:263:37":7,"s:264:15:264:Infinity":63,"s:265:17:265:Infinity":64,"b:265:17:265:42:265:42:265:Infinity":12,"s:266:16:266:Infinity":65,"s:267:19:267:Infinity":66,"s:269:18:269:Infinity":67,"s:271:2:271:Infinity":68,"s:272:2:272:Infinity":69,"s:273:2:273:Infinity":70,"b:273:77:273:103:273:103:273:107":13,"s:274:2:274:Infinity":71,"s:275:2:275:Infinity":72,"s:276:2:276:Infinity":73,"s:277:2:277:Infinity":74,"b:279:2:285:Infinity:undefined:undefined:undefined:undefined":14,"s:279:2:285:Infinity":75,"b:279:6:279:15:279:15:279:36":15,"s:280:4:282:Infinity":76,"s:283:4:283:Infinity":77,"s:284:4:284:Infinity":78,"b:289:0:299:Infinity:undefined:undefined:undefined:undefined":16,"s:289:0:299:Infinity":79,"b:290:2:290:Infinity:291:2:291:Infinity:292:2:292:Infinity:293:2:293:Infinity":17,"s:295:2:298:Infinity":80,"f:295:9:295:16":8,"s:296:4:296:Infinity":81,"s:297:4:297:Infinity":82}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/calendar-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/calendar-fetch.ts","statementMap":{"0":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":46},"end":{"line":37,"column":null}},"3":{"start":{"line":44,"column":58},"end":{"line":57,"column":null}},"4":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"5":{"start":{"line":46,"column":146},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"7":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"8":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"9":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"10":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"11":{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},"12":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"13":{"start":{"line":63,"column":69},"end":{"line":63,"column":null}},"14":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"15":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"16":{"start":{"line":66,"column":69},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":80,"column":20},"end":{"line":80,"column":null}},"19":{"start":{"line":81,"column":2},"end":{"line":164,"column":null}},"20":{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},"21":{"start":{"line":85,"column":21},"end":{"line":85,"column":null}},"22":{"start":{"line":86,"column":22},"end":{"line":88,"column":null}},"23":{"start":{"line":87,"column":42},"end":{"line":87,"column":71}},"24":{"start":{"line":89,"column":21},"end":{"line":89,"column":null}},"25":{"start":{"line":90,"column":41},"end":{"line":107,"column":null}},"26":{"start":{"line":108,"column":6},"end":{"line":108,"column":null}},"27":{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},"28":{"start":{"line":113,"column":18},"end":{"line":113,"column":null}},"29":{"start":{"line":114,"column":18},"end":{"line":114,"column":null}},"30":{"start":{"line":115,"column":44},"end":{"line":115,"column":null}},"31":{"start":{"line":116,"column":21},"end":{"line":116,"column":null}},"32":{"start":{"line":116,"column":40},"end":{"line":116,"column":72}},"33":{"start":{"line":117,"column":22},"end":{"line":119,"column":null}},"34":{"start":{"line":118,"column":35},"end":{"line":118,"column":64}},"35":{"start":{"line":120,"column":6},"end":{"line":131,"column":null}},"36":{"start":{"line":133,"column":26},"end":{"line":133,"column":null}},"37":{"start":{"line":134,"column":19},"end":{"line":134,"column":null}},"38":{"start":{"line":135,"column":20},"end":{"line":137,"column":null}},"39":{"start":{"line":136,"column":40},"end":{"line":136,"column":69}},"40":{"start":{"line":138,"column":4},"end":{"line":149,"column":null}},"41":{"start":{"line":151,"column":4},"end":{"line":163,"column":null}},"42":{"start":{"line":168,"column":2},"end":{"line":168,"column":null}},"43":{"start":{"line":169,"column":2},"end":{"line":169,"column":null}},"44":{"start":{"line":170,"column":2},"end":{"line":170,"column":null}},"45":{"start":{"line":174,"column":13},"end":{"line":174,"column":null}},"46":{"start":{"line":175,"column":11},"end":{"line":175,"column":null}},"47":{"start":{"line":176,"column":27},"end":{"line":176,"column":null}},"48":{"start":{"line":177,"column":27},"end":{"line":177,"column":null}},"49":{"start":{"line":178,"column":15},"end":{"line":178,"column":null}},"50":{"start":{"line":179,"column":16},"end":{"line":179,"column":null}},"51":{"start":{"line":180,"column":2},"end":{"line":211,"column":null}},"52":{"start":{"line":180,"column":15},"end":{"line":180,"column":18}},"53":{"start":{"line":181,"column":18},"end":{"line":181,"column":null}},"54":{"start":{"line":182,"column":17},"end":{"line":182,"column":null}},"55":{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},"56":{"start":{"line":184,"column":6},"end":{"line":184,"column":null}},"57":{"start":{"line":185,"column":6},"end":{"line":185,"column":null}},"58":{"start":{"line":186,"column":6},"end":{"line":186,"column":null}},"59":{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},"60":{"start":{"line":189,"column":6},"end":{"line":189,"column":null}},"61":{"start":{"line":190,"column":6},"end":{"line":190,"column":null}},"62":{"start":{"line":191,"column":6},"end":{"line":191,"column":null}},"63":{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},"64":{"start":{"line":194,"column":6},"end":{"line":194,"column":null}},"65":{"start":{"line":195,"column":6},"end":{"line":195,"column":null}},"66":{"start":{"line":196,"column":6},"end":{"line":196,"column":null}},"67":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"68":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"69":{"start":{"line":200,"column":6},"end":{"line":200,"column":null}},"70":{"start":{"line":201,"column":6},"end":{"line":201,"column":null}},"71":{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},"72":{"start":{"line":204,"column":6},"end":{"line":204,"column":null}},"73":{"start":{"line":205,"column":6},"end":{"line":205,"column":null}},"74":{"start":{"line":206,"column":6},"end":{"line":206,"column":null}},"75":{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},"76":{"start":{"line":209,"column":6},"end":{"line":209,"column":null}},"77":{"start":{"line":212,"column":2},"end":{"line":212,"column":null}},"78":{"start":{"line":216,"column":15},"end":{"line":216,"column":null}},"79":{"start":{"line":217,"column":17},"end":{"line":217,"column":null}},"80":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"81":{"start":{"line":219,"column":4},"end":{"line":219,"column":null}},"82":{"start":{"line":221,"column":2},"end":{"line":221,"column":null}},"83":{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},"84":{"start":{"line":225,"column":2},"end":{"line":228,"column":null}},"85":{"start":{"line":226,"column":4},"end":{"line":226,"column":null}},"86":{"start":{"line":227,"column":4},"end":{"line":227,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":44,"column":58},"end":{"line":44,"column":65}},"loc":{"start":{"line":44,"column":78},"end":{"line":57,"column":null}},"line":44},"1":{"name":"matchesScope","decl":{"start":{"line":59,"column":9},"end":{"line":59,"column":22}},"loc":{"start":{"line":59,"column":93},"end":{"line":69,"column":null}},"line":59},"2":{"name":"fetchCalendarStatus","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":null}},"loc":{"start":{"line":79,"column":27},"end":{"line":165,"column":null}},"line":79},"3":{"name":"(anonymous_3)","decl":{"start":{"line":87,"column":24},"end":{"line":87,"column":32}},"loc":{"start":{"line":87,"column":42},"end":{"line":87,"column":71}},"line":87},"4":{"name":"(anonymous_4)","decl":{"start":{"line":116,"column":25},"end":{"line":116,"column":30}},"loc":{"start":{"line":116,"column":40},"end":{"line":116,"column":72}},"line":116},"5":{"name":"(anonymous_5)","decl":{"start":{"line":118,"column":17},"end":{"line":118,"column":25}},"loc":{"start":{"line":118,"column":35},"end":{"line":118,"column":64}},"line":118},"6":{"name":"(anonymous_6)","decl":{"start":{"line":136,"column":22},"end":{"line":136,"column":30}},"loc":{"start":{"line":136,"column":40},"end":{"line":136,"column":69}},"line":136},"7":{"name":"persistCalendarStatus","decl":{"start":{"line":167,"column":16},"end":{"line":167,"column":38}},"loc":{"start":{"line":167,"column":115},"end":{"line":171,"column":null}},"line":167},"8":{"name":"parseArgs","decl":{"start":{"line":173,"column":9},"end":{"line":173,"column":19}},"loc":{"start":{"line":173,"column":148},"end":{"line":213,"column":null}},"line":173},"9":{"name":"main","decl":{"start":{"line":215,"column":15},"end":{"line":215,"column":37}},"loc":{"start":{"line":215,"column":37},"end":{"line":222,"column":null}},"line":215},"10":{"name":"(anonymous_10)","decl":{"start":{"line":225,"column":9},"end":{"line":225,"column":16}},"loc":{"start":{"line":225,"column":35},"end":{"line":228,"column":3}},"line":225}},"branchMap":{"0":{"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"4":{"loc":{"start":{"line":63,"column":8},"end":{"line":63,"column":69}},"type":"binary-expr","locations":[{"start":{"line":63,"column":8},"end":{"line":63,"column":22}},{"start":{"line":63,"column":22},"end":{"line":63,"column":69}}],"line":63},"5":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65},"6":{"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":66},"7":{"loc":{"start":{"line":66,"column":8},"end":{"line":66,"column":69}},"type":"binary-expr","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":22}},{"start":{"line":66,"column":22},"end":{"line":66,"column":69}}],"line":66},"8":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"default-arg","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":null}}],"line":74},"9":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"default-arg","locations":[{"start":{"line":75,"column":23},"end":{"line":75,"column":null}}],"line":75},"10":{"loc":{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":109,"column":null}},{"start":{},"end":{}}],"line":84},"11":{"loc":{"start":{"line":86,"column":22},"end":{"line":88,"column":null}},"type":"cond-expr","locations":[{"start":{"line":87,"column":10},"end":{"line":87,"column":null}},{"start":{"line":88,"column":10},"end":{"line":88,"column":null}}],"line":86},"12":{"loc":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":22},"end":{"line":86,"column":29}},{"start":{"line":86,"column":29},"end":{"line":86,"column":null}}],"line":86},"13":{"loc":{"start":{"line":98,"column":16},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":25},"end":{"line":98,"column":32}},{"start":{"line":98,"column":32},"end":{"line":98,"column":null}}],"line":98},"14":{"loc":{"start":{"line":101,"column":12},"end":{"line":106,"column":null}},"type":"cond-expr","locations":[{"start":{"line":102,"column":12},"end":{"line":105,"column":null}},{"start":{"line":106,"column":12},"end":{"line":106,"column":null}}],"line":101},"15":{"loc":{"start":{"line":101,"column":12},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":101,"column":12},"end":{"line":101,"column":35}},{"start":{"line":101,"column":35},"end":{"line":101,"column":null}}],"line":101},"16":{"loc":{"start":{"line":103,"column":14},"end":{"line":103,"column":null}},"type":"cond-expr","locations":[{"start":{"line":103,"column":36},"end":{"line":103,"column":72}},{"start":{"line":103,"column":72},"end":{"line":103,"column":null}}],"line":103},"17":{"loc":{"start":{"line":104,"column":14},"end":{"line":104,"column":null}},"type":"cond-expr","locations":[{"start":{"line":104,"column":37},"end":{"line":104,"column":75}},{"start":{"line":104,"column":75},"end":{"line":104,"column":null}}],"line":104},"18":{"loc":{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":4},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":112},"19":{"loc":{"start":{"line":117,"column":22},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":10},"end":{"line":118,"column":null}},{"start":{"line":119,"column":10},"end":{"line":119,"column":null}}],"line":117},"20":{"loc":{"start":{"line":117,"column":22},"end":{"line":117,"column":null}},"type":"binary-expr","locations":[{"start":{"line":117,"column":22},"end":{"line":117,"column":29}},{"start":{"line":117,"column":29},"end":{"line":117,"column":null}}],"line":117},"21":{"loc":{"start":{"line":135,"column":20},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":8},"end":{"line":136,"column":null}},{"start":{"line":137,"column":8},"end":{"line":137,"column":null}}],"line":135},"22":{"loc":{"start":{"line":135,"column":20},"end":{"line":135,"column":null}},"type":"binary-expr","locations":[{"start":{"line":135,"column":20},"end":{"line":135,"column":27}},{"start":{"line":135,"column":27},"end":{"line":135,"column":null}}],"line":135},"23":{"loc":{"start":{"line":146,"column":14},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":39},"end":{"line":146,"column":46}},{"start":{"line":146,"column":46},"end":{"line":146,"column":null}}],"line":146},"24":{"loc":{"start":{"line":162,"column":13},"end":{"line":162,"column":null}},"type":"cond-expr","locations":[{"start":{"line":162,"column":38},"end":{"line":162,"column":54}},{"start":{"line":162,"column":54},"end":{"line":162,"column":null}}],"line":162},"25":{"loc":{"start":{"line":167,"column":62},"end":{"line":167,"column":115}},"type":"default-arg","locations":[{"start":{"line":167,"column":75},"end":{"line":167,"column":115}}],"line":167},"26":{"loc":{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":183},"27":{"loc":{"start":{"line":183,"column":8},"end":{"line":183,"column":36}},"type":"binary-expr","locations":[{"start":{"line":183,"column":8},"end":{"line":183,"column":30}},{"start":{"line":183,"column":30},"end":{"line":183,"column":36}}],"line":183},"28":{"loc":{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":188},"29":{"loc":{"start":{"line":188,"column":8},"end":{"line":188,"column":34}},"type":"binary-expr","locations":[{"start":{"line":188,"column":8},"end":{"line":188,"column":28}},{"start":{"line":188,"column":28},"end":{"line":188,"column":34}}],"line":188},"30":{"loc":{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":193,"column":4},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":193},"31":{"loc":{"start":{"line":193,"column":8},"end":{"line":193,"column":35}},"type":"binary-expr","locations":[{"start":{"line":193,"column":8},"end":{"line":193,"column":29}},{"start":{"line":193,"column":29},"end":{"line":193,"column":35}}],"line":193},"32":{"loc":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"type":"if","locations":[{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},{"start":{},"end":{}}],"line":198},"33":{"loc":{"start":{"line":198,"column":8},"end":{"line":198,"column":35}},"type":"binary-expr","locations":[{"start":{"line":198,"column":8},"end":{"line":198,"column":29}},{"start":{"line":198,"column":29},"end":{"line":198,"column":35}}],"line":198},"34":{"loc":{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":207,"column":null}},{"start":{},"end":{}}],"line":203},"35":{"loc":{"start":{"line":203,"column":8},"end":{"line":203,"column":38}},"type":"binary-expr","locations":[{"start":{"line":203,"column":8},"end":{"line":203,"column":32}},{"start":{"line":203,"column":32},"end":{"line":203,"column":38}}],"line":203},"36":{"loc":{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},"type":"if","locations":[{"start":{"line":208,"column":4},"end":{"line":210,"column":null}},{"start":{},"end":{}}],"line":208},"37":{"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"38":{"loc":{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},"type":"if","locations":[{"start":{"line":224,"column":0},"end":{"line":229,"column":null}},{"start":{},"end":{}}],"line":224},"39":{"loc":{"start":{"line":224,"column":66},"end":{"line":224,"column":87}},"type":"binary-expr","locations":[{"start":{"line":224,"column":66},"end":{"line":224,"column":85}},{"start":{"line":224,"column":85},"end":{"line":224,"column":87}}],"line":224},"40":{"loc":{"start":{"line":226,"column":37},"end":{"line":226,"column":93}},"type":"cond-expr","locations":[{"start":{"line":226,"column":62},"end":{"line":226,"column":78}},{"start":{"line":226,"column":78},"end":{"line":226,"column":93}}],"line":226}},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":4,"12":4,"13":2,"14":2,"15":0,"16":0,"17":2,"18":3,"19":3,"20":3,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":3,"28":3,"29":3,"30":2,"31":2,"32":4,"33":2,"34":4,"35":3,"36":0,"37":0,"38":0,"39":0,"40":3,"41":1,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":1,"84":0,"85":0,"86":0},"f":{"0":0,"1":4,"2":3,"3":0,"4":4,"5":4,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[0,0],"1":[0,0],"2":[4,0],"3":[2,2],"4":[4,3],"5":[0,2],"6":[0,0],"7":[0,0],"8":[3],"9":[3],"10":[0,3],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0],"18":[3,0],"19":[2,0],"20":[2,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[1,0],"25":[0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,0],"35":[0,0],"36":[0,0],"37":[0,0],"38":[0,1],"39":[1,0],"40":[0,0]},"meta":{"lastBranch":41,"lastFunction":11,"lastStatement":87,"seen":{"s:35:18:35:Infinity":0,"s:36:18:36:Infinity":1,"s:37:46:37:Infinity":2,"s:44:58:57:Infinity":3,"f:44:58:44:65":0,"s:45:17:45:Infinity":4,"s:46:146:49:Infinity":5,"b:50:2:52:Infinity:undefined:undefined:undefined:undefined":0,"s:50:2:52:Infinity":6,"s:51:4:51:Infinity":7,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:55:Infinity":8,"s:54:4:54:Infinity":9,"s:56:2:56:Infinity":10,"f:59:9:59:22":1,"b:62:2:64:Infinity:undefined:undefined:undefined:undefined":2,"s:62:2:64:Infinity":11,"b:63:4:63:Infinity:undefined:undefined:undefined:undefined":3,"s:63:4:63:Infinity":12,"b:63:8:63:22:63:22:63:69":4,"s:63:69:63:Infinity":13,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":5,"s:65:2:67:Infinity":14,"b:66:4:66:Infinity:undefined:undefined:undefined:undefined":6,"s:66:4:66:Infinity":15,"b:66:8:66:22:66:22:66:69":7,"s:66:69:66:Infinity":16,"s:68:2:68:Infinity":17,"f:71:22:71:Infinity":2,"b:74:23:74:Infinity":8,"b:75:23:75:Infinity":9,"s:80:20:80:Infinity":18,"s:81:2:164:Infinity":19,"b:84:4:109:Infinity:undefined:undefined:undefined:undefined":10,"s:84:4:109:Infinity":20,"s:85:21:85:Infinity":21,"s:86:22:88:Infinity":22,"b:87:10:87:Infinity:88:10:88:Infinity":11,"b:86:22:86:29:86:29:86:Infinity":12,"f:87:24:87:32":3,"s:87:42:87:71":23,"s:89:21:89:Infinity":24,"s:90:41:107:Infinity":25,"b:98:25:98:32:98:32:98:Infinity":13,"b:102:12:105:Infinity:106:12:106:Infinity":14,"b:101:12:101:35:101:35:101:Infinity":15,"b:103:36:103:72:103:72:103:Infinity":16,"b:104:37:104:75:104:75:104:Infinity":17,"s:108:6:108:Infinity":26,"b:112:4:132:Infinity:undefined:undefined:undefined:undefined":18,"s:112:4:132:Infinity":27,"s:113:18:113:Infinity":28,"s:114:18:114:Infinity":29,"s:115:44:115:Infinity":30,"s:116:21:116:Infinity":31,"f:116:25:116:30":4,"s:116:40:116:72":32,"s:117:22:119:Infinity":33,"b:118:10:118:Infinity:119:10:119:Infinity":19,"b:117:22:117:29:117:29:117:Infinity":20,"f:118:17:118:25":5,"s:118:35:118:64":34,"s:120:6:131:Infinity":35,"s:133:26:133:Infinity":36,"s:134:19:134:Infinity":37,"s:135:20:137:Infinity":38,"b:136:8:136:Infinity:137:8:137:Infinity":21,"b:135:20:135:27:135:27:135:Infinity":22,"f:136:22:136:30":6,"s:136:40:136:69":39,"s:138:4:149:Infinity":40,"b:146:39:146:46:146:46:146:Infinity":23,"s:151:4:163:Infinity":41,"b:162:38:162:54:162:54:162:Infinity":24,"f:167:16:167:38":7,"b:167:75:167:115":25,"s:168:2:168:Infinity":42,"s:169:2:169:Infinity":43,"s:170:2:170:Infinity":44,"f:173:9:173:19":8,"s:174:13:174:Infinity":45,"s:175:11:175:Infinity":46,"s:176:27:176:Infinity":47,"s:177:27:177:Infinity":48,"s:178:15:178:Infinity":49,"s:179:16:179:Infinity":50,"s:180:2:211:Infinity":51,"s:180:15:180:18":52,"s:181:18:181:Infinity":53,"s:182:17:182:Infinity":54,"b:183:4:187:Infinity:undefined:undefined:undefined:undefined":26,"s:183:4:187:Infinity":55,"b:183:8:183:30:183:30:183:36":27,"s:184:6:184:Infinity":56,"s:185:6:185:Infinity":57,"s:186:6:186:Infinity":58,"b:188:4:192:Infinity:undefined:undefined:undefined:undefined":28,"s:188:4:192:Infinity":59,"b:188:8:188:28:188:28:188:34":29,"s:189:6:189:Infinity":60,"s:190:6:190:Infinity":61,"s:191:6:191:Infinity":62,"b:193:4:197:Infinity:undefined:undefined:undefined:undefined":30,"s:193:4:197:Infinity":63,"b:193:8:193:29:193:29:193:35":31,"s:194:6:194:Infinity":64,"s:195:6:195:Infinity":65,"s:196:6:196:Infinity":66,"b:198:4:202:Infinity:undefined:undefined:undefined:undefined":32,"s:198:4:202:Infinity":67,"b:198:8:198:29:198:29:198:35":33,"s:199:6:199:Infinity":68,"s:200:6:200:Infinity":69,"s:201:6:201:Infinity":70,"b:203:4:207:Infinity:undefined:undefined:undefined:undefined":34,"s:203:4:207:Infinity":71,"b:203:8:203:32:203:32:203:38":35,"s:204:6:204:Infinity":72,"s:205:6:205:Infinity":73,"s:206:6:206:Infinity":74,"b:208:4:210:Infinity:undefined:undefined:undefined:undefined":36,"s:208:4:210:Infinity":75,"s:209:6:209:Infinity":76,"s:212:2:212:Infinity":77,"f:215:15:215:37":9,"s:216:15:216:Infinity":78,"s:217:17:217:Infinity":79,"b:218:2:220:Infinity:undefined:undefined:undefined:undefined":37,"s:218:2:220:Infinity":80,"s:219:4:219:Infinity":81,"s:221:2:221:Infinity":82,"b:224:0:229:Infinity:undefined:undefined:undefined:undefined":38,"s:224:0:229:Infinity":83,"b:224:66:224:85:224:85:224:87":39,"s:225:2:228:Infinity":84,"f:225:9:225:16":10,"s:226:4:226:Infinity":85,"b:226:62:226:78:226:78:226:93":40,"s:227:4:227:Infinity":86}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/bake-stats-html.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/bake-stats-html.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":45,"column":63},"end":{"line":71,"column":null}},"2":{"start":{"line":85,"column":16},"end":{"line":85,"column":null}},"3":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"4":{"start":{"line":86,"column":26},"end":{"line":86,"column":null}},"5":{"start":{"line":87,"column":18},"end":{"line":87,"column":null}},"6":{"start":{"line":87,"column":49},"end":{"line":87,"column":57}},"7":{"start":{"line":88,"column":31},"end":{"line":88,"column":null}},"8":{"start":{"line":89,"column":2},"end":{"line":98,"column":null}},"9":{"start":{"line":89,"column":15},"end":{"line":89,"column":18}},"10":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"11":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"12":{"start":{"line":91,"column":14},"end":{"line":91,"column":null}},"13":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"14":{"start":{"line":93,"column":40},"end":{"line":93,"column":null}},"15":{"start":{"line":94,"column":4},"end":{"line":96,"column":null}},"16":{"start":{"line":94,"column":17},"end":{"line":94,"column":20}},"17":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"18":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"19":{"start":{"line":99,"column":2},"end":{"line":99,"column":null}},"20":{"start":{"line":111,"column":15},"end":{"line":111,"column":null}},"21":{"start":{"line":112,"column":43},"end":{"line":112,"column":null}},"22":{"start":{"line":113,"column":2},"end":{"line":118,"column":null}},"23":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"24":{"start":{"line":114,"column":34},"end":{"line":114,"column":null}},"25":{"start":{"line":115,"column":14},"end":{"line":115,"column":null}},"26":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"27":{"start":{"line":116,"column":29},"end":{"line":116,"column":null}},"28":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"29":{"start":{"line":119,"column":38},"end":{"line":119,"column":null}},"30":{"start":{"line":120,"column":2},"end":{"line":125,"column":null}},"31":{"start":{"line":121,"column":18},"end":{"line":121,"column":null}},"32":{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},"33":{"start":{"line":123,"column":6},"end":{"line":123,"column":null}},"34":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"35":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"36":{"start":{"line":146,"column":17},"end":{"line":146,"column":null}},"37":{"start":{"line":147,"column":20},"end":{"line":152,"column":null}},"38":{"start":{"line":148,"column":18},"end":{"line":148,"column":null}},"39":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"40":{"start":{"line":149,"column":29},"end":{"line":149,"column":null}},"41":{"start":{"line":150,"column":4},"end":{"line":150,"column":null}},"42":{"start":{"line":151,"column":4},"end":{"line":151,"column":null}},"43":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"44":{"start":{"line":167,"column":2},"end":{"line":167,"column":null}},"45":{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},"46":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"47":{"start":{"line":177,"column":18},"end":{"line":177,"column":null}},"48":{"start":{"line":178,"column":17},"end":{"line":178,"column":null}},"49":{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},"50":{"start":{"line":180,"column":4},"end":{"line":182,"column":null}},"51":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"52":{"start":{"line":186,"column":18},"end":{"line":186,"column":null}},"53":{"start":{"line":187,"column":56},"end":{"line":187,"column":null}},"54":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"55":{"start":{"line":189,"column":2},"end":{"line":200,"column":null}},"56":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"57":{"start":{"line":190,"column":23},"end":{"line":190,"column":null}},"58":{"start":{"line":191,"column":17},"end":{"line":191,"column":null}},"59":{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},"60":{"start":{"line":192,"column":37},"end":{"line":192,"column":null}},"61":{"start":{"line":193,"column":19},"end":{"line":193,"column":null}},"62":{"start":{"line":194,"column":38},"end":{"line":194,"column":null}},"63":{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},"64":{"start":{"line":196,"column":6},"end":{"line":196,"column":null}},"65":{"start":{"line":198,"column":4},"end":{"line":198,"column":null}},"66":{"start":{"line":199,"column":4},"end":{"line":199,"column":null}},"67":{"start":{"line":201,"column":2},"end":{"line":201,"column":null}},"68":{"start":{"line":206,"column":2},"end":{"line":206,"column":null}},"69":{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},"70":{"start":{"line":208,"column":18},"end":{"line":208,"column":null}},"71":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"72":{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},"73":{"start":{"line":212,"column":4},"end":{"line":212,"column":null}},"74":{"start":{"line":213,"column":4},"end":{"line":213,"column":null}},"75":{"start":{"line":215,"column":35},"end":{"line":215,"column":null}},"76":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"77":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"78":{"start":{"line":219,"column":2},"end":{"line":221,"column":null}},"79":{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},"80":{"start":{"line":223,"column":4},"end":{"line":225,"column":null}},"81":{"start":{"line":226,"column":4},"end":{"line":226,"column":null}}},"fnMap":{"0":{"name":"parseCsv","decl":{"start":{"line":84,"column":9},"end":{"line":84,"column":18}},"loc":{"start":{"line":84,"column":49},"end":{"line":100,"column":null}},"line":84},"1":{"name":"(anonymous_1)","decl":{"start":{"line":87,"column":38},"end":{"line":87,"column":43}},"loc":{"start":{"line":87,"column":49},"end":{"line":87,"column":57}},"line":87},"2":{"name":"buildStatLookup","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":32}},"loc":{"start":{"line":110,"column":73},"end":{"line":127,"column":null}},"line":110},"3":{"name":"bakeHtml","decl":{"start":{"line":137,"column":16},"end":{"line":137,"column":null}},"loc":{"start":{"line":140,"column":38},"end":{"line":154,"column":null}},"line":140},"4":{"name":"(anonymous_4)","decl":{"start":{"line":147,"column":33},"end":{"line":147,"column":42}},"loc":{"start":{"line":147,"column":80},"end":{"line":152,"column":3}},"line":147},"5":{"name":"defaultFilter","decl":{"start":{"line":166,"column":9},"end":{"line":166,"column":23}},"loc":{"start":{"line":166,"column":45},"end":{"line":168,"column":null}},"line":166},"6":{"name":"bakeStatsHtml","decl":{"start":{"line":170,"column":16},"end":{"line":170,"column":30}},"loc":{"start":{"line":173,"column":2},"end":{"line":202,"column":null}},"line":173}},"branchMap":{"0":{"loc":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":86},"1":{"loc":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"2":{"loc":{"start":{"line":95,"column":25},"end":{"line":95,"column":39}},"type":"binary-expr","locations":[{"start":{"line":95,"column":25},"end":{"line":95,"column":37}},{"start":{"line":95,"column":37},"end":{"line":95,"column":39}}],"line":95},"3":{"loc":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"4":{"loc":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":116},"5":{"loc":{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":122},"6":{"loc":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":149},"7":{"loc":{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},"type":"if","locations":[{"start":{"line":174,"column":2},"end":{"line":176,"column":null}},{"start":{},"end":{}}],"line":174},"8":{"loc":{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":2},"end":{"line":183,"column":null}},{"start":{},"end":{}}],"line":179},"9":{"loc":{"start":{"line":185,"column":17},"end":{"line":185,"column":null}},"type":"binary-expr","locations":[{"start":{"line":185,"column":17},"end":{"line":185,"column":32}},{"start":{"line":185,"column":32},"end":{"line":185,"column":null}}],"line":185},"10":{"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"type":"if","locations":[{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},{"start":{},"end":{}}],"line":190},"11":{"loc":{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":192,"column":4},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":192},"12":{"loc":{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":195,"column":4},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":195},"13":{"loc":{"start":{"line":195,"column":8},"end":{"line":195,"column":42}},"type":"binary-expr","locations":[{"start":{"line":195,"column":8},"end":{"line":195,"column":24}},{"start":{"line":195,"column":24},"end":{"line":195,"column":42}}],"line":195},"14":{"loc":{"start":{"line":206,"column":2},"end":{"line":206,"column":null}},"type":"binary-expr","locations":[{"start":{"line":206,"column":2},"end":{"line":206,"column":21}},{"start":{"line":206,"column":21},"end":{"line":206,"column":null}}],"line":206},"15":{"loc":{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":0},"end":{"line":228,"column":null}},{"start":{},"end":{}}],"line":207},"16":{"loc":{"start":{"line":208,"column":18},"end":{"line":208,"column":null}},"type":"binary-expr","locations":[{"start":{"line":208,"column":18},"end":{"line":208,"column":37}},{"start":{"line":208,"column":37},"end":{"line":208,"column":null}}],"line":208},"17":{"loc":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"type":"binary-expr","locations":[{"start":{"line":210,"column":4},"end":{"line":210,"column":23}},{"start":{"line":210,"column":23},"end":{"line":210,"column":null}}],"line":210},"18":{"loc":{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":211,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":211},"19":{"loc":{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":2},"end":{"line":227,"column":null}},{"start":{},"end":{}}],"line":222}},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":1,"6":6,"7":1,"8":1,"9":1,"10":7,"11":7,"12":0,"13":7,"14":7,"15":7,"16":7,"17":42,"18":7,"19":1,"20":1,"21":1,"22":1,"23":7,"24":1,"25":6,"26":6,"27":0,"28":6,"29":1,"30":1,"31":21,"32":21,"33":6,"34":1,"35":3,"36":3,"37":3,"38":5,"39":5,"40":2,"41":3,"42":3,"43":3,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":1,"69":1,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0},"f":{"0":1,"1":6,"2":1,"3":3,"4":5,"5":0,"6":0},"b":{"0":[0,1],"1":[0,7],"2":[42,0],"3":[1,6],"4":[0,6],"5":[6,15],"6":[2,3],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[1,1],"15":[0,1],"16":[0,0],"17":[0,0],"18":[0,0],"19":[0,0]},"meta":{"lastBranch":20,"lastFunction":7,"lastStatement":82,"seen":{"s:38:19:38:Infinity":0,"s:45:63:71:Infinity":1,"f:84:9:84:18":0,"s:85:16:85:Infinity":2,"b:86:2:86:Infinity:undefined:undefined:undefined:undefined":0,"s:86:2:86:Infinity":3,"s:86:26:86:Infinity":4,"s:87:18:87:Infinity":5,"f:87:38:87:43":1,"s:87:49:87:57":6,"s:88:31:88:Infinity":7,"s:89:2:98:Infinity":8,"s:89:15:89:18":9,"s:90:16:90:Infinity":10,"b:91:4:91:Infinity:undefined:undefined:undefined:undefined":1,"s:91:4:91:Infinity":11,"s:91:14:91:Infinity":12,"s:92:18:92:Infinity":13,"s:93:40:93:Infinity":14,"s:94:4:96:Infinity":15,"s:94:17:94:20":16,"s:95:6:95:Infinity":17,"b:95:25:95:37:95:37:95:39":2,"s:97:4:97:Infinity":18,"s:99:2:99:Infinity":19,"f:110:16:110:32":2,"s:111:15:111:Infinity":20,"s:112:43:112:Infinity":21,"s:113:2:118:Infinity":22,"b:114:4:114:Infinity:undefined:undefined:undefined:undefined":3,"s:114:4:114:Infinity":23,"s:114:34:114:Infinity":24,"s:115:14:115:Infinity":25,"b:116:4:116:Infinity:undefined:undefined:undefined:undefined":4,"s:116:4:116:Infinity":26,"s:116:29:116:Infinity":27,"s:117:4:117:Infinity":28,"s:119:38:119:Infinity":29,"s:120:2:125:Infinity":30,"s:121:18:121:Infinity":31,"b:122:4:124:Infinity:undefined:undefined:undefined:undefined":5,"s:122:4:124:Infinity":32,"s:123:6:123:Infinity":33,"s:126:2:126:Infinity":34,"f:137:16:137:Infinity":3,"s:145:4:145:Infinity":35,"s:146:17:146:Infinity":36,"s:147:20:152:Infinity":37,"f:147:33:147:42":4,"s:148:18:148:Infinity":38,"b:149:4:149:Infinity:undefined:undefined:undefined:undefined":6,"s:149:4:149:Infinity":39,"s:149:29:149:Infinity":40,"s:150:4:150:Infinity":41,"s:151:4:151:Infinity":42,"s:153:2:153:Infinity":43,"f:166:9:166:23":5,"s:167:2:167:Infinity":44,"f:170:16:170:30":6,"b:174:2:176:Infinity:undefined:undefined:undefined:undefined":7,"s:174:2:176:Infinity":45,"s:175:4:175:Infinity":46,"s:177:18:177:Infinity":47,"s:178:17:178:Infinity":48,"b:179:2:183:Infinity:undefined:undefined:undefined:undefined":8,"s:179:2:183:Infinity":49,"s:180:4:182:Infinity":50,"s:185:17:185:Infinity":51,"b:185:17:185:32:185:32:185:Infinity":9,"s:186:18:186:Infinity":52,"s:187:56:187:Infinity":53,"s:188:22:188:Infinity":54,"s:189:2:200:Infinity":55,"b:190:4:190:Infinity:undefined:undefined:undefined:undefined":10,"s:190:4:190:Infinity":56,"s:190:23:190:Infinity":57,"s:191:17:191:Infinity":58,"b:192:4:192:Infinity:undefined:undefined:undefined:undefined":11,"s:192:4:192:Infinity":59,"s:192:37:192:Infinity":60,"s:193:19:193:Infinity":61,"s:194:38:194:Infinity":62,"b:195:4:197:Infinity:undefined:undefined:undefined:undefined":12,"s:195:4:197:Infinity":63,"b:195:8:195:24:195:24:195:42":13,"s:196:6:196:Infinity":64,"s:198:4:198:Infinity":65,"s:199:4:199:Infinity":66,"s:201:2:201:Infinity":67,"s:206:2:206:Infinity":68,"b:206:2:206:21:206:21:206:Infinity":14,"b:207:0:228:Infinity:undefined:undefined:undefined:undefined":15,"s:207:0:228:Infinity":69,"s:208:18:208:Infinity":70,"b:208:18:208:37:208:37:208:Infinity":16,"s:210:4:210:Infinity":71,"b:210:4:210:23:210:23:210:Infinity":17,"b:211:2:214:Infinity:undefined:undefined:undefined:undefined":18,"s:211:2:214:Infinity":72,"s:212:4:212:Infinity":73,"s:213:4:213:Infinity":74,"s:215:35:215:Infinity":75,"s:216:2:218:Infinity":76,"s:217:4:217:Infinity":77,"s:219:2:221:Infinity":78,"b:222:2:227:Infinity:undefined:undefined:undefined:undefined":19,"s:222:2:227:Infinity":79,"s:223:4:225:Infinity":80,"s:226:4:226:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-analysis-language.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-analysis-language.ts","statementMap":{"0":{"start":{"line":20,"column":24},"end":{"line":34,"column":null}},"1":{"start":{"line":37,"column":34},"end":{"line":37,"column":null}},"2":{"start":{"line":40,"column":28},"end":{"line":40,"column":null}},"3":{"start":{"line":57,"column":13},"end":{"line":57,"column":null}},"4":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"5":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"6":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"7":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"8":{"start":{"line":79,"column":2},"end":{"line":82,"column":null}},"9":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"10":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"11":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"12":{"start":{"line":93,"column":36},"end":{"line":93,"column":51}},"13":{"start":{"line":105,"column":18},"end":{"line":105,"column":null}},"14":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"15":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"16":{"start":{"line":109,"column":21},"end":{"line":109,"column":null}},"17":{"start":{"line":110,"column":29},"end":{"line":110,"column":null}},"18":{"start":{"line":110,"column":47},"end":{"line":110,"column":69}},"19":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"20":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"21":{"start":{"line":127,"column":26},"end":{"line":127,"column":null}},"22":{"start":{"line":130,"column":20},"end":{"line":130,"column":null}},"23":{"start":{"line":132,"column":4},"end":{"line":154,"column":null}},"24":{"start":{"line":133,"column":23},"end":{"line":133,"column":null}},"25":{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},"26":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"27":{"start":{"line":137,"column":66},"end":{"line":137,"column":null}},"28":{"start":{"line":138,"column":8},"end":{"line":138,"column":null}},"29":{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},"30":{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},"31":{"start":{"line":141,"column":63},"end":{"line":141,"column":null}},"32":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"33":{"start":{"line":144,"column":56},"end":{"line":144,"column":null}},"34":{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},"35":{"start":{"line":147,"column":56},"end":{"line":147,"column":null}},"36":{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},"37":{"start":{"line":150,"column":40},"end":{"line":150,"column":null}},"38":{"start":{"line":152,"column":8},"end":{"line":152,"column":null}},"39":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"40":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"41":{"start":{"line":174,"column":42},"end":{"line":174,"column":null}},"42":{"start":{"line":175,"column":16},"end":{"line":175,"column":null}},"43":{"start":{"line":177,"column":2},"end":{"line":190,"column":null}},"44":{"start":{"line":178,"column":56},"end":{"line":178,"column":null}},"45":{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},"46":{"start":{"line":182,"column":6},"end":{"line":188,"column":null}},"47":{"start":{"line":192,"column":2},"end":{"line":192,"column":null}},"48":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},"49":{"start":{"line":199,"column":31},"end":{"line":199,"column":null}},"50":{"start":{"line":201,"column":17},"end":{"line":201,"column":null}},"51":{"start":{"line":202,"column":20},"end":{"line":202,"column":null}},"52":{"start":{"line":203,"column":15},"end":{"line":205,"column":null}},"53":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"54":{"start":{"line":207,"column":2},"end":{"line":207,"column":null}},"55":{"start":{"line":223,"column":15},"end":{"line":223,"column":null}},"56":{"start":{"line":224,"column":22},"end":{"line":224,"column":null}},"57":{"start":{"line":227,"column":2},"end":{"line":236,"column":null}},"58":{"start":{"line":228,"column":18},"end":{"line":228,"column":null}},"59":{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},"60":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"61":{"start":{"line":231,"column":6},"end":{"line":231,"column":null}},"62":{"start":{"line":234,"column":4},"end":{"line":234,"column":null}},"63":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"64":{"start":{"line":238,"column":21},"end":{"line":238,"column":null}},"65":{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},"66":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"67":{"start":{"line":242,"column":4},"end":{"line":242,"column":null}},"68":{"start":{"line":243,"column":4},"end":{"line":243,"column":null}},"69":{"start":{"line":247,"column":21},"end":{"line":247,"column":null}},"70":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"71":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"72":{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},"73":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}}},"fnMap":{"0":{"name":"stripMarkdownCodeAndFrontmatter","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":48}},"loc":{"start":{"line":56,"column":73},"end":{"line":85,"column":null}},"line":56},"1":{"name":"tokenizeWords","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":30}},"loc":{"start":{"line":91,"column":54},"end":{"line":94,"column":null}},"line":91},"2":{"name":"(anonymous_2)","decl":{"start":{"line":93,"column":27},"end":{"line":93,"column":31}},"loc":{"start":{"line":93,"column":36},"end":{"line":93,"column":51}},"line":93},"3":{"name":"calculateSwedishDensity","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":40}},"loc":{"start":{"line":104,"column":2},"end":{"line":114,"column":null}},"line":104},"4":{"name":"(anonymous_4)","decl":{"start":{"line":110,"column":35},"end":{"line":110,"column":42}},"loc":{"start":{"line":110,"column":47},"end":{"line":110,"column":69}},"line":110},"5":{"name":"findAnalysisMarkdownFiles","decl":{"start":{"line":126,"column":16},"end":{"line":126,"column":42}},"loc":{"start":{"line":126,"column":65},"end":{"line":159,"column":null}},"line":126},"6":{"name":"walk","decl":{"start":{"line":129,"column":11},"end":{"line":129,"column":16}},"loc":{"start":{"line":129,"column":36},"end":{"line":155,"column":null}},"line":129},"7":{"name":"validateAnalysisLanguage","decl":{"start":{"line":173,"column":16},"end":{"line":173,"column":41}},"loc":{"start":{"line":173,"column":83},"end":{"line":193,"column":null}},"line":173},"8":{"name":"formatViolationTable","decl":{"start":{"line":198,"column":16},"end":{"line":198,"column":37}},"loc":{"start":{"line":198,"column":78},"end":{"line":208,"column":null}},"line":198},"9":{"name":"(anonymous_9)","decl":{"start":{"line":203,"column":26},"end":{"line":203,"column":30}},"loc":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"line":204},"10":{"name":"main","decl":{"start":{"line":222,"column":22},"end":{"line":222,"column":29}},"loc":{"start":{"line":222,"column":29},"end":{"line":250,"column":null}},"line":222}},"branchMap":{"0":{"loc":{"start":{"line":93,"column":9},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":19},"end":{"line":93,"column":55}},{"start":{"line":93,"column":55},"end":{"line":93,"column":null}}],"line":93},"1":{"loc":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":35},"end":{"line":111,"column":69}},{"start":{"line":111,"column":69},"end":{"line":111,"column":null}}],"line":111},"2":{"loc":{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":6},"end":{"line":153,"column":null}},{"start":{"line":139,"column":13},"end":{"line":153,"column":null}}],"line":135},"3":{"loc":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":137},"4":{"loc":{"start":{"line":137,"column":12},"end":{"line":137,"column":66}},"type":"binary-expr","locations":[{"start":{"line":137,"column":12},"end":{"line":137,"column":38}},{"start":{"line":137,"column":38},"end":{"line":137,"column":66}}],"line":137},"5":{"loc":{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":13},"end":{"line":153,"column":null}},{"start":{},"end":{}}],"line":139},"6":{"loc":{"start":{"line":139,"column":17},"end":{"line":139,"column":63}},"type":"binary-expr","locations":[{"start":{"line":139,"column":17},"end":{"line":139,"column":35}},{"start":{"line":139,"column":35},"end":{"line":139,"column":63}}],"line":139},"7":{"loc":{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"8":{"loc":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},{"start":{},"end":{}}],"line":144},"9":{"loc":{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":147},"10":{"loc":{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},"type":"if","locations":[{"start":{"line":150,"column":8},"end":{"line":150,"column":null}},{"start":{},"end":{}}],"line":150},"11":{"loc":{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":4},"end":{"line":189,"column":null}},{"start":{},"end":{}}],"line":181},"12":{"loc":{"start":{"line":181,"column":8},"end":{"line":181,"column":90}},"type":"binary-expr","locations":[{"start":{"line":181,"column":8},"end":{"line":181,"column":47}},{"start":{"line":181,"column":47},"end":{"line":181,"column":90}}],"line":181},"13":{"loc":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},"type":"if","locations":[{"start":{"line":199,"column":2},"end":{"line":199,"column":null}},{"start":{},"end":{}}],"line":199},"14":{"loc":{"start":{"line":224,"column":22},"end":{"line":224,"column":null}},"type":"cond-expr","locations":[{"start":{"line":224,"column":61},"end":{"line":224,"column":71}},{"start":{"line":224,"column":71},"end":{"line":224,"column":null}}],"line":224},"15":{"loc":{"start":{"line":224,"column":22},"end":{"line":224,"column":61}},"type":"binary-expr","locations":[{"start":{"line":224,"column":22},"end":{"line":224,"column":33}},{"start":{"line":224,"column":33},"end":{"line":224,"column":61}}],"line":224},"16":{"loc":{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},"type":"if","locations":[{"start":{"line":229,"column":4},"end":{"line":232,"column":null}},{"start":{},"end":{}}],"line":229},"17":{"loc":{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":240},"18":{"loc":{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},"type":"if","locations":[{"start":{"line":253,"column":0},"end":{"line":255,"column":null}},{"start":{},"end":{}}],"line":253}},"s":{"0":3,"1":3,"2":3,"3":1205,"4":1205,"5":1205,"6":1205,"7":1205,"8":1205,"9":1205,"10":1204,"11":1204,"12":45361,"13":11,"14":11,"15":11,"16":11,"17":11,"18":214,"19":11,"20":11,"21":12,"22":12,"23":12,"24":20,"25":20,"26":2,"27":2,"28":0,"29":18,"30":18,"31":3,"32":15,"33":0,"34":15,"35":1,"36":14,"37":0,"38":14,"39":12,"40":12,"41":7,"42":7,"43":7,"44":8,"45":8,"46":2,"47":7,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":3,"73":0},"f":{"0":1205,"1":1204,"2":45361,"3":11,"4":214,"5":12,"6":12,"7":7,"8":0,"9":0,"10":0},"b":{"0":[1202,2],"1":[10,1],"2":[2,18],"3":[2,0],"4":[2,1],"5":[18,0],"6":[18,18],"7":[3,15],"8":[0,15],"9":[1,14],"10":[0,14],"11":[2,6],"12":[8,3],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0],"18":[0,3]},"meta":{"lastBranch":19,"lastFunction":11,"lastStatement":74,"seen":{"s:20:24:34:Infinity":0,"s:37:34:37:Infinity":1,"s:40:28:40:Infinity":2,"f:56:16:56:48":0,"s:57:13:57:Infinity":3,"s:63:2:63:Infinity":4,"s:66:2:66:Infinity":5,"s:69:2:69:Infinity":6,"s:73:2:73:Infinity":7,"s:79:2:82:Infinity":8,"s:84:2:84:Infinity":9,"f:91:16:91:30":1,"s:92:18:92:Infinity":10,"s:93:2:93:Infinity":11,"b:93:19:93:55:93:55:93:Infinity":0,"f:93:27:93:31":2,"s:93:36:93:51":12,"f:100:16:100:40":3,"s:105:18:105:Infinity":13,"s:106:16:106:Infinity":14,"s:107:16:107:Infinity":15,"s:109:21:109:Infinity":16,"s:110:29:110:Infinity":17,"f:110:35:110:42":4,"s:110:47:110:69":18,"s:111:18:111:Infinity":19,"b:111:35:111:69:111:69:111:Infinity":1,"s:113:2:113:Infinity":20,"f:126:16:126:42":5,"s:127:26:127:Infinity":21,"f:129:11:129:16":6,"s:130:20:130:Infinity":22,"s:132:4:154:Infinity":23,"s:133:23:133:Infinity":24,"b:135:6:153:Infinity:139:13:153:Infinity":2,"s:135:6:153:Infinity":25,"b:137:8:137:Infinity:undefined:undefined:undefined:undefined":3,"s:137:8:137:Infinity":26,"b:137:12:137:38:137:38:137:66":4,"s:137:66:137:Infinity":27,"s:138:8:138:Infinity":28,"b:139:13:153:Infinity:undefined:undefined:undefined:undefined":5,"s:139:13:153:Infinity":29,"b:139:17:139:35:139:35:139:63":6,"b:141:8:141:Infinity:undefined:undefined:undefined:undefined":7,"s:141:8:141:Infinity":30,"s:141:63:141:Infinity":31,"b:144:8:144:Infinity:undefined:undefined:undefined:undefined":8,"s:144:8:144:Infinity":32,"s:144:56:144:Infinity":33,"b:147:8:147:Infinity:undefined:undefined:undefined:undefined":9,"s:147:8:147:Infinity":34,"s:147:56:147:Infinity":35,"b:150:8:150:Infinity:undefined:undefined:undefined:undefined":10,"s:150:8:150:Infinity":36,"s:150:40:150:Infinity":37,"s:152:8:152:Infinity":38,"s:157:2:157:Infinity":39,"s:158:2:158:Infinity":40,"f:173:16:173:41":7,"s:174:42:174:Infinity":41,"s:175:16:175:Infinity":42,"s:177:2:190:Infinity":43,"s:178:56:178:Infinity":44,"b:181:4:189:Infinity:undefined:undefined:undefined:undefined":11,"s:181:4:189:Infinity":45,"b:181:8:181:47:181:47:181:90":12,"s:182:6:188:Infinity":46,"s:192:2:192:Infinity":47,"f:198:16:198:37":8,"b:199:2:199:Infinity:undefined:undefined:undefined:undefined":13,"s:199:2:199:Infinity":48,"s:199:31:199:Infinity":49,"s:201:17:201:Infinity":50,"s:202:20:202:Infinity":51,"s:203:15:205:Infinity":52,"f:203:26:203:30":9,"s:204:4:204:Infinity":53,"s:207:2:207:Infinity":54,"f:222:22:222:29":10,"s:223:15:223:Infinity":55,"s:224:22:224:Infinity":56,"b:224:61:224:71:224:71:224:Infinity":14,"b:224:22:224:33:224:33:224:61":15,"s:227:2:236:Infinity":57,"s:228:18:228:Infinity":58,"b:229:4:232:Infinity:undefined:undefined:undefined:undefined":16,"s:229:4:232:Infinity":59,"s:230:6:230:Infinity":60,"s:231:6:231:Infinity":61,"s:234:4:234:Infinity":62,"s:235:4:235:Infinity":63,"s:238:21:238:Infinity":64,"b:240:2:244:Infinity:undefined:undefined:undefined:undefined":17,"s:240:2:244:Infinity":65,"s:241:4:241:Infinity":66,"s:242:4:242:Infinity":67,"s:243:4:243:Infinity":68,"s:247:21:247:Infinity":69,"s:248:2:248:Infinity":70,"s:249:2:249:Infinity":71,"b:253:0:255:Infinity:undefined:undefined:undefined:undefined":18,"s:253:0:255:Infinity":72,"s:254:2:254:Infinity":73}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-brief-language.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-brief-language.ts","statementMap":{"0":{"start":{"line":62,"column":52},"end":{"line":79,"column":null}},"1":{"start":{"line":100,"column":41},"end":{"line":100,"column":null}},"2":{"start":{"line":101,"column":45},"end":{"line":101,"column":null}},"3":{"start":{"line":102,"column":45},"end":{"line":102,"column":null}},"4":{"start":{"line":105,"column":35},"end":{"line":105,"column":null}},"5":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"6":{"start":{"line":111,"column":18},"end":{"line":111,"column":null}},"7":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"8":{"start":{"line":119,"column":27},"end":{"line":119,"column":null}},"9":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"10":{"start":{"line":120,"column":27},"end":{"line":120,"column":null}},"11":{"start":{"line":121,"column":2},"end":{"line":121,"column":null}},"12":{"start":{"line":141,"column":16},"end":{"line":141,"column":null}},"13":{"start":{"line":142,"column":16},"end":{"line":142,"column":null}},"14":{"start":{"line":143,"column":21},"end":{"line":143,"column":null}},"15":{"start":{"line":144,"column":29},"end":{"line":144,"column":null}},"16":{"start":{"line":144,"column":49},"end":{"line":144,"column":71}},"17":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"18":{"start":{"line":146,"column":2},"end":{"line":146,"column":null}},"19":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"20":{"start":{"line":154,"column":56},"end":{"line":154,"column":null}},"21":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"22":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"23":{"start":{"line":172,"column":22},"end":{"line":172,"column":null}},"24":{"start":{"line":181,"column":27},"end":{"line":181,"column":null}},"25":{"start":{"line":184,"column":4},"end":{"line":188,"column":null}},"26":{"start":{"line":185,"column":6},"end":{"line":185,"column":null}},"27":{"start":{"line":187,"column":6},"end":{"line":187,"column":null}},"28":{"start":{"line":189,"column":4},"end":{"line":198,"column":null}},"29":{"start":{"line":190,"column":23},"end":{"line":190,"column":null}},"30":{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},"31":{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},"32":{"start":{"line":192,"column":66},"end":{"line":192,"column":null}},"33":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"34":{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},"35":{"start":{"line":195,"column":18},"end":{"line":195,"column":null}},"36":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"37":{"start":{"line":196,"column":32},"end":{"line":196,"column":null}},"38":{"start":{"line":200,"column":2},"end":{"line":200,"column":null}},"39":{"start":{"line":201,"column":2},"end":{"line":201,"column":null}},"40":{"start":{"line":219,"column":47},"end":{"line":219,"column":null}},"41":{"start":{"line":220,"column":17},"end":{"line":220,"column":null}},"42":{"start":{"line":222,"column":2},"end":{"line":240,"column":null}},"43":{"start":{"line":224,"column":4},"end":{"line":228,"column":null}},"44":{"start":{"line":225,"column":6},"end":{"line":225,"column":null}},"45":{"start":{"line":227,"column":6},"end":{"line":227,"column":null}},"46":{"start":{"line":229,"column":20},"end":{"line":229,"column":null}},"47":{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},"48":{"start":{"line":231,"column":6},"end":{"line":238,"column":null}},"49":{"start":{"line":241,"column":2},"end":{"line":241,"column":null}},"50":{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},"51":{"start":{"line":245,"column":31},"end":{"line":245,"column":null}},"52":{"start":{"line":246,"column":26},"end":{"line":246,"column":null}},"53":{"start":{"line":247,"column":2},"end":{"line":254,"column":null}},"54":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"55":{"start":{"line":249,"column":4},"end":{"line":252,"column":null}},"56":{"start":{"line":253,"column":4},"end":{"line":253,"column":null}},"57":{"start":{"line":255,"column":2},"end":{"line":255,"column":null}},"58":{"start":{"line":275,"column":15},"end":{"line":275,"column":null}},"59":{"start":{"line":276,"column":22},"end":{"line":276,"column":null}},"60":{"start":{"line":278,"column":2},"end":{"line":287,"column":null}},"61":{"start":{"line":279,"column":18},"end":{"line":279,"column":null}},"62":{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},"63":{"start":{"line":281,"column":6},"end":{"line":281,"column":null}},"64":{"start":{"line":282,"column":6},"end":{"line":282,"column":null}},"65":{"start":{"line":285,"column":4},"end":{"line":285,"column":null}},"66":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"67":{"start":{"line":289,"column":21},"end":{"line":289,"column":null}},"68":{"start":{"line":290,"column":23},"end":{"line":290,"column":null}},"69":{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},"70":{"start":{"line":293,"column":4},"end":{"line":295,"column":null}},"71":{"start":{"line":296,"column":4},"end":{"line":296,"column":null}},"72":{"start":{"line":297,"column":4},"end":{"line":302,"column":null}},"73":{"start":{"line":303,"column":4},"end":{"line":303,"column":null}},"74":{"start":{"line":306,"column":2},"end":{"line":308,"column":null}},"75":{"start":{"line":309,"column":2},"end":{"line":309,"column":null}},"76":{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},"77":{"start":{"line":314,"column":2},"end":{"line":314,"column":null}}},"fnMap":{"0":{"name":"thresholdForLanguage","decl":{"start":{"line":118,"column":16},"end":{"line":118,"column":37}},"loc":{"start":{"line":118,"column":59},"end":{"line":122,"column":null}},"line":118},"1":{"name":"calculateEnglishDensity","decl":{"start":{"line":140,"column":16},"end":{"line":140,"column":40}},"loc":{"start":{"line":140,"column":74},"end":{"line":147,"column":null}},"line":140},"2":{"name":"(anonymous_2)","decl":{"start":{"line":144,"column":35},"end":{"line":144,"column":43}},"loc":{"start":{"line":144,"column":49},"end":{"line":144,"column":71}},"line":144},"3":{"name":"exceedsEnglishThreshold","decl":{"start":{"line":153,"column":16},"end":{"line":153,"column":40}},"loc":{"start":{"line":153,"column":88},"end":{"line":157,"column":null}},"line":153},"4":{"name":"findTranslatedBriefs","decl":{"start":{"line":180,"column":16},"end":{"line":180,"column":37}},"loc":{"start":{"line":180,"column":63},"end":{"line":202,"column":null}},"line":180},"5":{"name":"walk","decl":{"start":{"line":182,"column":11},"end":{"line":182,"column":16}},"loc":{"start":{"line":182,"column":42},"end":{"line":199,"column":null}},"line":182},"6":{"name":"validateBriefLanguages","decl":{"start":{"line":218,"column":16},"end":{"line":218,"column":39}},"loc":{"start":{"line":218,"column":86},"end":{"line":242,"column":null}},"line":218},"7":{"name":"formatViolationReport","decl":{"start":{"line":244,"column":16},"end":{"line":244,"column":38}},"loc":{"start":{"line":244,"column":93},"end":{"line":256,"column":null}},"line":244},"8":{"name":"main","decl":{"start":{"line":274,"column":22},"end":{"line":274,"column":44}},"loc":{"start":{"line":274,"column":44},"end":{"line":310,"column":null}},"line":274}},"branchMap":{"0":{"loc":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},{"start":{},"end":{}}],"line":119},"1":{"loc":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":120},"2":{"loc":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":35},"end":{"line":145,"column":69}},{"start":{"line":145,"column":69},"end":{"line":145,"column":null}}],"line":145},"3":{"loc":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":154},"4":{"loc":{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":191,"column":6},"end":{"line":197,"column":null}},{"start":{"line":194,"column":13},"end":{"line":197,"column":null}}],"line":191},"5":{"loc":{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":192,"column":8},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":192},"6":{"loc":{"start":{"line":192,"column":12},"end":{"line":192,"column":66}},"type":"binary-expr","locations":[{"start":{"line":192,"column":12},"end":{"line":192,"column":38}},{"start":{"line":192,"column":38},"end":{"line":192,"column":66}}],"line":192},"7":{"loc":{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":194,"column":13},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":194},"8":{"loc":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":196},"9":{"loc":{"start":{"line":196,"column":12},"end":{"line":196,"column":32}},"type":"binary-expr","locations":[{"start":{"line":196,"column":12},"end":{"line":196,"column":17}},{"start":{"line":196,"column":17},"end":{"line":196,"column":32}}],"line":196},"10":{"loc":{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},"type":"if","locations":[{"start":{"line":230,"column":4},"end":{"line":239,"column":null}},{"start":{},"end":{}}],"line":230},"11":{"loc":{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},"type":"if","locations":[{"start":{"line":245,"column":2},"end":{"line":245,"column":null}},{"start":{},"end":{}}],"line":245},"12":{"loc":{"start":{"line":276,"column":22},"end":{"line":276,"column":null}},"type":"cond-expr","locations":[{"start":{"line":276,"column":61},"end":{"line":276,"column":71}},{"start":{"line":276,"column":71},"end":{"line":276,"column":null}}],"line":276},"13":{"loc":{"start":{"line":276,"column":22},"end":{"line":276,"column":61}},"type":"binary-expr","locations":[{"start":{"line":276,"column":22},"end":{"line":276,"column":33}},{"start":{"line":276,"column":33},"end":{"line":276,"column":61}}],"line":276},"14":{"loc":{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":4},"end":{"line":283,"column":null}},{"start":{},"end":{}}],"line":280},"15":{"loc":{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},"type":"if","locations":[{"start":{"line":292,"column":2},"end":{"line":304,"column":null}},{"start":{},"end":{}}],"line":292},"16":{"loc":{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":0},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":313}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":14,"8":3,"9":11,"10":11,"11":8,"12":1190,"13":1190,"14":1190,"15":1190,"16":45140,"17":1190,"18":1190,"19":16,"20":2,"21":14,"22":14,"23":2,"24":5,"25":15,"26":15,"27":0,"28":15,"29":21,"30":21,"31":12,"32":2,"33":10,"34":9,"35":9,"36":9,"37":6,"38":5,"39":5,"40":3,"41":3,"42":3,"43":3,"44":3,"45":0,"46":3,"47":3,"48":2,"49":3,"50":2,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":2,"77":0},"f":{"0":14,"1":1190,"2":45140,"3":16,"4":5,"5":15,"6":3,"7":2,"8":0},"b":{"0":[3,11],"1":[3,8],"2":[1190,0],"3":[2,14],"4":[12,9],"5":[2,10],"6":[12,11],"7":[9,0],"8":[6,3],"9":[9,7],"10":[2,1],"11":[1,1],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,2]},"meta":{"lastBranch":17,"lastFunction":9,"lastStatement":78,"seen":{"s:62:52:79:Infinity":0,"s:100:41:100:Infinity":1,"s:101:45:101:Infinity":2,"s:102:45:102:Infinity":3,"s:105:35:105:Infinity":4,"s:108:18:108:Infinity":5,"s:111:18:111:Infinity":6,"f:118:16:118:37":0,"b:119:2:119:Infinity:undefined:undefined:undefined:undefined":0,"s:119:2:119:Infinity":7,"s:119:27:119:Infinity":8,"b:120:2:120:Infinity:undefined:undefined:undefined:undefined":1,"s:120:2:120:Infinity":9,"s:120:27:120:Infinity":10,"s:121:2:121:Infinity":11,"f:140:16:140:40":1,"s:141:16:141:Infinity":12,"s:142:16:142:Infinity":13,"s:143:21:143:Infinity":14,"s:144:29:144:Infinity":15,"f:144:35:144:43":2,"s:144:49:144:71":16,"s:145:18:145:Infinity":17,"b:145:35:145:69:145:69:145:Infinity":2,"s:146:2:146:Infinity":18,"f:153:16:153:40":3,"b:154:2:154:Infinity:undefined:undefined:undefined:undefined":3,"s:154:2:154:Infinity":19,"s:154:56:154:Infinity":20,"s:155:20:155:Infinity":21,"s:156:2:156:Infinity":22,"s:172:22:172:Infinity":23,"f:180:16:180:37":4,"s:181:27:181:Infinity":24,"f:182:11:182:16":5,"s:184:4:188:Infinity":25,"s:185:6:185:Infinity":26,"s:187:6:187:Infinity":27,"s:189:4:198:Infinity":28,"s:190:23:190:Infinity":29,"b:191:6:197:Infinity:194:13:197:Infinity":4,"s:191:6:197:Infinity":30,"b:192:8:192:Infinity:undefined:undefined:undefined:undefined":5,"s:192:8:192:Infinity":31,"b:192:12:192:38:192:38:192:66":6,"s:192:66:192:Infinity":32,"s:193:8:193:Infinity":33,"b:194:13:197:Infinity:undefined:undefined:undefined:undefined":7,"s:194:13:197:Infinity":34,"s:195:18:195:Infinity":35,"b:196:8:196:Infinity:undefined:undefined:undefined:undefined":8,"s:196:8:196:Infinity":36,"b:196:12:196:17:196:17:196:32":9,"s:196:32:196:Infinity":37,"s:200:2:200:Infinity":38,"s:201:2:201:Infinity":39,"f:218:16:218:39":6,"s:219:47:219:Infinity":40,"s:220:17:220:Infinity":41,"s:222:2:240:Infinity":42,"s:224:4:228:Infinity":43,"s:225:6:225:Infinity":44,"s:227:6:227:Infinity":45,"s:229:20:229:Infinity":46,"b:230:4:239:Infinity:undefined:undefined:undefined:undefined":10,"s:230:4:239:Infinity":47,"s:231:6:238:Infinity":48,"s:241:2:241:Infinity":49,"f:244:16:244:38":7,"b:245:2:245:Infinity:undefined:undefined:undefined:undefined":11,"s:245:2:245:Infinity":50,"s:245:31:245:Infinity":51,"s:246:26:246:Infinity":52,"s:247:2:254:Infinity":53,"s:248:4:248:Infinity":54,"s:249:4:252:Infinity":55,"s:253:4:253:Infinity":56,"s:255:2:255:Infinity":57,"f:274:22:274:44":8,"s:275:15:275:Infinity":58,"s:276:22:276:Infinity":59,"b:276:61:276:71:276:71:276:Infinity":12,"b:276:22:276:33:276:33:276:61":13,"s:278:2:287:Infinity":60,"s:279:18:279:Infinity":61,"b:280:4:283:Infinity:undefined:undefined:undefined:undefined":14,"s:280:4:283:Infinity":62,"s:281:6:281:Infinity":63,"s:282:6:282:Infinity":64,"s:285:4:285:Infinity":65,"s:286:4:286:Infinity":66,"s:289:21:289:Infinity":67,"s:290:23:290:Infinity":68,"b:292:2:304:Infinity:undefined:undefined:undefined:undefined":15,"s:292:2:304:Infinity":69,"s:293:4:295:Infinity":70,"s:296:4:296:Infinity":71,"s:297:4:302:Infinity":72,"s:303:4:303:Infinity":73,"s:306:2:308:Infinity":74,"s:309:2:309:Infinity":75,"b:313:0:315:Infinity:undefined:undefined:undefined:undefined":16,"s:313:0:315:Infinity":76,"s:314:2:314:Infinity":77}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-headline-quality.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-headline-quality.ts","statementMap":{"0":{"start":{"line":66,"column":2},"end":{"line":70,"column":null}},"1":{"start":{"line":69,"column":19},"end":{"line":69,"column":63}},"2":{"start":{"line":95,"column":39},"end":{"line":130,"column":null}},"3":{"start":{"line":134,"column":18},"end":{"line":134,"column":null}},"4":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"5":{"start":{"line":135,"column":16},"end":{"line":135,"column":null}},"6":{"start":{"line":136,"column":15},"end":{"line":136,"column":null}},"7":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"8":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"9":{"start":{"line":138,"column":42},"end":{"line":138,"column":null}},"10":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"11":{"start":{"line":156,"column":2},"end":{"line":156,"column":null}},"12":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"13":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"14":{"start":{"line":161,"column":28},"end":{"line":161,"column":null}},"15":{"start":{"line":164,"column":15},"end":{"line":164,"column":null}},"16":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"17":{"start":{"line":172,"column":28},"end":{"line":172,"column":null}},"18":{"start":{"line":177,"column":29},"end":{"line":177,"column":null}},"19":{"start":{"line":180,"column":2},"end":{"line":183,"column":null}},"20":{"start":{"line":202,"column":93},"end":{"line":209,"column":null}},"21":{"start":{"line":212,"column":25},"end":{"line":212,"column":null}},"22":{"start":{"line":213,"column":2},"end":{"line":215,"column":null}},"23":{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},"24":{"start":{"line":214,"column":21},"end":{"line":214,"column":null}},"25":{"start":{"line":216,"column":2},"end":{"line":216,"column":null}},"26":{"start":{"line":231,"column":2},"end":{"line":235,"column":null}},"27":{"start":{"line":248,"column":15},"end":{"line":248,"column":null}},"28":{"start":{"line":249,"column":14},"end":{"line":249,"column":null}},"29":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"30":{"start":{"line":250,"column":41},"end":{"line":250,"column":null}},"31":{"start":{"line":253,"column":16},"end":{"line":253,"column":null}},"32":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},"33":{"start":{"line":254,"column":26},"end":{"line":254,"column":null}},"34":{"start":{"line":255,"column":2},"end":{"line":255,"column":null}},"35":{"start":{"line":264,"column":2},"end":{"line":268,"column":null}},"36":{"start":{"line":267,"column":18},"end":{"line":267,"column":42}},"37":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"38":{"start":{"line":280,"column":18},"end":{"line":280,"column":null}},"39":{"start":{"line":281,"column":19},"end":{"line":281,"column":null}},"40":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"41":{"start":{"line":282,"column":17},"end":{"line":282,"column":null}},"42":{"start":{"line":283,"column":20},"end":{"line":283,"column":null}},"43":{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},"44":{"start":{"line":284,"column":43},"end":{"line":284,"column":null}},"45":{"start":{"line":285,"column":19},"end":{"line":285,"column":null}},"46":{"start":{"line":286,"column":15},"end":{"line":286,"column":null}},"47":{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},"48":{"start":{"line":287,"column":13},"end":{"line":287,"column":null}},"49":{"start":{"line":288,"column":20},"end":{"line":288,"column":null}},"50":{"start":{"line":289,"column":2},"end":{"line":289,"column":null}},"51":{"start":{"line":305,"column":15},"end":{"line":305,"column":null}},"52":{"start":{"line":306,"column":12},"end":{"line":306,"column":null}},"53":{"start":{"line":307,"column":2},"end":{"line":307,"column":null}},"54":{"start":{"line":321,"column":24},"end":{"line":321,"column":null}},"55":{"start":{"line":324,"column":4},"end":{"line":328,"column":null}},"56":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"57":{"start":{"line":327,"column":6},"end":{"line":327,"column":null}},"58":{"start":{"line":329,"column":4},"end":{"line":337,"column":null}},"59":{"start":{"line":330,"column":23},"end":{"line":330,"column":null}},"60":{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},"61":{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},"62":{"start":{"line":332,"column":66},"end":{"line":332,"column":null}},"63":{"start":{"line":333,"column":8},"end":{"line":333,"column":null}},"64":{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},"65":{"start":{"line":335,"column":8},"end":{"line":335,"column":null}},"66":{"start":{"line":339,"column":2},"end":{"line":339,"column":null}},"67":{"start":{"line":340,"column":2},"end":{"line":340,"column":null}},"68":{"start":{"line":366,"column":27},"end":{"line":366,"column":null}},"69":{"start":{"line":369,"column":22},"end":{"line":369,"column":null}},"70":{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},"71":{"start":{"line":371,"column":4},"end":{"line":371,"column":null}},"72":{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},"73":{"start":{"line":376,"column":4},"end":{"line":376,"column":null}},"74":{"start":{"line":380,"column":14},"end":{"line":380,"column":null}},"75":{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},"76":{"start":{"line":382,"column":4},"end":{"line":382,"column":null}},"77":{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},"78":{"start":{"line":385,"column":4},"end":{"line":385,"column":null}},"79":{"start":{"line":389,"column":22},"end":{"line":389,"column":null}},"80":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"81":{"start":{"line":391,"column":4},"end":{"line":391,"column":null}},"82":{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},"83":{"start":{"line":396,"column":4},"end":{"line":398,"column":null}},"84":{"start":{"line":401,"column":2},"end":{"line":401,"column":null}},"85":{"start":{"line":406,"column":42},"end":{"line":406,"column":null}},"86":{"start":{"line":407,"column":17},"end":{"line":407,"column":null}},"87":{"start":{"line":409,"column":2},"end":{"line":428,"column":null}},"88":{"start":{"line":411,"column":4},"end":{"line":415,"column":null}},"89":{"start":{"line":412,"column":6},"end":{"line":412,"column":null}},"90":{"start":{"line":414,"column":6},"end":{"line":414,"column":null}},"91":{"start":{"line":416,"column":15},"end":{"line":416,"column":null}},"92":{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},"93":{"start":{"line":417,"column":13},"end":{"line":417,"column":null}},"94":{"start":{"line":418,"column":22},"end":{"line":418,"column":null}},"95":{"start":{"line":419,"column":19},"end":{"line":419,"column":null}},"96":{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},"97":{"start":{"line":421,"column":6},"end":{"line":426,"column":null}},"98":{"start":{"line":429,"column":2},"end":{"line":429,"column":null}},"99":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"100":{"start":{"line":433,"column":31},"end":{"line":433,"column":null}},"101":{"start":{"line":434,"column":26},"end":{"line":434,"column":null}},"102":{"start":{"line":435,"column":2},"end":{"line":442,"column":null}},"103":{"start":{"line":436,"column":4},"end":{"line":436,"column":null}},"104":{"start":{"line":437,"column":4},"end":{"line":437,"column":null}},"105":{"start":{"line":438,"column":4},"end":{"line":440,"column":null}},"106":{"start":{"line":439,"column":6},"end":{"line":439,"column":null}},"107":{"start":{"line":441,"column":4},"end":{"line":441,"column":null}},"108":{"start":{"line":443,"column":2},"end":{"line":443,"column":null}},"109":{"start":{"line":462,"column":15},"end":{"line":462,"column":null}},"110":{"start":{"line":463,"column":22},"end":{"line":463,"column":null}},"111":{"start":{"line":465,"column":2},"end":{"line":474,"column":null}},"112":{"start":{"line":466,"column":18},"end":{"line":466,"column":null}},"113":{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},"114":{"start":{"line":468,"column":6},"end":{"line":468,"column":null}},"115":{"start":{"line":469,"column":6},"end":{"line":469,"column":null}},"116":{"start":{"line":472,"column":4},"end":{"line":472,"column":null}},"117":{"start":{"line":473,"column":4},"end":{"line":473,"column":null}},"118":{"start":{"line":476,"column":21},"end":{"line":476,"column":null}},"119":{"start":{"line":477,"column":23},"end":{"line":477,"column":null}},"120":{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},"121":{"start":{"line":480,"column":4},"end":{"line":482,"column":null}},"122":{"start":{"line":483,"column":4},"end":{"line":483,"column":null}},"123":{"start":{"line":484,"column":4},"end":{"line":492,"column":null}},"124":{"start":{"line":493,"column":4},"end":{"line":493,"column":null}},"125":{"start":{"line":496,"column":2},"end":{"line":496,"column":null}},"126":{"start":{"line":497,"column":2},"end":{"line":497,"column":null}},"127":{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},"128":{"start":{"line":502,"column":2},"end":{"line":502,"column":null}}},"fnMap":{"0":{"name":"prettifySlugSegment","decl":{"start":{"line":65,"column":9},"end":{"line":65,"column":29}},"loc":{"start":{"line":65,"column":54},"end":{"line":71,"column":null}},"line":65},"1":{"name":"(anonymous_1)","decl":{"start":{"line":69,"column":5},"end":{"line":69,"column":10}},"loc":{"start":{"line":69,"column":19},"end":{"line":69,"column":63}},"line":69},"2":{"name":"findSwedishHeadlineTokens","decl":{"start":{"line":133,"column":16},"end":{"line":133,"column":42}},"loc":{"start":{"line":133,"column":64},"end":{"line":141,"column":null}},"line":133},"3":{"name":"hasWeekdayDatePrefix","decl":{"start":{"line":160,"column":16},"end":{"line":160,"column":37}},"loc":{"start":{"line":160,"column":58},"end":{"line":166,"column":null}},"line":160},"4":{"name":"hasIsoDateAffix","decl":{"start":{"line":179,"column":16},"end":{"line":179,"column":32}},"loc":{"start":{"line":179,"column":85},"end":{"line":184,"column":null}},"line":179},"5":{"name":"findBoilerplatePrefixes","decl":{"start":{"line":211,"column":16},"end":{"line":211,"column":40}},"loc":{"start":{"line":211,"column":62},"end":{"line":217,"column":null}},"line":211},"6":{"name":"normaliseHeadlineForCompare","decl":{"start":{"line":230,"column":16},"end":{"line":230,"column":44}},"loc":{"start":{"line":230,"column":66},"end":{"line":236,"column":null}},"line":230},"7":{"name":"subfolderFromBriefPath","decl":{"start":{"line":247,"column":16},"end":{"line":247,"column":39}},"loc":{"start":{"line":247,"column":72},"end":{"line":256,"column":null}},"line":247},"8":{"name":"prettifySubfolderPath","decl":{"start":{"line":263,"column":16},"end":{"line":263,"column":38}},"loc":{"start":{"line":263,"column":65},"end":{"line":269,"column":null}},"line":263},"9":{"name":"(anonymous_9)","decl":{"start":{"line":267,"column":5},"end":{"line":267,"column":10}},"loc":{"start":{"line":267,"column":18},"end":{"line":267,"column":42}},"line":267},"10":{"name":"matchesPrettifiedSubfolder","decl":{"start":{"line":279,"column":16},"end":{"line":279,"column":43}},"loc":{"start":{"line":279,"column":90},"end":{"line":290,"column":null}},"line":279},"11":{"name":"extractH1","decl":{"start":{"line":302,"column":16},"end":{"line":302,"column":26}},"loc":{"start":{"line":302,"column":59},"end":{"line":308,"column":null}},"line":302},"12":{"name":"findEnglishBriefs","decl":{"start":{"line":320,"column":16},"end":{"line":320,"column":34}},"loc":{"start":{"line":320,"column":57},"end":{"line":341,"column":null}},"line":320},"13":{"name":"walk","decl":{"start":{"line":322,"column":11},"end":{"line":322,"column":16}},"loc":{"start":{"line":322,"column":42},"end":{"line":338,"column":null}},"line":322},"14":{"name":"validateH1","decl":{"start":{"line":365,"column":16},"end":{"line":365,"column":27}},"loc":{"start":{"line":365,"column":76},"end":{"line":402,"column":null}},"line":365},"15":{"name":"validateHeadlines","decl":{"start":{"line":405,"column":16},"end":{"line":405,"column":34}},"loc":{"start":{"line":405,"column":76},"end":{"line":430,"column":null}},"line":405},"16":{"name":"formatViolationReport","decl":{"start":{"line":432,"column":16},"end":{"line":432,"column":38}},"loc":{"start":{"line":432,"column":79},"end":{"line":444,"column":null}},"line":432},"17":{"name":"main","decl":{"start":{"line":461,"column":22},"end":{"line":461,"column":44}},"loc":{"start":{"line":461,"column":44},"end":{"line":498,"column":null}},"line":461}},"branchMap":{"0":{"loc":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},{"start":{},"end":{}}],"line":135},"1":{"loc":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":138},"2":{"loc":{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"3":{"loc":{"start":{"line":165,"column":9},"end":{"line":165,"column":null}},"type":"binary-expr","locations":[{"start":{"line":165,"column":9},"end":{"line":165,"column":37}},{"start":{"line":165,"column":37},"end":{"line":165,"column":60}},{"start":{"line":165,"column":60},"end":{"line":165,"column":null}}],"line":165},"4":{"loc":{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":4},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"5":{"loc":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"type":"if","locations":[{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},{"start":{},"end":{}}],"line":250},"6":{"loc":{"start":{"line":250,"column":6},"end":{"line":250,"column":41}},"type":"binary-expr","locations":[{"start":{"line":250,"column":6},"end":{"line":250,"column":17}},{"start":{"line":250,"column":17},"end":{"line":250,"column":41}}],"line":250},"7":{"loc":{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":254,"column":2},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":254},"8":{"loc":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},{"start":{},"end":{}}],"line":280},"9":{"loc":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":282},"10":{"loc":{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},"type":"if","locations":[{"start":{"line":284,"column":2},"end":{"line":284,"column":null}},{"start":{},"end":{}}],"line":284},"11":{"loc":{"start":{"line":284,"column":6},"end":{"line":284,"column":43}},"type":"binary-expr","locations":[{"start":{"line":284,"column":6},"end":{"line":284,"column":19}},{"start":{"line":284,"column":19},"end":{"line":284,"column":43}}],"line":284},"12":{"loc":{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":287,"column":2},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":287},"13":{"loc":{"start":{"line":289,"column":9},"end":{"line":289,"column":null}},"type":"binary-expr","locations":[{"start":{"line":289,"column":9},"end":{"line":289,"column":31}},{"start":{"line":289,"column":31},"end":{"line":289,"column":null}}],"line":289},"14":{"loc":{"start":{"line":307,"column":9},"end":{"line":307,"column":null}},"type":"cond-expr","locations":[{"start":{"line":307,"column":13},"end":{"line":307,"column":27}},{"start":{"line":307,"column":27},"end":{"line":307,"column":null}}],"line":307},"15":{"loc":{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":331,"column":6},"end":{"line":336,"column":null}},{"start":{"line":334,"column":13},"end":{"line":336,"column":null}}],"line":331},"16":{"loc":{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},"type":"if","locations":[{"start":{"line":332,"column":8},"end":{"line":332,"column":null}},{"start":{},"end":{}}],"line":332},"17":{"loc":{"start":{"line":332,"column":12},"end":{"line":332,"column":66}},"type":"binary-expr","locations":[{"start":{"line":332,"column":12},"end":{"line":332,"column":38}},{"start":{"line":332,"column":38},"end":{"line":332,"column":66}}],"line":332},"18":{"loc":{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":334,"column":13},"end":{"line":336,"column":null}},{"start":{},"end":{}}],"line":334},"19":{"loc":{"start":{"line":334,"column":17},"end":{"line":334,"column":72}},"type":"binary-expr","locations":[{"start":{"line":334,"column":17},"end":{"line":334,"column":35}},{"start":{"line":334,"column":35},"end":{"line":334,"column":72}}],"line":334},"20":{"loc":{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},"type":"if","locations":[{"start":{"line":370,"column":2},"end":{"line":372,"column":null}},{"start":{},"end":{}}],"line":370},"21":{"loc":{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},"type":"if","locations":[{"start":{"line":375,"column":2},"end":{"line":377,"column":null}},{"start":{},"end":{}}],"line":375},"22":{"loc":{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},"type":"if","locations":[{"start":{"line":381,"column":2},"end":{"line":383,"column":null}},{"start":{},"end":{}}],"line":381},"23":{"loc":{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},"type":"if","locations":[{"start":{"line":384,"column":2},"end":{"line":386,"column":null}},{"start":{},"end":{}}],"line":384},"24":{"loc":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"type":"if","locations":[{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},{"start":{},"end":{}}],"line":390},"25":{"loc":{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},"type":"if","locations":[{"start":{"line":395,"column":2},"end":{"line":399,"column":null}},{"start":{},"end":{}}],"line":395},"26":{"loc":{"start":{"line":395,"column":6},"end":{"line":395,"column":62}},"type":"binary-expr","locations":[{"start":{"line":395,"column":6},"end":{"line":395,"column":19}},{"start":{"line":395,"column":19},"end":{"line":395,"column":62}}],"line":395},"27":{"loc":{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},"type":"if","locations":[{"start":{"line":417,"column":4},"end":{"line":417,"column":null}},{"start":{},"end":{}}],"line":417},"28":{"loc":{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},"type":"if","locations":[{"start":{"line":420,"column":4},"end":{"line":427,"column":null}},{"start":{},"end":{}}],"line":420},"29":{"loc":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"type":"if","locations":[{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},{"start":{},"end":{}}],"line":433},"30":{"loc":{"start":{"line":463,"column":22},"end":{"line":463,"column":null}},"type":"cond-expr","locations":[{"start":{"line":463,"column":61},"end":{"line":463,"column":71}},{"start":{"line":463,"column":71},"end":{"line":463,"column":null}}],"line":463},"31":{"loc":{"start":{"line":463,"column":22},"end":{"line":463,"column":61}},"type":"binary-expr","locations":[{"start":{"line":463,"column":22},"end":{"line":463,"column":33}},{"start":{"line":463,"column":33},"end":{"line":463,"column":61}}],"line":463},"32":{"loc":{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":4},"end":{"line":470,"column":null}},{"start":{},"end":{}}],"line":467},"33":{"loc":{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":2},"end":{"line":494,"column":null}},{"start":{},"end":{}}],"line":479},"34":{"loc":{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},"type":"if","locations":[{"start":{"line":501,"column":0},"end":{"line":503,"column":null}},{"start":{},"end":{}}],"line":501}},"s":{"0":21,"1":28,"2":1,"3":13,"4":13,"5":0,"6":13,"7":13,"8":62,"9":7,"10":13,"11":1,"12":1,"13":12,"14":6,"15":6,"16":6,"17":1,"18":1,"19":10,"20":1,"21":12,"22":12,"23":72,"24":6,"25":12,"26":23,"27":5,"28":5,"29":5,"30":2,"31":3,"32":3,"33":0,"34":3,"35":11,"36":17,"37":11,"38":2,"39":9,"40":9,"41":0,"42":9,"43":9,"44":5,"45":4,"46":4,"47":4,"48":0,"49":4,"50":4,"51":4,"52":4,"53":4,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":6,"69":6,"70":6,"71":1,"72":6,"73":1,"74":6,"75":6,"76":0,"77":6,"78":1,"79":6,"80":6,"81":1,"82":6,"83":1,"84":6,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":1,"128":0},"f":{"0":21,"1":28,"2":13,"3":12,"4":10,"5":12,"6":23,"7":5,"8":11,"9":17,"10":11,"11":4,"12":0,"13":0,"14":6,"15":0,"16":0,"17":0},"b":{"0":[0,13],"1":[7,55],"2":[6,6],"3":[6,4,4],"4":[6,66],"5":[2,3],"6":[5,4],"7":[0,3],"8":[2,9],"9":[0,9],"10":[5,4],"11":[9,9],"12":[0,4],"13":[4,4],"14":[3,1],"15":[0,0],"16":[0,0],"17":[0,0],"18":[0,0],"19":[0,0],"20":[1,5],"21":[1,5],"22":[0,6],"23":[1,5],"24":[1,5],"25":[1,5],"26":[6,1],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,1]},"meta":{"lastBranch":35,"lastFunction":18,"lastStatement":129,"seen":{"f:65:9:65:29":0,"s:66:2:70:Infinity":0,"f:69:5:69:10":1,"s:69:19:69:63":1,"s:95:39:130:Infinity":2,"f:133:16:133:42":2,"s:134:18:134:Infinity":3,"b:135:2:135:Infinity:undefined:undefined:undefined:undefined":0,"s:135:2:135:Infinity":4,"s:135:16:135:Infinity":5,"s:136:15:136:Infinity":6,"s:137:2:139:Infinity":7,"b:138:4:138:Infinity:undefined:undefined:undefined:undefined":1,"s:138:4:138:Infinity":8,"s:138:42:138:Infinity":9,"s:140:2:140:Infinity":10,"s:156:2:156:Infinity":11,"s:158:2:158:Infinity":12,"f:160:16:160:37":3,"b:161:2:161:Infinity:undefined:undefined:undefined:undefined":2,"s:161:2:161:Infinity":13,"s:161:28:161:Infinity":14,"s:164:15:164:Infinity":15,"s:165:2:165:Infinity":16,"b:165:9:165:37:165:37:165:60:165:60:165:Infinity":3,"s:172:28:172:Infinity":17,"s:177:29:177:Infinity":18,"f:179:16:179:32":4,"s:180:2:183:Infinity":19,"s:202:93:209:Infinity":20,"f:211:16:211:40":5,"s:212:25:212:Infinity":21,"s:213:2:215:Infinity":22,"b:214:4:214:Infinity:undefined:undefined:undefined:undefined":4,"s:214:4:214:Infinity":23,"s:214:21:214:Infinity":24,"s:216:2:216:Infinity":25,"f:230:16:230:44":6,"s:231:2:235:Infinity":26,"f:247:16:247:39":7,"s:248:15:248:Infinity":27,"s:249:14:249:Infinity":28,"b:250:2:250:Infinity:undefined:undefined:undefined:undefined":5,"s:250:2:250:Infinity":29,"b:250:6:250:17:250:17:250:41":6,"s:250:41:250:Infinity":30,"s:253:16:253:Infinity":31,"b:254:2:254:Infinity:undefined:undefined:undefined:undefined":7,"s:254:2:254:Infinity":32,"s:254:26:254:Infinity":33,"s:255:2:255:Infinity":34,"f:263:16:263:38":8,"s:264:2:268:Infinity":35,"f:267:5:267:10":9,"s:267:18:267:42":36,"f:279:16:279:43":10,"b:280:2:280:Infinity:undefined:undefined:undefined:undefined":8,"s:280:2:280:Infinity":37,"s:280:18:280:Infinity":38,"s:281:19:281:Infinity":39,"b:282:2:282:Infinity:undefined:undefined:undefined:undefined":9,"s:282:2:282:Infinity":40,"s:282:17:282:Infinity":41,"s:283:20:283:Infinity":42,"b:284:2:284:Infinity:undefined:undefined:undefined:undefined":10,"s:284:2:284:Infinity":43,"b:284:6:284:19:284:19:284:43":11,"s:284:43:284:Infinity":44,"s:285:19:285:Infinity":45,"s:286:15:286:Infinity":46,"b:287:2:287:Infinity:undefined:undefined:undefined:undefined":12,"s:287:2:287:Infinity":47,"s:287:13:287:Infinity":48,"s:288:20:288:Infinity":49,"s:289:2:289:Infinity":50,"b:289:9:289:31:289:31:289:Infinity":13,"f:302:16:302:26":11,"s:305:15:305:Infinity":51,"s:306:12:306:Infinity":52,"s:307:2:307:Infinity":53,"b:307:13:307:27:307:27:307:Infinity":14,"f:320:16:320:34":12,"s:321:24:321:Infinity":54,"f:322:11:322:16":13,"s:324:4:328:Infinity":55,"s:325:6:325:Infinity":56,"s:327:6:327:Infinity":57,"s:329:4:337:Infinity":58,"s:330:23:330:Infinity":59,"b:331:6:336:Infinity:334:13:336:Infinity":15,"s:331:6:336:Infinity":60,"b:332:8:332:Infinity:undefined:undefined:undefined:undefined":16,"s:332:8:332:Infinity":61,"b:332:12:332:38:332:38:332:66":17,"s:332:66:332:Infinity":62,"s:333:8:333:Infinity":63,"b:334:13:336:Infinity:undefined:undefined:undefined:undefined":18,"s:334:13:336:Infinity":64,"b:334:17:334:35:334:35:334:72":19,"s:335:8:335:Infinity":65,"s:339:2:339:Infinity":66,"s:340:2:340:Infinity":67,"f:365:16:365:27":14,"s:366:27:366:Infinity":68,"s:369:22:369:Infinity":69,"b:370:2:372:Infinity:undefined:undefined:undefined:undefined":20,"s:370:2:372:Infinity":70,"s:371:4:371:Infinity":71,"b:375:2:377:Infinity:undefined:undefined:undefined:undefined":21,"s:375:2:377:Infinity":72,"s:376:4:376:Infinity":73,"s:380:14:380:Infinity":74,"b:381:2:383:Infinity:undefined:undefined:undefined:undefined":22,"s:381:2:383:Infinity":75,"s:382:4:382:Infinity":76,"b:384:2:386:Infinity:undefined:undefined:undefined:undefined":23,"s:384:2:386:Infinity":77,"s:385:4:385:Infinity":78,"s:389:22:389:Infinity":79,"b:390:2:392:Infinity:undefined:undefined:undefined:undefined":24,"s:390:2:392:Infinity":80,"s:391:4:391:Infinity":81,"b:395:2:399:Infinity:undefined:undefined:undefined:undefined":25,"s:395:2:399:Infinity":82,"b:395:6:395:19:395:19:395:62":26,"s:396:4:398:Infinity":83,"s:401:2:401:Infinity":84,"f:405:16:405:34":15,"s:406:42:406:Infinity":85,"s:407:17:407:Infinity":86,"s:409:2:428:Infinity":87,"s:411:4:415:Infinity":88,"s:412:6:412:Infinity":89,"s:414:6:414:Infinity":90,"s:416:15:416:Infinity":91,"b:417:4:417:Infinity:undefined:undefined:undefined:undefined":27,"s:417:4:417:Infinity":92,"s:417:13:417:Infinity":93,"s:418:22:418:Infinity":94,"s:419:19:419:Infinity":95,"b:420:4:427:Infinity:undefined:undefined:undefined:undefined":28,"s:420:4:427:Infinity":96,"s:421:6:426:Infinity":97,"s:429:2:429:Infinity":98,"f:432:16:432:38":16,"b:433:2:433:Infinity:undefined:undefined:undefined:undefined":29,"s:433:2:433:Infinity":99,"s:433:31:433:Infinity":100,"s:434:26:434:Infinity":101,"s:435:2:442:Infinity":102,"s:436:4:436:Infinity":103,"s:437:4:437:Infinity":104,"s:438:4:440:Infinity":105,"s:439:6:439:Infinity":106,"s:441:4:441:Infinity":107,"s:443:2:443:Infinity":108,"f:461:22:461:44":17,"s:462:15:462:Infinity":109,"s:463:22:463:Infinity":110,"b:463:61:463:71:463:71:463:Infinity":30,"b:463:22:463:33:463:33:463:61":31,"s:465:2:474:Infinity":111,"s:466:18:466:Infinity":112,"b:467:4:470:Infinity:undefined:undefined:undefined:undefined":32,"s:467:4:470:Infinity":113,"s:468:6:468:Infinity":114,"s:469:6:469:Infinity":115,"s:472:4:472:Infinity":116,"s:473:4:473:Infinity":117,"s:476:21:476:Infinity":118,"s:477:23:477:Infinity":119,"b:479:2:494:Infinity:undefined:undefined:undefined:undefined":33,"s:479:2:494:Infinity":120,"s:480:4:482:Infinity":121,"s:483:4:483:Infinity":122,"s:484:4:492:Infinity":123,"s:493:4:493:Infinity":124,"s:496:2:496:Infinity":125,"s:497:2:497:Infinity":126,"b:501:0:503:Infinity:undefined:undefined:undefined:undefined":34,"s:501:0:503:Infinity":127,"s:502:2:502:Infinity":128}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-imf-connectivity.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/check-imf-connectivity.ts","statementMap":{"0":{"start":{"line":121,"column":28},"end":{"line":121,"column":null}},"1":{"start":{"line":135,"column":16},"end":{"line":135,"column":null}},"2":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},"3":{"start":{"line":136,"column":14},"end":{"line":136,"column":null}},"4":{"start":{"line":137,"column":15},"end":{"line":137,"column":null}},"5":{"start":{"line":138,"column":16},"end":{"line":138,"column":null}},"6":{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},"7":{"start":{"line":139,"column":57},"end":{"line":139,"column":null}},"8":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"9":{"start":{"line":140,"column":31},"end":{"line":140,"column":null}},"10":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"11":{"start":{"line":153,"column":17},"end":{"line":153,"column":null}},"12":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"13":{"start":{"line":154,"column":15},"end":{"line":154,"column":null}},"14":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"15":{"start":{"line":156,"column":24},"end":{"line":156,"column":null}},"16":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"17":{"start":{"line":168,"column":17},"end":{"line":168,"column":null}},"18":{"start":{"line":168,"column":45},"end":{"line":168,"column":50}},"19":{"start":{"line":169,"column":24},"end":{"line":171,"column":null}},"20":{"start":{"line":170,"column":24},"end":{"line":170,"column":81}},"21":{"start":{"line":172,"column":2},"end":{"line":186,"column":null}},"22":{"start":{"line":198,"column":25},"end":{"line":200,"column":null}},"23":{"start":{"line":201,"column":2},"end":{"line":208,"column":null}},"24":{"start":{"line":216,"column":17},"end":{"line":216,"column":null}},"25":{"start":{"line":216,"column":45},"end":{"line":216,"column":50}},"26":{"start":{"line":217,"column":24},"end":{"line":219,"column":null}},"27":{"start":{"line":218,"column":24},"end":{"line":218,"column":81}},"28":{"start":{"line":220,"column":2},"end":{"line":230,"column":null}},"29":{"start":{"line":246,"column":32},"end":{"line":246,"column":null}},"30":{"start":{"line":249,"column":40},"end":{"line":249,"column":null}},"31":{"start":{"line":262,"column":2},"end":{"line":262,"column":null}},"32":{"start":{"line":278,"column":23},"end":{"line":278,"column":null}},"33":{"start":{"line":279,"column":2},"end":{"line":291,"column":null}},"34":{"start":{"line":280,"column":18},"end":{"line":285,"column":null}},"35":{"start":{"line":283,"column":8},"end":{"line":283,"column":null}},"36":{"start":{"line":283,"column":33},"end":{"line":283,"column":55}},"37":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"38":{"start":{"line":288,"column":4},"end":{"line":288,"column":null}},"39":{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},"40":{"start":{"line":290,"column":15},"end":{"line":290,"column":null}},"41":{"start":{"line":305,"column":35},"end":{"line":305,"column":null}},"42":{"start":{"line":308,"column":18},"end":{"line":308,"column":null}},"43":{"start":{"line":309,"column":19},"end":{"line":312,"column":null}},"44":{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},"45":{"start":{"line":314,"column":6},"end":{"line":320,"column":null}},"46":{"start":{"line":322,"column":21},"end":{"line":322,"column":null}},"47":{"start":{"line":323,"column":6},"end":{"line":329,"column":null}},"48":{"start":{"line":334,"column":18},"end":{"line":334,"column":null}},"49":{"start":{"line":335,"column":19},"end":{"line":338,"column":null}},"50":{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},"51":{"start":{"line":340,"column":6},"end":{"line":346,"column":null}},"52":{"start":{"line":348,"column":21},"end":{"line":348,"column":null}},"53":{"start":{"line":349,"column":6},"end":{"line":355,"column":null}},"54":{"start":{"line":360,"column":18},"end":{"line":360,"column":null}},"55":{"start":{"line":361,"column":26},"end":{"line":361,"column":null}},"56":{"start":{"line":362,"column":19},"end":{"line":365,"column":null}},"57":{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},"58":{"start":{"line":367,"column":25},"end":{"line":367,"column":null}},"59":{"start":{"line":369,"column":8},"end":{"line":370,"column":null}},"60":{"start":{"line":371,"column":20},"end":{"line":373,"column":null}},"61":{"start":{"line":374,"column":6},"end":{"line":380,"column":null}},"62":{"start":{"line":382,"column":18},"end":{"line":382,"column":null}},"63":{"start":{"line":383,"column":20},"end":{"line":383,"column":null}},"64":{"start":{"line":384,"column":24},"end":{"line":384,"column":null}},"65":{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},"66":{"start":{"line":387,"column":25},"end":{"line":387,"column":null}},"67":{"start":{"line":388,"column":21},"end":{"line":388,"column":null}},"68":{"start":{"line":389,"column":25},"end":{"line":389,"column":null}},"69":{"start":{"line":390,"column":8},"end":{"line":392,"column":null}},"70":{"start":{"line":391,"column":10},"end":{"line":391,"column":null}},"71":{"start":{"line":394,"column":17},"end":{"line":394,"column":null}},"72":{"start":{"line":395,"column":6},"end":{"line":401,"column":null}},"73":{"start":{"line":405,"column":2},"end":{"line":405,"column":null}},"74":{"start":{"line":417,"column":20},"end":{"line":417,"column":null}},"75":{"start":{"line":418,"column":16},"end":{"line":418,"column":null}},"76":{"start":{"line":419,"column":21},"end":{"line":421,"column":null}},"77":{"start":{"line":420,"column":4},"end":{"line":420,"column":null}},"78":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"79":{"start":{"line":422,"column":20},"end":{"line":422,"column":null}},"80":{"start":{"line":422,"column":39},"end":{"line":422,"column":44}},"81":{"start":{"line":423,"column":50},"end":{"line":429,"column":null}},"82":{"start":{"line":430,"column":20},"end":{"line":430,"column":null}},"83":{"start":{"line":431,"column":21},"end":{"line":438,"column":null}},"84":{"start":{"line":439,"column":23},"end":{"line":445,"column":null}},"85":{"start":{"line":446,"column":2},"end":{"line":446,"column":null}},"86":{"start":{"line":459,"column":2},"end":{"line":459,"column":null}},"87":{"start":{"line":460,"column":22},"end":{"line":460,"column":null}},"88":{"start":{"line":461,"column":2},"end":{"line":461,"column":null}},"89":{"start":{"line":463,"column":19},"end":{"line":463,"column":null}},"90":{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},"91":{"start":{"line":465,"column":19},"end":{"line":465,"column":null}},"92":{"start":{"line":465,"column":47},"end":{"line":465,"column":52}},"93":{"start":{"line":465,"column":65},"end":{"line":465,"column":75}},"94":{"start":{"line":466,"column":21},"end":{"line":477,"column":null}},"95":{"start":{"line":478,"column":4},"end":{"line":478,"column":null}},"96":{"start":{"line":492,"column":13},"end":{"line":492,"column":null}},"97":{"start":{"line":512,"column":15},"end":{"line":512,"column":null}},"98":{"start":{"line":513,"column":18},"end":{"line":513,"column":null}},"99":{"start":{"line":514,"column":13},"end":{"line":514,"column":null}},"100":{"start":{"line":515,"column":2},"end":{"line":535,"column":null}},"101":{"start":{"line":515,"column":15},"end":{"line":515,"column":18}},"102":{"start":{"line":516,"column":18},"end":{"line":516,"column":null}},"103":{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},"104":{"start":{"line":518,"column":6},"end":{"line":518,"column":null}},"105":{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},"106":{"start":{"line":520,"column":6},"end":{"line":520,"column":null}},"107":{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},"108":{"start":{"line":522,"column":19},"end":{"line":522,"column":null}},"109":{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},"110":{"start":{"line":524,"column":8},"end":{"line":524,"column":null}},"111":{"start":{"line":525,"column":8},"end":{"line":525,"column":null}},"112":{"start":{"line":527,"column":6},"end":{"line":527,"column":null}},"113":{"start":{"line":528,"column":6},"end":{"line":528,"column":null}},"114":{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},"115":{"start":{"line":530,"column":6},"end":{"line":530,"column":null}},"116":{"start":{"line":532,"column":6},"end":{"line":532,"column":null}},"117":{"start":{"line":533,"column":6},"end":{"line":533,"column":null}},"118":{"start":{"line":536,"column":2},"end":{"line":536,"column":null}},"119":{"start":{"line":540,"column":15},"end":{"line":540,"column":null}},"120":{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},"121":{"start":{"line":542,"column":4},"end":{"line":542,"column":null}},"122":{"start":{"line":543,"column":4},"end":{"line":543,"column":null}},"123":{"start":{"line":546,"column":17},"end":{"line":546,"column":null}},"124":{"start":{"line":547,"column":17},"end":{"line":547,"column":null}},"125":{"start":{"line":548,"column":17},"end":{"line":548,"column":null}},"126":{"start":{"line":550,"column":2},"end":{"line":550,"column":null}},"127":{"start":{"line":552,"column":2},"end":{"line":552,"column":null}},"128":{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},"129":{"start":{"line":555,"column":4},"end":{"line":559,"column":null}},"130":{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},"131":{"start":{"line":561,"column":6},"end":{"line":561,"column":null}},"132":{"start":{"line":563,"column":4},"end":{"line":563,"column":null}},"133":{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},"134":{"start":{"line":567,"column":4},"end":{"line":575,"column":null}},"135":{"start":{"line":581,"column":6},"end":{"line":585,"column":null}},"136":{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},"137":{"start":{"line":582,"column":58},"end":{"line":582,"column":null}},"138":{"start":{"line":583,"column":16},"end":{"line":583,"column":null}},"139":{"start":{"line":584,"column":2},"end":{"line":584,"column":null}},"140":{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},"141":{"start":{"line":588,"column":2},"end":{"line":592,"column":null}},"142":{"start":{"line":589,"column":16},"end":{"line":589,"column":null}},"143":{"start":{"line":590,"column":4},"end":{"line":590,"column":null}},"144":{"start":{"line":591,"column":4},"end":{"line":591,"column":null}}},"fnMap":{"0":{"name":"parseVintage","decl":{"start":{"line":134,"column":16},"end":{"line":134,"column":29}},"loc":{"start":{"line":134,"column":86},"end":{"line":142,"column":null}},"line":134},"1":{"name":"vintageAgeMonths","decl":{"start":{"line":152,"column":16},"end":{"line":152,"column":33}},"loc":{"start":{"line":152,"column":82},"end":{"line":158,"column":null}},"line":152},"2":{"name":"formatUnavailableWarning","decl":{"start":{"line":167,"column":16},"end":{"line":167,"column":41}},"loc":{"start":{"line":167,"column":110},"end":{"line":187,"column":null}},"line":167},"3":{"name":"(anonymous_3)","decl":{"start":{"line":168,"column":31},"end":{"line":168,"column":39}},"loc":{"start":{"line":168,"column":45},"end":{"line":168,"column":50}},"line":168},"4":{"name":"(anonymous_4)","decl":{"start":{"line":170,"column":13},"end":{"line":170,"column":18}},"loc":{"start":{"line":170,"column":24},"end":{"line":170,"column":81}},"line":170},"5":{"name":"formatStaleVintageAnnotation","decl":{"start":{"line":197,"column":16},"end":{"line":197,"column":45}},"loc":{"start":{"line":197,"column":122},"end":{"line":209,"column":null}},"line":197},"6":{"name":"formatDegradedWarning","decl":{"start":{"line":215,"column":16},"end":{"line":215,"column":38}},"loc":{"start":{"line":215,"column":107},"end":{"line":231,"column":null}},"line":215},"7":{"name":"(anonymous_7)","decl":{"start":{"line":216,"column":31},"end":{"line":216,"column":39}},"loc":{"start":{"line":216,"column":45},"end":{"line":216,"column":50}},"line":216},"8":{"name":"(anonymous_8)","decl":{"start":{"line":218,"column":13},"end":{"line":218,"column":18}},"loc":{"start":{"line":218,"column":24},"end":{"line":218,"column":81}},"line":218},"9":{"name":"isProbeErr","decl":{"start":{"line":261,"column":9},"end":{"line":261,"column":20}},"loc":{"start":{"line":261,"column":70},"end":{"line":263,"column":null}},"line":261},"10":{"name":"withTimeout","decl":{"start":{"line":273,"column":15},"end":{"line":273,"column":null}},"loc":{"start":{"line":276,"column":27},"end":{"line":292,"column":null}},"line":276},"11":{"name":"(anonymous_11)","decl":{"start":{"line":282,"column":10},"end":{"line":282,"column":22}},"loc":{"start":{"line":282,"column":43},"end":{"line":284,"column":7}},"line":282},"12":{"name":"(anonymous_12)","decl":{"start":{"line":283,"column":16},"end":{"line":283,"column":33}},"loc":{"start":{"line":283,"column":33},"end":{"line":283,"column":55}},"line":283},"13":{"name":"runProbes","decl":{"start":{"line":304,"column":22},"end":{"line":304,"column":32}},"loc":{"start":{"line":304,"column":78},"end":{"line":406,"column":null}},"line":304},"14":{"name":"buildReport","decl":{"start":{"line":412,"column":16},"end":{"line":412,"column":null}},"loc":{"start":{"line":416,"column":25},"end":{"line":447,"column":null}},"line":416},"15":{"name":"(anonymous_15)","decl":{"start":{"line":419,"column":35},"end":{"line":419,"column":42}},"loc":{"start":{"line":420,"column":4},"end":{"line":420,"column":null}},"line":420},"16":{"name":"(anonymous_16)","decl":{"start":{"line":420,"column":11},"end":{"line":420,"column":17}},"loc":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"line":420},"17":{"name":"(anonymous_17)","decl":{"start":{"line":422,"column":27},"end":{"line":422,"column":33}},"loc":{"start":{"line":422,"column":39},"end":{"line":422,"column":44}},"line":422},"18":{"name":"writeReport","decl":{"start":{"line":458,"column":16},"end":{"line":458,"column":28}},"loc":{"start":{"line":458,"column":85},"end":{"line":480,"column":null}},"line":458},"19":{"name":"(anonymous_19)","decl":{"start":{"line":465,"column":33},"end":{"line":465,"column":41}},"loc":{"start":{"line":465,"column":47},"end":{"line":465,"column":52}},"line":465},"20":{"name":"(anonymous_20)","decl":{"start":{"line":465,"column":54},"end":{"line":465,"column":59}},"loc":{"start":{"line":465,"column":65},"end":{"line":465,"column":75}},"line":465},"21":{"name":"parseCliArgs","decl":{"start":{"line":511,"column":16},"end":{"line":511,"column":29}},"loc":{"start":{"line":511,"column":66},"end":{"line":537,"column":null}},"line":511},"22":{"name":"mainCli","decl":{"start":{"line":539,"column":15},"end":{"line":539,"column":40}},"loc":{"start":{"line":539,"column":40},"end":{"line":577,"column":null}},"line":539},"23":{"name":"(anonymous_23)","decl":{"start":{"line":581,"column":6},"end":{"line":581,"column":34}},"loc":{"start":{"line":581,"column":34},"end":{"line":585,"column":1}},"line":581},"24":{"name":"(anonymous_24)","decl":{"start":{"line":588,"column":12},"end":{"line":588,"column":19}},"loc":{"start":{"line":588,"column":36},"end":{"line":592,"column":3}},"line":588}},"branchMap":{"0":{"loc":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":2},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":136},"1":{"loc":{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":139},"2":{"loc":{"start":{"line":139,"column":6},"end":{"line":139,"column":57}},"type":"binary-expr","locations":[{"start":{"line":139,"column":6},"end":{"line":139,"column":32}},{"start":{"line":139,"column":32},"end":{"line":139,"column":57}}],"line":139},"3":{"loc":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":140},"4":{"loc":{"start":{"line":140,"column":6},"end":{"line":140,"column":31}},"type":"binary-expr","locations":[{"start":{"line":140,"column":6},"end":{"line":140,"column":19}},{"start":{"line":140,"column":19},"end":{"line":140,"column":31}}],"line":140},"5":{"loc":{"start":{"line":152,"column":50},"end":{"line":152,"column":82}},"type":"default-arg","locations":[{"start":{"line":152,"column":62},"end":{"line":152,"column":82}}],"line":152},"6":{"loc":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":154},"7":{"loc":{"start":{"line":169,"column":24},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},{"start":{"line":171,"column":6},"end":{"line":171,"column":null}}],"line":169},"8":{"loc":{"start":{"line":170,"column":59},"end":{"line":170,"column":81}},"type":"binary-expr","locations":[{"start":{"line":170,"column":59},"end":{"line":170,"column":70}},{"start":{"line":170,"column":70},"end":{"line":170,"column":81}}],"line":170},"9":{"loc":{"start":{"line":198,"column":25},"end":{"line":200,"column":null}},"type":"cond-expr","locations":[{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},{"start":{"line":200,"column":6},"end":{"line":200,"column":null}}],"line":198},"10":{"loc":{"start":{"line":217,"column":24},"end":{"line":219,"column":null}},"type":"cond-expr","locations":[{"start":{"line":218,"column":6},"end":{"line":218,"column":null}},{"start":{"line":219,"column":6},"end":{"line":219,"column":null}}],"line":217},"11":{"loc":{"start":{"line":218,"column":59},"end":{"line":218,"column":81}},"type":"binary-expr","locations":[{"start":{"line":218,"column":59},"end":{"line":218,"column":70}},{"start":{"line":218,"column":70},"end":{"line":218,"column":81}}],"line":218},"12":{"loc":{"start":{"line":288,"column":31},"end":{"line":288,"column":83}},"type":"cond-expr","locations":[{"start":{"line":288,"column":54},"end":{"line":288,"column":60}},{"start":{"line":288,"column":60},"end":{"line":288,"column":83}}],"line":288},"13":{"loc":{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},"type":"if","locations":[{"start":{"line":290,"column":4},"end":{"line":290,"column":null}},{"start":{},"end":{}}],"line":290},"14":{"loc":{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":4},"end":{"line":330,"column":null}},{"start":{"line":321,"column":11},"end":{"line":330,"column":null}}],"line":313},"15":{"loc":{"start":{"line":328,"column":12},"end":{"line":328,"column":null}},"type":"cond-expr","locations":[{"start":{"line":328,"column":34},"end":{"line":328,"column":62}},{"start":{"line":328,"column":62},"end":{"line":328,"column":null}}],"line":328},"16":{"loc":{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},"type":"if","locations":[{"start":{"line":339,"column":4},"end":{"line":356,"column":null}},{"start":{"line":347,"column":11},"end":{"line":356,"column":null}}],"line":339},"17":{"loc":{"start":{"line":354,"column":12},"end":{"line":354,"column":null}},"type":"cond-expr","locations":[{"start":{"line":354,"column":34},"end":{"line":354,"column":62}},{"start":{"line":354,"column":62},"end":{"line":354,"column":null}}],"line":354},"18":{"loc":{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},"type":"if","locations":[{"start":{"line":366,"column":4},"end":{"line":402,"column":null}},{"start":{"line":381,"column":11},"end":{"line":402,"column":null}}],"line":366},"19":{"loc":{"start":{"line":369,"column":8},"end":{"line":370,"column":null}},"type":"binary-expr","locations":[{"start":{"line":369,"column":8},"end":{"line":369,"column":null}},{"start":{"line":370,"column":8},"end":{"line":370,"column":null}}],"line":369},"20":{"loc":{"start":{"line":371,"column":20},"end":{"line":373,"column":null}},"type":"cond-expr","locations":[{"start":{"line":372,"column":10},"end":{"line":372,"column":null}},{"start":{"line":373,"column":10},"end":{"line":373,"column":null}}],"line":371},"21":{"loc":{"start":{"line":371,"column":20},"end":{"line":371,"column":null}},"type":"binary-expr","locations":[{"start":{"line":371,"column":20},"end":{"line":371,"column":38}},{"start":{"line":371,"column":38},"end":{"line":371,"column":null}}],"line":371},"22":{"loc":{"start":{"line":383,"column":20},"end":{"line":383,"column":null}},"type":"binary-expr","locations":[{"start":{"line":383,"column":20},"end":{"line":383,"column":36}},{"start":{"line":383,"column":36},"end":{"line":383,"column":null}}],"line":383},"23":{"loc":{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},"type":"if","locations":[{"start":{"line":385,"column":6},"end":{"line":393,"column":null}},{"start":{},"end":{}}],"line":385},"24":{"loc":{"start":{"line":389,"column":25},"end":{"line":389,"column":null}},"type":"binary-expr","locations":[{"start":{"line":389,"column":25},"end":{"line":389,"column":46}},{"start":{"line":389,"column":46},"end":{"line":389,"column":63}},{"start":{"line":389,"column":63},"end":{"line":389,"column":null}}],"line":389},"25":{"loc":{"start":{"line":391,"column":37},"end":{"line":391,"column":53}},"type":"binary-expr","locations":[{"start":{"line":391,"column":37},"end":{"line":391,"column":51}},{"start":{"line":391,"column":51},"end":{"line":391,"column":53}}],"line":391},"26":{"loc":{"start":{"line":394,"column":17},"end":{"line":394,"column":null}},"type":"binary-expr","locations":[{"start":{"line":394,"column":17},"end":{"line":394,"column":26}},{"start":{"line":394,"column":26},"end":{"line":394,"column":null}}],"line":394},"27":{"loc":{"start":{"line":400,"column":12},"end":{"line":400,"column":null}},"type":"cond-expr","locations":[{"start":{"line":400,"column":17},"end":{"line":400,"column":22}},{"start":{"line":400,"column":22},"end":{"line":400,"column":null}}],"line":400},"28":{"loc":{"start":{"line":400,"column":31},"end":{"line":400,"column":83}},"type":"cond-expr","locations":[{"start":{"line":400,"column":39},"end":{"line":400,"column":61}},{"start":{"line":400,"column":61},"end":{"line":400,"column":83}}],"line":400},"29":{"loc":{"start":{"line":415,"column":2},"end":{"line":415,"column":null}},"type":"default-arg","locations":[{"start":{"line":415,"column":14},"end":{"line":415,"column":null}}],"line":415},"30":{"loc":{"start":{"line":420,"column":23},"end":{"line":420,"column":54}},"type":"binary-expr","locations":[{"start":{"line":420,"column":23},"end":{"line":420,"column":50}},{"start":{"line":420,"column":50},"end":{"line":420,"column":54}}],"line":420},"31":{"loc":{"start":{"line":423,"column":50},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":424,"column":6},"end":{"line":424,"column":null}},{"start":{"line":425,"column":6},"end":{"line":429,"column":null}}],"line":423},"32":{"loc":{"start":{"line":425,"column":6},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":426,"column":8},"end":{"line":426,"column":null}},{"start":{"line":427,"column":8},"end":{"line":429,"column":null}}],"line":425},"33":{"loc":{"start":{"line":427,"column":8},"end":{"line":429,"column":null}},"type":"cond-expr","locations":[{"start":{"line":428,"column":10},"end":{"line":428,"column":null}},{"start":{"line":429,"column":8},"end":{"line":429,"column":null}}],"line":427},"34":{"loc":{"start":{"line":434,"column":22},"end":{"line":434,"column":null}},"type":"cond-expr","locations":[{"start":{"line":434,"column":51},"end":{"line":434,"column":63}},{"start":{"line":434,"column":63},"end":{"line":434,"column":null}}],"line":434},"35":{"loc":{"start":{"line":439,"column":23},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},{"start":{"line":441,"column":6},"end":{"line":445,"column":null}}],"line":439},"36":{"loc":{"start":{"line":441,"column":6},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},{"start":{"line":443,"column":8},"end":{"line":445,"column":null}}],"line":441},"37":{"loc":{"start":{"line":443,"column":8},"end":{"line":445,"column":null}},"type":"cond-expr","locations":[{"start":{"line":444,"column":10},"end":{"line":444,"column":null}},{"start":{"line":445,"column":10},"end":{"line":445,"column":null}}],"line":443},"38":{"loc":{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},"type":"if","locations":[{"start":{"line":464,"column":2},"end":{"line":479,"column":null}},{"start":{},"end":{}}],"line":464},"39":{"loc":{"start":{"line":469,"column":29},"end":{"line":469,"column":null}},"type":"binary-expr","locations":[{"start":{"line":469,"column":29},"end":{"line":469,"column":39}},{"start":{"line":469,"column":39},"end":{"line":469,"column":null}}],"line":469},"40":{"loc":{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":517,"column":4},"end":{"line":534,"column":null}},{"start":{"line":519,"column":11},"end":{"line":534,"column":null}}],"line":517},"41":{"loc":{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":519,"column":11},"end":{"line":534,"column":null}},{"start":{"line":521,"column":11},"end":{"line":534,"column":null}}],"line":519},"42":{"loc":{"start":{"line":519,"column":15},"end":{"line":519,"column":53}},"type":"binary-expr","locations":[{"start":{"line":519,"column":15},"end":{"line":519,"column":37}},{"start":{"line":519,"column":37},"end":{"line":519,"column":53}}],"line":519},"43":{"loc":{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":521,"column":11},"end":{"line":534,"column":null}},{"start":{"line":529,"column":11},"end":{"line":534,"column":null}}],"line":521},"44":{"loc":{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},"type":"if","locations":[{"start":{"line":523,"column":6},"end":{"line":526,"column":null}},{"start":{},"end":{}}],"line":523},"45":{"loc":{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},"type":"if","locations":[{"start":{"line":529,"column":11},"end":{"line":534,"column":null}},{"start":{"line":531,"column":11},"end":{"line":534,"column":null}}],"line":529},"46":{"loc":{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},"type":"if","locations":[{"start":{"line":541,"column":2},"end":{"line":544,"column":null}},{"start":{},"end":{}}],"line":541},"47":{"loc":{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},"type":"if","locations":[{"start":{"line":554,"column":2},"end":{"line":564,"column":null}},{"start":{},"end":{}}],"line":554},"48":{"loc":{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},"type":"if","locations":[{"start":{"line":560,"column":4},"end":{"line":562,"column":null}},{"start":{},"end":{}}],"line":560},"49":{"loc":{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},"type":"if","locations":[{"start":{"line":566,"column":2},"end":{"line":576,"column":null}},{"start":{},"end":{}}],"line":566},"50":{"loc":{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},"type":"if","locations":[{"start":{"line":582,"column":2},"end":{"line":582,"column":null}},{"start":{},"end":{}}],"line":582},"51":{"loc":{"start":{"line":582,"column":6},"end":{"line":582,"column":58}},"type":"binary-expr","locations":[{"start":{"line":582,"column":6},"end":{"line":582,"column":40}},{"start":{"line":582,"column":40},"end":{"line":582,"column":58}}],"line":582},"52":{"loc":{"start":{"line":584,"column":9},"end":{"line":584,"column":null}},"type":"binary-expr","locations":[{"start":{"line":584,"column":9},"end":{"line":584,"column":56}},{"start":{"line":584,"column":56},"end":{"line":584,"column":null}}],"line":584},"53":{"loc":{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},"type":"if","locations":[{"start":{"line":587,"column":0},"end":{"line":593,"column":null}},{"start":{},"end":{}}],"line":587},"54":{"loc":{"start":{"line":589,"column":16},"end":{"line":589,"column":null}},"type":"cond-expr","locations":[{"start":{"line":589,"column":39},"end":{"line":589,"column":53}},{"start":{"line":589,"column":53},"end":{"line":589,"column":null}}],"line":589}},"s":{"0":2,"1":20,"2":20,"3":5,"4":15,"5":15,"6":15,"7":0,"8":15,"9":1,"10":14,"11":14,"12":14,"13":2,"14":12,"15":12,"16":12,"17":3,"18":8,"19":3,"20":5,"21":3,"22":6,"23":6,"24":3,"25":8,"26":3,"27":3,"28":3,"29":2,"30":2,"31":33,"32":33,"33":33,"34":33,"35":33,"36":3,"37":22,"38":11,"39":33,"40":33,"41":11,"42":11,"43":11,"44":11,"45":2,"46":9,"47":9,"48":11,"49":11,"50":11,"51":2,"52":9,"53":9,"54":11,"55":11,"56":11,"57":11,"58":7,"59":7,"60":7,"61":7,"62":4,"63":4,"64":4,"65":4,"66":3,"67":3,"68":3,"69":3,"70":3,"71":4,"72":4,"73":11,"74":9,"75":9,"76":9,"77":16,"78":27,"79":9,"80":23,"81":9,"82":9,"83":9,"84":9,"85":9,"86":4,"87":4,"88":4,"89":4,"90":4,"91":1,"92":3,"93":3,"94":1,"95":1,"96":2,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":2,"136":2,"137":0,"138":2,"139":2,"140":2,"141":0,"142":0,"143":0,"144":0},"f":{"0":20,"1":14,"2":3,"3":8,"4":5,"5":6,"6":3,"7":8,"8":3,"9":33,"10":33,"11":33,"12":3,"13":11,"14":9,"15":16,"16":27,"17":23,"18":4,"19":3,"20":3,"21":0,"22":0,"23":2,"24":0},"b":{"0":[5,15],"1":[0,15],"2":[15,15],"3":[1,14],"4":[15,15],"5":[14],"6":[2,12],"7":[3,0],"8":[5,0],"9":[2,4],"10":[3,0],"11":[3,0],"12":[11,0],"13":[33,0],"14":[2,9],"15":[1,8],"16":[2,9],"17":[1,8],"18":[7,4],"19":[7,3],"20":[3,4],"21":[7,6],"22":[4,4],"23":[3,1],"24":[3,0,0],"25":[3,0],"26":[4,3],"27":[2,2],"28":[1,1],"29":[9],"30":[27,16],"31":[2,7],"32":[3,4],"33":[2,2],"34":[8,1],"35":[2,7],"36":[3,4],"37":[2,2],"38":[1,3],"39":[1,0],"40":[0,0],"41":[0,0],"42":[0,0],"43":[0,0],"44":[0,0],"45":[0,0],"46":[0,0],"47":[0,0],"48":[0,0],"49":[0,0],"50":[0,2],"51":[2,2],"52":[2,2],"53":[0,2],"54":[0,0]},"meta":{"lastBranch":55,"lastFunction":25,"lastStatement":145,"seen":{"s:121:28:121:Infinity":0,"f:134:16:134:29":0,"s:135:16:135:Infinity":1,"b:136:2:136:Infinity:undefined:undefined:undefined:undefined":0,"s:136:2:136:Infinity":2,"s:136:14:136:Infinity":3,"s:137:15:137:Infinity":4,"s:138:16:138:Infinity":5,"b:139:2:139:Infinity:undefined:undefined:undefined:undefined":1,"s:139:2:139:Infinity":6,"b:139:6:139:32:139:32:139:57":2,"s:139:57:139:Infinity":7,"b:140:2:140:Infinity:undefined:undefined:undefined:undefined":3,"s:140:2:140:Infinity":8,"b:140:6:140:19:140:19:140:31":4,"s:140:31:140:Infinity":9,"s:141:2:141:Infinity":10,"f:152:16:152:33":1,"b:152:62:152:82":5,"s:153:17:153:Infinity":11,"b:154:2:154:Infinity:undefined:undefined:undefined:undefined":6,"s:154:2:154:Infinity":12,"s:154:15:154:Infinity":13,"s:155:20:155:Infinity":14,"s:156:24:156:Infinity":15,"s:157:2:157:Infinity":16,"f:167:16:167:41":2,"s:168:17:168:Infinity":17,"f:168:31:168:39":3,"s:168:45:168:50":18,"s:169:24:171:Infinity":19,"b:170:6:170:Infinity:171:6:171:Infinity":7,"f:170:13:170:18":4,"s:170:24:170:81":20,"b:170:59:170:70:170:70:170:81":8,"s:172:2:186:Infinity":21,"f:197:16:197:45":5,"s:198:25:200:Infinity":22,"b:199:6:199:Infinity:200:6:200:Infinity":9,"s:201:2:208:Infinity":23,"f:215:16:215:38":6,"s:216:17:216:Infinity":24,"f:216:31:216:39":7,"s:216:45:216:50":25,"s:217:24:219:Infinity":26,"b:218:6:218:Infinity:219:6:219:Infinity":10,"f:218:13:218:18":8,"s:218:24:218:81":27,"b:218:59:218:70:218:70:218:81":11,"s:220:2:230:Infinity":28,"s:246:32:246:Infinity":29,"s:249:40:249:Infinity":30,"f:261:9:261:20":9,"s:262:2:262:Infinity":31,"f:273:15:273:Infinity":10,"s:278:23:278:Infinity":32,"s:279:2:291:Infinity":33,"s:280:18:285:Infinity":34,"f:282:10:282:22":11,"s:283:8:283:Infinity":35,"f:283:16:283:33":12,"s:283:33:283:55":36,"s:286:4:286:Infinity":37,"s:288:4:288:Infinity":38,"b:288:54:288:60:288:60:288:83":12,"b:290:4:290:Infinity:undefined:undefined:undefined:undefined":13,"s:290:4:290:Infinity":39,"s:290:15:290:Infinity":40,"f:304:22:304:32":13,"s:305:35:305:Infinity":41,"s:308:18:308:Infinity":42,"s:309:19:312:Infinity":43,"b:313:4:330:Infinity:321:11:330:Infinity":14,"s:313:4:330:Infinity":44,"s:314:6:320:Infinity":45,"s:322:21:322:Infinity":46,"s:323:6:329:Infinity":47,"b:328:34:328:62:328:62:328:Infinity":15,"s:334:18:334:Infinity":48,"s:335:19:338:Infinity":49,"b:339:4:356:Infinity:347:11:356:Infinity":16,"s:339:4:356:Infinity":50,"s:340:6:346:Infinity":51,"s:348:21:348:Infinity":52,"s:349:6:355:Infinity":53,"b:354:34:354:62:354:62:354:Infinity":17,"s:360:18:360:Infinity":54,"s:361:26:361:Infinity":55,"s:362:19:365:Infinity":56,"b:366:4:402:Infinity:381:11:402:Infinity":18,"s:366:4:402:Infinity":57,"s:367:25:367:Infinity":58,"s:369:8:370:Infinity":59,"b:369:8:369:Infinity:370:8:370:Infinity":19,"s:371:20:373:Infinity":60,"b:372:10:372:Infinity:373:10:373:Infinity":20,"b:371:20:371:38:371:38:371:Infinity":21,"s:374:6:380:Infinity":61,"s:382:18:382:Infinity":62,"s:383:20:383:Infinity":63,"b:383:20:383:36:383:36:383:Infinity":22,"s:384:24:384:Infinity":64,"b:385:6:393:Infinity:undefined:undefined:undefined:undefined":23,"s:385:6:393:Infinity":65,"s:387:25:387:Infinity":66,"s:388:21:388:Infinity":67,"s:389:25:389:Infinity":68,"b:389:25:389:46:389:46:389:63:389:63:389:Infinity":24,"s:390:8:392:Infinity":69,"s:391:10:391:Infinity":70,"b:391:37:391:51:391:51:391:53":25,"s:394:17:394:Infinity":71,"b:394:17:394:26:394:26:394:Infinity":26,"s:395:6:401:Infinity":72,"b:400:17:400:22:400:22:400:Infinity":27,"b:400:39:400:61:400:61:400:83":28,"s:405:2:405:Infinity":73,"f:412:16:412:Infinity":14,"b:415:14:415:Infinity":29,"s:417:20:417:Infinity":74,"s:418:16:418:Infinity":75,"s:419:21:421:Infinity":76,"f:419:35:419:42":15,"s:420:4:420:Infinity":77,"f:420:11:420:17":16,"s:420:23:420:54":78,"b:420:23:420:50:420:50:420:54":30,"s:422:20:422:Infinity":79,"f:422:27:422:33":17,"s:422:39:422:44":80,"s:423:50:429:Infinity":81,"b:424:6:424:Infinity:425:6:429:Infinity":31,"b:426:8:426:Infinity:427:8:429:Infinity":32,"b:428:10:428:Infinity:429:8:429:Infinity":33,"s:430:20:430:Infinity":82,"s:431:21:438:Infinity":83,"b:434:51:434:63:434:63:434:Infinity":34,"s:439:23:445:Infinity":84,"b:440:6:440:Infinity:441:6:445:Infinity":35,"b:442:8:442:Infinity:443:8:445:Infinity":36,"b:444:10:444:Infinity:445:10:445:Infinity":37,"s:446:2:446:Infinity":85,"f:458:16:458:28":18,"s:459:2:459:Infinity":86,"s:460:22:460:Infinity":87,"s:461:2:461:Infinity":88,"s:463:19:463:Infinity":89,"b:464:2:479:Infinity:undefined:undefined:undefined:undefined":38,"s:464:2:479:Infinity":90,"s:465:19:465:Infinity":91,"f:465:33:465:41":19,"s:465:47:465:52":92,"f:465:54:465:59":20,"s:465:65:465:75":93,"s:466:21:477:Infinity":94,"b:469:29:469:39:469:39:469:Infinity":39,"s:478:4:478:Infinity":95,"s:492:13:492:Infinity":96,"f:511:16:511:29":21,"s:512:15:512:Infinity":97,"s:513:18:513:Infinity":98,"s:514:13:514:Infinity":99,"s:515:2:535:Infinity":100,"s:515:15:515:18":101,"s:516:18:516:Infinity":102,"b:517:4:534:Infinity:519:11:534:Infinity":40,"s:517:4:534:Infinity":103,"s:518:6:518:Infinity":104,"b:519:11:534:Infinity:521:11:534:Infinity":41,"s:519:11:534:Infinity":105,"b:519:15:519:37:519:37:519:53":42,"s:520:6:520:Infinity":106,"b:521:11:534:Infinity:529:11:534:Infinity":43,"s:521:11:534:Infinity":107,"s:522:19:522:Infinity":108,"b:523:6:526:Infinity:undefined:undefined:undefined:undefined":44,"s:523:6:526:Infinity":109,"s:524:8:524:Infinity":110,"s:525:8:525:Infinity":111,"s:527:6:527:Infinity":112,"s:528:6:528:Infinity":113,"b:529:11:534:Infinity:531:11:534:Infinity":45,"s:529:11:534:Infinity":114,"s:530:6:530:Infinity":115,"s:532:6:532:Infinity":116,"s:533:6:533:Infinity":117,"s:536:2:536:Infinity":118,"f:539:15:539:40":22,"s:540:15:540:Infinity":119,"b:541:2:544:Infinity:undefined:undefined:undefined:undefined":46,"s:541:2:544:Infinity":120,"s:542:4:542:Infinity":121,"s:543:4:543:Infinity":122,"s:546:17:546:Infinity":123,"s:547:17:547:Infinity":124,"s:548:17:548:Infinity":125,"s:550:2:550:Infinity":126,"s:552:2:552:Infinity":127,"b:554:2:564:Infinity:undefined:undefined:undefined:undefined":47,"s:554:2:564:Infinity":128,"s:555:4:559:Infinity":129,"b:560:4:562:Infinity:undefined:undefined:undefined:undefined":48,"s:560:4:562:Infinity":130,"s:561:6:561:Infinity":131,"s:563:4:563:Infinity":132,"b:566:2:576:Infinity:undefined:undefined:undefined:undefined":49,"s:566:2:576:Infinity":133,"s:567:4:575:Infinity":134,"s:581:6:585:Infinity":135,"f:581:6:581:34":23,"b:582:2:582:Infinity:undefined:undefined:undefined:undefined":50,"s:582:2:582:Infinity":136,"b:582:6:582:40:582:40:582:58":51,"s:582:58:582:Infinity":137,"s:583:16:583:Infinity":138,"s:584:2:584:Infinity":139,"b:584:9:584:56:584:56:584:Infinity":52,"b:587:0:593:Infinity:undefined:undefined:undefined:undefined":53,"s:587:0:593:Infinity":140,"s:588:2:592:Infinity":141,"f:588:12:588:19":24,"s:589:16:589:Infinity":142,"b:589:39:589:53:589:53:589:Infinity":54,"s:590:4:590:Infinity":143,"s:591:4:591:Infinity":144}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/cli.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/cli.ts","statementMap":{"0":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"2":{"start":{"line":33,"column":16},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":35,"column":15},"end":{"line":35,"column":18}},"6":{"start":{"line":36,"column":18},"end":{"line":36,"column":null}},"7":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"8":{"start":{"line":37,"column":43},"end":{"line":37,"column":null}},"9":{"start":{"line":38,"column":16},"end":{"line":38,"column":null}},"10":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"11":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"12":{"start":{"line":41,"column":6},"end":{"line":41,"column":null}},"13":{"start":{"line":42,"column":6},"end":{"line":42,"column":null}},"14":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"15":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"16":{"start":{"line":48,"column":15},"end":{"line":48,"column":null}},"17":{"start":{"line":49,"column":13},"end":{"line":49,"column":null}},"18":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"19":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"20":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"21":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"22":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"23":{"start":{"line":60,"column":15},"end":{"line":60,"column":null}},"24":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"25":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"26":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"27":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"28":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"29":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"30":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"31":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":2},"end":{"line":19,"column":14}},"loc":{"start":{"line":19,"column":31},"end":{"line":22,"column":null}},"line":19},"1":{"name":"parseCalendarArgs","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":34}},"loc":{"start":{"line":32,"column":2},"end":{"line":57,"column":null}},"line":32},"2":{"name":"main","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":44}},"loc":{"start":{"line":59,"column":44},"end":{"line":76,"column":null}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":37,"column":8},"end":{"line":37,"column":43}},"type":"binary-expr","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":18}},{"start":{"line":37,"column":18},"end":{"line":37,"column":43}}],"line":37},"2":{"loc":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},{"start":{"line":43,"column":11},"end":{"line":45,"column":null}}],"line":40},"3":{"loc":{"start":{"line":40,"column":8},"end":{"line":40,"column":54}},"type":"binary-expr","locations":[{"start":{"line":40,"column":8},"end":{"line":40,"column":30}},{"start":{"line":40,"column":30},"end":{"line":40,"column":54}}],"line":40},"4":{"loc":{"start":{"line":48,"column":15},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":15},"end":{"line":48,"column":36}},{"start":{"line":48,"column":36},"end":{"line":48,"column":null}}],"line":48},"5":{"loc":{"start":{"line":49,"column":13},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":13},"end":{"line":49,"column":32}},{"start":{"line":49,"column":32},"end":{"line":49,"column":52}},{"start":{"line":49,"column":52},"end":{"line":49,"column":null}}],"line":49},"6":{"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":52,"column":null}},{"start":{},"end":{}}],"line":50},"7":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},{"start":{"line":69,"column":9},"end":{"line":71,"column":null}}],"line":67},"9":{"loc":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":73}},"s":{"0":5,"1":5,"2":9,"3":9,"4":9,"5":9,"6":17,"7":17,"8":0,"9":17,"10":17,"11":17,"12":16,"13":16,"14":1,"15":9,"16":9,"17":9,"18":9,"19":4,"20":5,"21":1,"22":4,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0},"f":{"0":5,"1":9,"2":0},"b":{"0":[0,17],"1":[17,17],"2":[16,1],"3":[17,16],"4":[9,2],"5":[9,2,1],"6":[4,5],"7":[1,4],"8":[0,0],"9":[0,0]},"meta":{"lastBranch":10,"lastFunction":3,"lastStatement":32,"seen":{"f:19:2:19:14":0,"s:20:4:20:Infinity":0,"s:21:4:21:Infinity":1,"f:28:16:28:34":1,"s:33:16:33:Infinity":2,"s:34:19:34:Infinity":3,"s:35:2:46:Infinity":4,"s:35:15:35:18":5,"s:36:18:36:Infinity":6,"b:37:4:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:37:Infinity":7,"b:37:8:37:18:37:18:37:43":1,"s:37:43:37:Infinity":8,"s:38:16:38:Infinity":9,"s:39:17:39:Infinity":10,"b:40:4:45:Infinity:43:11:45:Infinity":2,"s:40:4:45:Infinity":11,"b:40:8:40:30:40:30:40:54":3,"s:41:6:41:Infinity":12,"s:42:6:42:Infinity":13,"s:44:6:44:Infinity":14,"s:47:22:47:Infinity":15,"s:48:15:48:Infinity":16,"b:48:15:48:36:48:36:48:Infinity":4,"s:49:13:49:Infinity":17,"b:49:13:49:32:49:32:49:52:49:52:49:Infinity":5,"b:50:2:52:Infinity:undefined:undefined:undefined:undefined":6,"s:50:2:52:Infinity":18,"s:51:4:51:Infinity":19,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":7,"s:53:2:55:Infinity":20,"s:54:4:54:Infinity":21,"s:56:2:56:Infinity":22,"f:59:22:59:44":2,"s:60:15:60:Infinity":23,"s:61:2:61:Infinity":24,"s:63:17:63:Infinity":25,"s:65:2:65:Infinity":26,"b:67:2:71:Infinity:69:9:71:Infinity":8,"s:67:2:71:Infinity":27,"s:68:4:68:Infinity":28,"s:70:4:70:Infinity":29,"b:73:2:75:Infinity:undefined:undefined:undefined:undefined":9,"s:73:2:75:Infinity":30,"s:74:4:74:Infinity":31}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/manifest.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/manifest.ts","statementMap":{"0":{"start":{"line":20,"column":18},"end":{"line":20,"column":null}},"1":{"start":{"line":22,"column":18},"end":{"line":22,"column":null}},"2":{"start":{"line":23,"column":21},"end":{"line":23,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":21},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":18},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"10":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"11":{"start":{"line":60,"column":4},"end":{"line":64,"column":null}},"12":{"start":{"line":66,"column":16},"end":{"line":72,"column":null}},"13":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"14":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"15":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"16":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"17":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"persistCalendarJson","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":52,"column":null}},"line":37},"1":{"name":"formatManifestMarkdown","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":39}},"loc":{"start":{"line":58,"column":80},"end":{"line":80,"column":null}},"line":58}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":22},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":17},"end":{"line":39,"column":43}},{"start":{"line":39,"column":43},"end":{"line":39,"column":null}}],"line":39},"2":{"loc":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":47},"end":{"line":40,"column":74}},{"start":{"line":40,"column":74},"end":{"line":40,"column":null}}],"line":40},"3":{"loc":{"start":{"line":40,"column":19},"end":{"line":40,"column":47}},"type":"binary-expr","locations":[{"start":{"line":40,"column":19},"end":{"line":40,"column":29}},{"start":{"line":40,"column":29},"end":{"line":40,"column":47}}],"line":40},"4":{"loc":{"start":{"line":60,"column":4},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":null}},{"start":{"line":62,"column":8},"end":{"line":64,"column":null}}],"line":60},"5":{"loc":{"start":{"line":62,"column":8},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},{"start":{"line":64,"column":10},"end":{"line":64,"column":null}}],"line":62},"6":{"loc":{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":73},"7":{"loc":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76}},"s":{"0":9,"1":9,"2":9,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":4,"10":4,"11":3,"12":3,"13":3,"14":2,"15":3,"16":1,"17":3},"f":{"0":4,"1":3},"b":{"0":[4],"1":[4,0],"2":[1,3],"3":[4,4],"4":[1,2],"5":[1,1],"6":[2,1],"7":[1,2]},"meta":{"lastBranch":8,"lastFunction":2,"lastStatement":18,"seen":{"s:20:18:20:Infinity":0,"s:22:18:22:Infinity":1,"s:23:21:23:Infinity":2,"f:33:16:33:Infinity":0,"b:36:22:36:Infinity":0,"s:38:2:38:Infinity":3,"s:39:17:39:Infinity":4,"b:39:17:39:43:39:43:39:Infinity":1,"s:40:19:40:Infinity":5,"b:40:47:40:74:40:74:40:Infinity":2,"b:40:19:40:29:40:29:40:47":3,"s:41:21:41:Infinity":6,"s:42:18:46:Infinity":7,"s:47:2:47:Infinity":8,"s:48:2:50:Infinity":9,"s:51:2:51:Infinity":10,"f:58:16:58:39":1,"s:60:4:64:Infinity":11,"b:61:8:61:Infinity:62:8:64:Infinity":4,"b:63:10:63:Infinity:64:10:64:Infinity":5,"s:66:16:72:Infinity":12,"b:73:2:75:Infinity:undefined:undefined:undefined:undefined":6,"s:73:2:75:Infinity":13,"s:74:4:74:Infinity":14,"b:76:2:78:Infinity:undefined:undefined:undefined:undefined":7,"s:76:2:78:Infinity":15,"s:77:4:77:Infinity":16,"s:79:2:79:Infinity":17}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/errors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/errors.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"1":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"2":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"3":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"4":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"8":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"isHtmlErrorResponse","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":36}},"loc":{"start":{"line":23,"column":59},"end":{"line":25,"column":null}},"line":23},"1":{"name":"isDegradedKalenderSentinel","decl":{"start":{"line":48,"column":16},"end":{"line":48,"column":43}},"loc":{"start":{"line":48,"column":84},"end":{"line":52,"column":null}},"line":48},"2":{"name":"(anonymous_2)","decl":{"start":{"line":61,"column":2},"end":{"line":61,"column":14}},"loc":{"start":{"line":61,"column":86},"end":{"line":66,"column":null}},"line":61}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":25},"end":{"line":49,"column":63}},{"start":{"line":49,"column":63},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":61}},{"start":{"line":50,"column":61},"end":{"line":50,"column":null}}],"line":50},"2":{"loc":{"start":{"line":51,"column":9},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":9},"end":{"line":51,"column":27}},{"start":{"line":51,"column":27},"end":{"line":51,"column":null}}],"line":51}},"s":{"0":41,"1":32,"2":38,"3":38,"4":38,"5":25,"6":25,"7":25,"8":25},"f":{"0":32,"1":38,"2":25},"b":{"0":[38,10],"1":[38,10],"2":[38,29]},"meta":{"lastBranch":3,"lastFunction":3,"lastStatement":9,"seen":{"s:17:2:17:Infinity":0,"f:23:16:23:36":0,"s:24:2:24:Infinity":1,"f:48:16:48:43":1,"s:49:25:49:Infinity":2,"b:49:25:49:63:49:63:49:Infinity":0,"s:50:21:50:Infinity":3,"b:50:21:50:61:50:61:50:Infinity":1,"s:51:2:51:Infinity":4,"b:51:9:51:27:51:27:51:Infinity":2,"f:61:2:61:14":2,"s:62:4:62:Infinity":5,"s:63:4:63:Infinity":6,"s:64:4:64:Infinity":7,"s:65:4:65:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/client.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":31},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":35},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":35},"end":{"line":22,"column":null}},"4":{"start":{"line":44,"column":13},"end":{"line":44,"column":null}},"5":{"start":{"line":57,"column":31},"end":{"line":62,"column":null}},"6":{"start":{"line":64,"column":21},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":14},"end":{"line":65,"column":null}},"8":{"start":{"line":65,"column":31},"end":{"line":65,"column":51}},"9":{"start":{"line":68,"column":2},"end":{"line":94,"column":null}},"10":{"start":{"line":69,"column":21},"end":{"line":77,"column":null}},"11":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"12":{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},"13":{"start":{"line":82,"column":6},"end":{"line":86,"column":null}},"14":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"15":{"start":{"line":89,"column":41},"end":{"line":89,"column":null}},"16":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"17":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"18":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"19":{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},"20":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"21":{"start":{"line":101,"column":2},"end":{"line":108,"column":null}},"22":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"23":{"start":{"line":104,"column":4},"end":{"line":107,"column":null}},"24":{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},"25":{"start":{"line":111,"column":16},"end":{"line":111,"column":null}},"26":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"27":{"start":{"line":115,"column":17},"end":{"line":115,"column":null}},"28":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"29":{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},"30":{"start":{"line":120,"column":4},"end":{"line":127,"column":null}},"31":{"start":{"line":121,"column":6},"end":{"line":121,"column":null}},"32":{"start":{"line":123,"column":6},"end":{"line":126,"column":null}},"33":{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},"34":{"start":{"line":132,"column":6},"end":{"line":136,"column":null}},"35":{"start":{"line":138,"column":19},"end":{"line":138,"column":null}},"36":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"37":{"start":{"line":139,"column":31},"end":{"line":139,"column":null}},"38":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"39":{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},"40":{"start":{"line":144,"column":4},"end":{"line":148,"column":null}},"41":{"start":{"line":151,"column":17},"end":{"line":151,"column":null}},"42":{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},"43":{"start":{"line":152,"column":29},"end":{"line":152,"column":null}},"44":{"start":{"line":154,"column":2},"end":{"line":154,"column":null}}},"fnMap":{"0":{"name":"callMcpCalendarEvents","decl":{"start":{"line":52,"column":22},"end":{"line":52,"column":null}},"loc":{"start":{"line":56,"column":22},"end":{"line":155,"column":null}},"line":56},"1":{"name":"(anonymous_1)","decl":{"start":{"line":65,"column":14},"end":{"line":65,"column":31}},"loc":{"start":{"line":65,"column":31},"end":{"line":65,"column":51}},"line":65}},"branchMap":{"0":{"loc":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"type":"binary-expr","locations":[{"start":{"line":18,"column":2},"end":{"line":18,"column":35}},{"start":{"line":18,"column":35},"end":{"line":18,"column":null}}],"line":18},"1":{"loc":{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":81},"2":{"loc":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"type":"cond-expr","locations":[{"start":{"line":84,"column":44},"end":{"line":84,"column":53}},{"start":{"line":84,"column":53},"end":{"line":84,"column":null}}],"line":84},"3":{"loc":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"4":{"loc":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":90,"column":39},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":null}}],"line":90},"5":{"loc":{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":96},"6":{"loc":{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":110,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":110},"7":{"loc":{"start":{"line":111,"column":16},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":16},"end":{"line":111,"column":37}},{"start":{"line":111,"column":37},"end":{"line":111,"column":null}}],"line":111},"8":{"loc":{"start":{"line":115,"column":17},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":17},"end":{"line":115,"column":31}},{"start":{"line":115,"column":31},"end":{"line":115,"column":null}}],"line":115},"9":{"loc":{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":118},"10":{"loc":{"start":{"line":118,"column":6},"end":{"line":118,"column":50}},"type":"binary-expr","locations":[{"start":{"line":118,"column":6},"end":{"line":118,"column":32}},{"start":{"line":118,"column":32},"end":{"line":118,"column":50}}],"line":118},"11":{"loc":{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":131,"column":4},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":131},"12":{"loc":{"start":{"line":133,"column":45},"end":{"line":133,"column":84}},"type":"binary-expr","locations":[{"start":{"line":133,"column":45},"end":{"line":133,"column":63}},{"start":{"line":133,"column":63},"end":{"line":133,"column":84}}],"line":133},"13":{"loc":{"start":{"line":135,"column":8},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":135,"column":47},"end":{"line":135,"column":66}},{"start":{"line":135,"column":66},"end":{"line":135,"column":null}}],"line":135},"14":{"loc":{"start":{"line":138,"column":19},"end":{"line":138,"column":null}},"type":"binary-expr","locations":[{"start":{"line":138,"column":19},"end":{"line":138,"column":40}},{"start":{"line":138,"column":40},"end":{"line":138,"column":null}}],"line":138},"15":{"loc":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":139},"16":{"loc":{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":2},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":143},"17":{"loc":{"start":{"line":145,"column":43},"end":{"line":145,"column":83}},"type":"binary-expr","locations":[{"start":{"line":145,"column":43},"end":{"line":145,"column":62}},{"start":{"line":145,"column":62},"end":{"line":145,"column":83}}],"line":145},"18":{"loc":{"start":{"line":147,"column":6},"end":{"line":147,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":46},"end":{"line":147,"column":66}},{"start":{"line":147,"column":66},"end":{"line":147,"column":null}}],"line":147},"19":{"loc":{"start":{"line":151,"column":17},"end":{"line":151,"column":null}},"type":"binary-expr","locations":[{"start":{"line":151,"column":17},"end":{"line":151,"column":39}},{"start":{"line":151,"column":39},"end":{"line":151,"column":null}}],"line":151},"20":{"loc":{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":152,"column":null}},{"start":{},"end":{}}],"line":152}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":28,"6":28,"7":28,"8":0,"9":28,"10":28,"11":22,"12":22,"13":1,"14":7,"15":1,"16":6,"17":7,"18":28,"19":21,"20":4,"21":17,"22":17,"23":0,"24":17,"25":1,"26":1,"27":16,"28":28,"29":28,"30":11,"31":11,"32":1,"33":10,"34":4,"35":6,"36":11,"37":6,"38":0,"39":5,"40":2,"41":3,"42":28,"43":2,"44":1},"f":{"0":28,"1":0},"b":{"0":[9,9],"1":[1,21],"2":[0,1],"3":[1,6],"4":[6,0],"5":[4,17],"6":[1,16],"7":[1,0],"8":[16,0],"9":[11,17],"10":[28,11],"11":[4,6],"12":[4,0],"13":[3,1],"14":[6,0],"15":[6,5],"16":[2,3],"17":[2,1],"18":[1,1],"19":[3,2],"20":[2,26]},"meta":{"lastBranch":21,"lastFunction":2,"lastStatement":45,"seen":{"s:18:2:18:Infinity":0,"b:18:2:18:35:18:35:18:Infinity":0,"s:19:31:19:Infinity":1,"s:20:35:20:Infinity":2,"s:22:35:22:Infinity":3,"s:44:13:44:Infinity":4,"f:52:22:52:Infinity":0,"s:57:31:62:Infinity":5,"s:64:21:64:Infinity":6,"s:65:14:65:Infinity":7,"f:65:14:65:31":1,"s:65:31:65:51":8,"s:68:2:94:Infinity":9,"s:69:21:77:Infinity":10,"s:79:4:79:Infinity":11,"b:81:4:87:Infinity:undefined:undefined:undefined:undefined":1,"s:81:4:87:Infinity":12,"s:82:6:86:Infinity":13,"b:84:44:84:53:84:53:84:Infinity":2,"b:89:4:89:Infinity:undefined:undefined:undefined:undefined":3,"s:89:4:89:Infinity":14,"s:89:41:89:Infinity":15,"s:90:16:90:Infinity":16,"b:90:39:90:53:90:53:90:Infinity":4,"s:91:4:91:Infinity":17,"s:93:4:93:Infinity":18,"b:96:2:98:Infinity:undefined:undefined:undefined:undefined":5,"s:96:2:98:Infinity":19,"s:97:4:97:Infinity":20,"s:101:2:108:Infinity":21,"s:102:4:102:Infinity":22,"s:104:4:107:Infinity":23,"b:110:2:113:Infinity:undefined:undefined:undefined:undefined":6,"s:110:2:113:Infinity":24,"s:111:16:111:Infinity":25,"b:111:16:111:37:111:37:111:Infinity":7,"s:112:4:112:Infinity":26,"s:115:17:115:Infinity":27,"b:115:17:115:31:115:31:115:Infinity":8,"s:117:18:117:Infinity":28,"b:118:2:141:Infinity:undefined:undefined:undefined:undefined":9,"s:118:2:141:Infinity":29,"b:118:6:118:32:118:32:118:50":10,"s:120:4:127:Infinity":30,"s:121:6:121:Infinity":31,"s:123:6:126:Infinity":32,"b:131:4:137:Infinity:undefined:undefined:undefined:undefined":11,"s:131:4:137:Infinity":33,"s:132:6:136:Infinity":34,"b:133:45:133:63:133:63:133:84":12,"b:135:47:135:66:135:66:135:Infinity":13,"s:138:19:138:Infinity":35,"b:138:19:138:40:138:40:138:Infinity":14,"b:139:4:139:Infinity:undefined:undefined:undefined:undefined":15,"s:139:4:139:Infinity":36,"s:139:31:139:Infinity":37,"s:140:4:140:Infinity":38,"b:143:2:149:Infinity:undefined:undefined:undefined:undefined":16,"s:143:2:149:Infinity":39,"s:144:4:148:Infinity":40,"b:145:43:145:62:145:62:145:83":17,"b:147:46:147:66:147:66:147:Infinity":18,"s:151:17:151:Infinity":41,"b:151:17:151:39:151:39:151:Infinity":19,"b:152:2:152:Infinity:undefined:undefined:undefined:undefined":20,"s:152:2:152:Infinity":42,"s:152:29:152:Infinity":43,"s:154:2:154:Infinity":44}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/normaliser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/mcp/normaliser.ts","statementMap":{"0":{"start":{"line":21,"column":13},"end":{"line":21,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"3":{"start":{"line":25,"column":14},"end":{"line":25,"column":null}},"4":{"start":{"line":26,"column":14},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"6":{"start":{"line":29,"column":28},"end":{"line":29,"column":null}},"7":{"start":{"line":30,"column":2},"end":{"line":39,"column":null}},"8":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"11":{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},"12":{"start":{"line":35,"column":6},"end":{"line":37,"column":null}},"13":{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},"14":{"start":{"line":36,"column":53},"end":{"line":36,"column":null}},"15":{"start":{"line":41,"column":2},"end":{"line":49,"column":null}}},"fnMap":{"0":{"name":"normalizeMcpCalendarEvent","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":42}},"loc":{"start":{"line":20,"column":71},"end":{"line":50,"column":null}},"line":20}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":13},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":13},"end":{"line":21,"column":20}},{"start":{"line":21,"column":20},"end":{"line":21,"column":null}}],"line":21},"1":{"loc":{"start":{"line":23,"column":25},"end":{"line":23,"column":73}},"type":"binary-expr","locations":[{"start":{"line":23,"column":25},"end":{"line":23,"column":41}},{"start":{"line":23,"column":41},"end":{"line":23,"column":57}},{"start":{"line":23,"column":57},"end":{"line":23,"column":71}},{"start":{"line":23,"column":71},"end":{"line":23,"column":73}}],"line":23},"2":{"loc":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"type":"binary-expr","locations":[{"start":{"line":24,"column":16},"end":{"line":24,"column":77}},{"start":{"line":24,"column":77},"end":{"line":24,"column":null}}],"line":24},"3":{"loc":{"start":{"line":24,"column":23},"end":{"line":24,"column":65}},"type":"binary-expr","locations":[{"start":{"line":24,"column":23},"end":{"line":24,"column":37}},{"start":{"line":24,"column":37},"end":{"line":24,"column":51}},{"start":{"line":24,"column":51},"end":{"line":24,"column":63}},{"start":{"line":24,"column":63},"end":{"line":24,"column":65}}],"line":24},"4":{"loc":{"start":{"line":25,"column":21},"end":{"line":25,"column":78}},"type":"binary-expr","locations":[{"start":{"line":25,"column":21},"end":{"line":25,"column":35}},{"start":{"line":25,"column":35},"end":{"line":25,"column":47}},{"start":{"line":25,"column":47},"end":{"line":25,"column":59}},{"start":{"line":25,"column":59},"end":{"line":25,"column":76}},{"start":{"line":25,"column":76},"end":{"line":25,"column":78}}],"line":25},"5":{"loc":{"start":{"line":26,"column":21},"end":{"line":26,"column":77}},"type":"binary-expr","locations":[{"start":{"line":26,"column":21},"end":{"line":26,"column":33}},{"start":{"line":26,"column":33},"end":{"line":26,"column":45}},{"start":{"line":26,"column":45},"end":{"line":26,"column":58}},{"start":{"line":26,"column":58},"end":{"line":26,"column":75}},{"start":{"line":26,"column":75},"end":{"line":26,"column":77}}],"line":26},"6":{"loc":{"start":{"line":27,"column":25},"end":{"line":27,"column":87}},"type":"binary-expr","locations":[{"start":{"line":27,"column":25},"end":{"line":27,"column":41}},{"start":{"line":27,"column":41},"end":{"line":27,"column":57}},{"start":{"line":27,"column":57},"end":{"line":27,"column":71}},{"start":{"line":27,"column":71},"end":{"line":27,"column":85}},{"start":{"line":27,"column":85},"end":{"line":27,"column":87}}],"line":27},"7":{"loc":{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":38,"column":null}},{"start":{"line":34,"column":11},"end":{"line":38,"column":null}}],"line":32},"8":{"loc":{"start":{"line":32,"column":8},"end":{"line":32,"column":47}},"type":"binary-expr","locations":[{"start":{"line":32,"column":8},"end":{"line":32,"column":35}},{"start":{"line":32,"column":35},"end":{"line":32,"column":47}}],"line":32},"9":{"loc":{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":11},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":34},"10":{"loc":{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":8},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"11":{"loc":{"start":{"line":36,"column":12},"end":{"line":36,"column":53}},"type":"binary-expr","locations":[{"start":{"line":36,"column":12},"end":{"line":36,"column":40}},{"start":{"line":36,"column":40},"end":{"line":36,"column":53}}],"line":36},"12":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"type":"cond-expr","locations":[{"start":{"line":43,"column":16},"end":{"line":43,"column":28}},{"start":{"line":43,"column":28},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":14,"7":14,"8":84,"9":84,"10":6,"11":78,"12":1,"13":2,"14":2,"15":14},"f":{"0":14},"b":{"0":[14,1],"1":[14,2,1,1],"2":[14,12],"3":[14,12,12,12],"4":[14,1,1,1,1],"5":[14,1,1,1,1],"6":[14,2,1,1,1],"7":[6,78],"8":[84,6],"9":[1,77],"10":[2,0],"11":[2,2],"12":[2,12]},"meta":{"lastBranch":13,"lastFunction":1,"lastStatement":16,"seen":{"f:20:16:20:42":0,"s:21:13:21:Infinity":0,"b:21:13:21:20:21:20:21:Infinity":0,"s:23:18:23:Infinity":1,"b:23:25:23:41:23:41:23:57:23:57:23:71:23:71:23:73":1,"s:24:16:24:Infinity":2,"b:24:16:24:77:24:77:24:Infinity":2,"b:24:23:24:37:24:37:24:51:24:51:24:63:24:63:24:65":3,"s:25:14:25:Infinity":3,"b:25:21:25:35:25:35:25:47:25:47:25:59:25:59:25:76:25:76:25:78":4,"s:26:14:26:Infinity":4,"b:26:21:26:33:26:33:26:45:26:45:26:58:26:58:26:75:26:75:26:77":5,"s:27:18:27:Infinity":5,"b:27:25:27:41:27:41:27:57:27:57:27:71:27:71:27:85:27:85:27:87":6,"s:29:28:29:Infinity":6,"s:30:2:39:Infinity":7,"s:31:16:31:Infinity":8,"b:32:4:38:Infinity:34:11:38:Infinity":7,"s:32:4:38:Infinity":9,"b:32:8:32:35:32:35:32:47":8,"s:33:6:33:Infinity":10,"b:34:11:38:Infinity:undefined:undefined:undefined:undefined":9,"s:34:11:38:Infinity":11,"s:35:6:37:Infinity":12,"b:36:8:36:Infinity:undefined:undefined:undefined:undefined":10,"s:36:8:36:Infinity":13,"b:36:12:36:40:36:40:36:53":11,"s:36:53:36:Infinity":14,"s:41:2:49:Infinity":15,"b:43:16:43:28:43:28:43:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/article-block.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/article-block.ts","statementMap":{"0":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"2":{"start":{"line":34,"column":16},"end":{"line":34,"column":null}},"3":{"start":{"line":37,"column":4},"end":{"line":41,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":48,"column":null}},"5":{"start":{"line":50,"column":31},"end":{"line":50,"column":null}},"6":{"start":{"line":52,"column":2},"end":{"line":59,"column":null}}},"fnMap":{"0":{"name":"parseCalendarArticle","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":37}},"loc":{"start":{"line":32,"column":88},"end":{"line":60,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":37,"column":4},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},{"start":{"line":41,"column":4},"end":{"line":41,"column":null}}],"line":37},"2":{"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}},{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},{"start":{"line":48,"column":4},"end":{"line":48,"column":null}}],"line":44}},"s":{"0":11,"1":11,"2":1,"3":10,"4":11,"5":11,"6":11},"f":{"0":11},"b":{"0":[1,10],"1":[10,1,1,0,0],"2":[11,1,1,1,0]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":7,"seen":{"f:32:16:32:37":0,"s:33:18:33:Infinity":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":1,"s:34:16:34:Infinity":2,"s:37:4:41:Infinity":3,"b:37:4:37:Infinity:38:4:38:Infinity:39:4:39:Infinity:40:4:40:Infinity:41:4:41:Infinity":1,"s:44:4:48:Infinity":4,"b:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity:47:4:47:Infinity:48:4:48:Infinity":2,"s:50:31:50:Infinity":5,"s:52:2:59:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/orchestrator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/orchestrator.ts","statementMap":{"0":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"1":{"start":{"line":30,"column":34},"end":{"line":30,"column":57}},"2":{"start":{"line":46,"column":17},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"7":{"start":{"line":51,"column":18},"end":{"line":51,"column":null}},"8":{"start":{"line":52,"column":20},"end":{"line":52,"column":null}},"9":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"10":{"start":{"line":57,"column":2},"end":{"line":91,"column":null}},"11":{"start":{"line":57,"column":21},"end":{"line":57,"column":24}},"12":{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},"13":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"14":{"start":{"line":60,"column":6},"end":{"line":60,"column":null}},"15":{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},"16":{"start":{"line":64,"column":4},"end":{"line":90,"column":null}},"17":{"start":{"line":65,"column":6},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":72,"column":6},"end":{"line":81,"column":null}},"22":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"23":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"24":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"25":{"start":{"line":86,"column":6},"end":{"line":88,"column":null}},"26":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"27":{"start":{"line":89,"column":66},"end":{"line":89,"column":null}},"28":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"29":{"start":{"line":95,"column":2},"end":{"line":113,"column":null}},"30":{"start":{"line":96,"column":19},"end":{"line":96,"column":null}},"31":{"start":{"line":97,"column":4},"end":{"line":97,"column":null}},"32":{"start":{"line":99,"column":4},"end":{"line":109,"column":null}},"33":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"34":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"35":{"start":{"line":115,"column":2},"end":{"line":126,"column":null}}},"fnMap":{"0":{"name":"defaultSleep","decl":{"start":{"line":29,"column":9},"end":{"line":29,"column":22}},"loc":{"start":{"line":29,"column":49},"end":{"line":31,"column":null}},"line":29},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":13},"end":{"line":30,"column":22}},"loc":{"start":{"line":30,"column":34},"end":{"line":30,"column":57}},"line":30},"2":{"name":"fetchCalendarWithFallback","decl":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"loc":{"start":{"line":45,"column":32},"end":{"line":127,"column":null}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"default-arg","locations":[{"start":{"line":44,"column":32},"end":{"line":44,"column":null}}],"line":44},"1":{"loc":{"start":{"line":46,"column":17},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":17},"end":{"line":46,"column":34}},{"start":{"line":46,"column":34},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":21},"end":{"line":47,"column":42}},{"start":{"line":47,"column":42},"end":{"line":47,"column":null}}],"line":47},"3":{"loc":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":18},"end":{"line":48,"column":36}},{"start":{"line":48,"column":36},"end":{"line":48,"column":null}}],"line":48},"4":{"loc":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":42}},{"start":{"line":49,"column":42},"end":{"line":49,"column":null}}],"line":49},"5":{"loc":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":18},"end":{"line":50,"column":36}},{"start":{"line":50,"column":36},"end":{"line":50,"column":null}}],"line":50},"6":{"loc":{"start":{"line":51,"column":18},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":18},"end":{"line":51,"column":36}},{"start":{"line":51,"column":36},"end":{"line":51,"column":null}}],"line":51},"7":{"loc":{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":58},"8":{"loc":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":41},"end":{"line":83,"column":55}},{"start":{"line":83,"column":55},"end":{"line":83,"column":null}}],"line":83},"9":{"loc":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":53},"end":{"line":85,"column":64}},{"start":{"line":85,"column":64},"end":{"line":85,"column":null}}],"line":85},"10":{"loc":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"11":{"loc":{"start":{"line":89,"column":10},"end":{"line":89,"column":66}},"type":"binary-expr","locations":[{"start":{"line":89,"column":10},"end":{"line":89,"column":45}},{"start":{"line":89,"column":45},"end":{"line":89,"column":66}}],"line":89},"12":{"loc":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":43},"end":{"line":111,"column":57}},{"start":{"line":111,"column":57},"end":{"line":111,"column":null}}],"line":111}},"s":{"0":0,"1":0,"2":9,"3":9,"4":9,"5":9,"6":9,"7":9,"8":9,"9":9,"10":9,"11":9,"12":12,"13":3,"14":3,"15":3,"16":12,"17":12,"18":12,"19":4,"20":4,"21":4,"22":8,"23":8,"24":8,"25":8,"26":8,"27":3,"28":5,"29":5,"30":5,"31":4,"32":4,"33":1,"34":1,"35":1},"f":{"0":0,"1":0,"2":9},"b":{"0":[9],"1":[9,0],"2":[9,0],"3":[9,0],"4":[9,0],"5":[9,0],"6":[9,0],"7":[3,9],"8":[8,0],"9":[8,0],"10":[3,5],"11":[8,8],"12":[1,0]},"meta":{"lastBranch":13,"lastFunction":3,"lastStatement":36,"seen":{"f:29:9:29:22":0,"s:30:2:30:Infinity":0,"f:30:13:30:22":1,"s:30:34:30:57":1,"f:41:22:41:Infinity":2,"b:44:32:44:Infinity":0,"s:46:17:46:Infinity":2,"b:46:17:46:34:46:34:46:Infinity":1,"s:47:21:47:Infinity":3,"b:47:21:47:42:47:42:47:Infinity":2,"s:48:18:48:Infinity":4,"b:48:18:48:36:48:36:48:Infinity":3,"s:49:21:49:Infinity":5,"b:49:21:49:42:49:42:49:Infinity":4,"s:50:18:50:Infinity":6,"b:50:18:50:36:50:36:50:Infinity":5,"s:51:18:51:Infinity":7,"b:51:18:51:36:51:36:51:Infinity":6,"s:52:20:52:Infinity":8,"s:54:19:54:Infinity":9,"s:57:2:91:Infinity":10,"s:57:21:57:24":11,"b:58:4:62:Infinity:undefined:undefined:undefined:undefined":7,"s:58:4:62:Infinity":12,"s:59:20:59:Infinity":13,"s:60:6:60:Infinity":14,"s:61:6:61:Infinity":15,"s:64:4:90:Infinity":16,"s:65:6:67:Infinity":17,"s:68:18:68:Infinity":18,"s:69:21:69:Infinity":19,"s:70:6:70:Infinity":20,"s:72:6:81:Infinity":21,"s:83:18:83:Infinity":22,"b:83:41:83:55:83:55:83:Infinity":8,"s:84:6:84:Infinity":23,"s:85:19:85:Infinity":24,"b:85:53:85:64:85:64:85:Infinity":9,"s:86:6:88:Infinity":25,"b:89:6:89:Infinity:undefined:undefined:undefined:undefined":10,"s:89:6:89:Infinity":26,"b:89:10:89:45:89:45:89:66":11,"s:89:66:89:Infinity":27,"s:93:2:93:Infinity":28,"s:95:2:113:Infinity":29,"s:96:19:96:Infinity":30,"s:97:4:97:Infinity":31,"s:99:4:109:Infinity":32,"s:111:4:111:Infinity":33,"b:111:43:111:57:111:57:111:Infinity":12,"s:112:4:112:Infinity":34,"s:115:2:126:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/extractors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/extractors.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"1":{"start":{"line":22,"column":12},"end":{"line":22,"column":null}},"2":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"3":{"start":{"line":28,"column":13},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":12},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"6":{"start":{"line":35,"column":12},"end":{"line":35,"column":null}},"7":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"8":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"9":{"start":{"line":45,"column":13},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":12},"end":{"line":49,"column":null}},"11":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"12":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"13":{"start":{"line":62,"column":23},"end":{"line":62,"column":null}},"14":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"15":{"start":{"line":65,"column":28},"end":{"line":65,"column":null}},"16":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"17":{"start":{"line":67,"column":2},"end":{"line":72,"column":null}},"18":{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"22":{"start":{"line":79,"column":12},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"24":{"start":{"line":85,"column":2},"end":{"line":90,"column":null}},"25":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"26":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"27":{"start":{"line":106,"column":2},"end":{"line":110,"column":null}}},"fnMap":{"0":{"name":"escapeRegex","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":28}},"loc":{"start":{"line":16,"column":47},"end":{"line":18,"column":null}},"line":16},"1":{"name":"extractDatetime","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":32}},"loc":{"start":{"line":21,"column":61},"end":{"line":24,"column":null}},"line":21},"2":{"name":"extractDataAttr","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":32}},"loc":{"start":{"line":27,"column":76},"end":{"line":31,"column":null}},"line":27},"3":{"name":"hasCalendarItemClass","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":37}},"loc":{"start":{"line":34,"column":61},"end":{"line":37,"column":null}},"line":34},"4":{"name":"extractSpanText","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":32}},"loc":{"start":{"line":43,"column":75},"end":{"line":51,"column":null}},"line":43},"5":{"name":"extractHeadingAndLinks","decl":{"start":{"line":57,"column":16},"end":{"line":57,"column":39}},"loc":{"start":{"line":60,"column":2},"end":{"line":75,"column":null}},"line":60},"6":{"name":"extractFirstAnchorText","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":39}},"loc":{"start":{"line":78,"column":61},"end":{"line":81,"column":null}},"line":78},"7":{"name":"isRiksdagDocumentHref","decl":{"start":{"line":84,"column":16},"end":{"line":84,"column":38}},"loc":{"start":{"line":84,"column":61},"end":{"line":92,"column":null}},"line":84},"8":{"name":"stripTags","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":26}},"loc":{"start":{"line":95,"column":48},"end":{"line":97,"column":null}},"line":95},"9":{"name":"normalizeOrgCode","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":33}},"loc":{"start":{"line":100,"column":54},"end":{"line":102,"column":null}},"line":100},"10":{"name":"normalizeAkt","decl":{"start":{"line":105,"column":16},"end":{"line":105,"column":29}},"loc":{"start":{"line":105,"column":50},"end":{"line":111,"column":null}},"line":105}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":9},"end":{"line":23,"column":null}},"type":"cond-expr","locations":[{"start":{"line":23,"column":14},"end":{"line":23,"column":30}},{"start":{"line":23,"column":30},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":23,"column":14},"end":{"line":23,"column":30}},"type":"binary-expr","locations":[{"start":{"line":23,"column":14},"end":{"line":23,"column":22}},{"start":{"line":23,"column":22},"end":{"line":23,"column":30}}],"line":23},"2":{"loc":{"start":{"line":30,"column":9},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":29},"end":{"line":30,"column":43}},{"start":{"line":30,"column":43},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":30,"column":9},"end":{"line":30,"column":29}},"type":"binary-expr","locations":[{"start":{"line":30,"column":9},"end":{"line":30,"column":14}},{"start":{"line":30,"column":14},"end":{"line":30,"column":29}}],"line":30},"4":{"loc":{"start":{"line":36,"column":9},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":9},"end":{"line":36,"column":67}},{"start":{"line":36,"column":67},"end":{"line":36,"column":null}}],"line":36},"5":{"loc":{"start":{"line":36,"column":14},"end":{"line":36,"column":24}},"type":"binary-expr","locations":[{"start":{"line":36,"column":14},"end":{"line":36,"column":22}},{"start":{"line":36,"column":22},"end":{"line":36,"column":24}}],"line":36},"6":{"loc":{"start":{"line":50,"column":9},"end":{"line":50,"column":null}},"type":"cond-expr","locations":[{"start":{"line":50,"column":13},"end":{"line":50,"column":52}},{"start":{"line":50,"column":52},"end":{"line":50,"column":null}}],"line":50},"7":{"loc":{"start":{"line":50,"column":13},"end":{"line":50,"column":52}},"type":"binary-expr","locations":[{"start":{"line":50,"column":13},"end":{"line":50,"column":45}},{"start":{"line":50,"column":45},"end":{"line":50,"column":52}}],"line":50},"8":{"loc":{"start":{"line":50,"column":23},"end":{"line":50,"column":33}},"type":"binary-expr","locations":[{"start":{"line":50,"column":23},"end":{"line":50,"column":31}},{"start":{"line":50,"column":31},"end":{"line":50,"column":33}}],"line":50},"9":{"loc":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":34},"end":{"line":63,"column":59}},{"start":{"line":63,"column":59},"end":{"line":63,"column":null}}],"line":63},"10":{"loc":{"start":{"line":63,"column":34},"end":{"line":63,"column":59}},"type":"binary-expr","locations":[{"start":{"line":63,"column":34},"end":{"line":63,"column":53}},{"start":{"line":63,"column":53},"end":{"line":63,"column":59}}],"line":63},"11":{"loc":{"start":{"line":68,"column":18},"end":{"line":68,"column":28}},"type":"binary-expr","locations":[{"start":{"line":68,"column":18},"end":{"line":68,"column":26}},{"start":{"line":68,"column":26},"end":{"line":68,"column":28}}],"line":68},"12":{"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69},"13":{"loc":{"start":{"line":80,"column":9},"end":{"line":80,"column":null}},"type":"cond-expr","locations":[{"start":{"line":80,"column":14},"end":{"line":80,"column":28}},{"start":{"line":80,"column":28},"end":{"line":80,"column":null}}],"line":80},"14":{"loc":{"start":{"line":80,"column":14},"end":{"line":80,"column":28}},"type":"binary-expr","locations":[{"start":{"line":80,"column":14},"end":{"line":80,"column":22}},{"start":{"line":80,"column":22},"end":{"line":80,"column":28}}],"line":80},"15":{"loc":{"start":{"line":86,"column":4},"end":{"line":90,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},{"start":{"line":90,"column":4},"end":{"line":90,"column":null}}],"line":86}},"s":{"0":35,"1":17,"2":17,"3":28,"4":28,"5":28,"6":12,"7":12,"8":7,"9":7,"10":7,"11":7,"12":12,"13":12,"14":12,"15":12,"16":12,"17":12,"18":5,"19":5,"20":5,"21":12,"22":2,"23":2,"24":7,"25":18,"26":14,"27":12},"f":{"0":35,"1":17,"2":28,"3":12,"4":7,"5":12,"6":2,"7":7,"8":18,"9":14,"10":12},"b":{"0":[13,4],"1":[13,0],"2":[19,9],"3":[28,19],"4":[12,0],"5":[12,0],"6":[6,1],"7":[6,0],"8":[6,0],"9":[10,2],"10":[10,0],"11":[5,0],"12":[5,0],"13":[2,0],"14":[2,0],"15":[7,1,1,1,1]},"meta":{"lastBranch":16,"lastFunction":11,"lastStatement":28,"seen":{"f:16:16:16:28":0,"s:17:2:17:Infinity":0,"f:21:16:21:32":1,"s:22:12:22:Infinity":1,"s:23:2:23:Infinity":2,"b:23:14:23:30:23:30:23:Infinity":0,"b:23:14:23:22:23:22:23:30":1,"f:27:16:27:32":2,"s:28:13:28:Infinity":3,"s:29:12:29:Infinity":4,"s:30:2:30:Infinity":5,"b:30:29:30:43:30:43:30:Infinity":2,"b:30:9:30:14:30:14:30:29":3,"f:34:16:34:37":3,"s:35:12:35:Infinity":6,"s:36:2:36:Infinity":7,"b:36:9:36:67:36:67:36:Infinity":4,"b:36:14:36:22:36:22:36:24":5,"f:43:16:43:32":4,"s:44:15:44:Infinity":8,"s:45:13:48:Infinity":9,"s:49:12:49:Infinity":10,"s:50:2:50:Infinity":11,"b:50:13:50:52:50:52:50:Infinity":6,"b:50:13:50:45:50:45:50:52":7,"b:50:23:50:31:50:31:50:33":8,"f:57:16:57:39":5,"s:61:20:61:Infinity":12,"s:62:23:62:Infinity":13,"s:63:18:63:Infinity":14,"b:63:34:63:59:63:59:63:Infinity":9,"b:63:34:63:53:63:53:63:59":10,"s:65:28:65:Infinity":15,"s:66:17:66:Infinity":16,"s:67:2:72:Infinity":17,"s:68:10:68:Infinity":18,"b:68:18:68:26:68:26:68:28":11,"b:69:4:71:Infinity:undefined:undefined:undefined:undefined":12,"s:69:4:71:Infinity":19,"s:70:6:70:Infinity":20,"s:74:2:74:Infinity":21,"f:78:16:78:39":6,"s:79:12:79:Infinity":22,"s:80:2:80:Infinity":23,"b:80:14:80:28:80:28:80:Infinity":13,"b:80:14:80:22:80:22:80:28":14,"f:84:16:84:38":7,"s:85:2:90:Infinity":24,"b:86:4:86:Infinity:87:4:87:Infinity:88:4:88:Infinity:89:4:89:Infinity:90:4:90:Infinity":15,"f:95:16:95:26":8,"s:96:2:96:Infinity":25,"f:100:16:100:33":9,"s:101:2:101:Infinity":26,"f:105:16:105:29":10,"s:106:2:110:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/list-item.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/list-item.ts","statementMap":{"0":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"2":{"start":{"line":34,"column":16},"end":{"line":34,"column":null}},"3":{"start":{"line":37,"column":4},"end":{"line":40,"column":null}},"4":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"5":{"start":{"line":48,"column":31},"end":{"line":48,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"parseCalendarListItem","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":38}},"loc":{"start":{"line":32,"column":89},"end":{"line":58,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":37,"column":4},"end":{"line":40,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{"line":40,"column":4},"end":{"line":40,"column":null}}],"line":37},"2":{"loc":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}}],"line":43}},"s":{"0":3,"1":3,"2":1,"3":2,"4":3,"5":3,"6":3},"f":{"0":3},"b":{"0":[1,2],"1":[2,2,0,0],"2":[3,2,0,0]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":7,"seen":{"f:32:16:32:38":0,"s:33:18:33:Infinity":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":1,"s:34:16:34:Infinity":2,"s:37:4:40:Infinity":3,"b:37:4:37:Infinity:38:4:38:Infinity:39:4:39:Infinity:40:4:40:Infinity":1,"s:43:4:46:Infinity":4,"b:43:4:43:Infinity:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity":2,"s:48:31:48:Infinity":5,"s:50:2:57:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/parse.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-calendar/scraper/parse.ts","statementMap":{"0":{"start":{"line":28,"column":34},"end":{"line":28,"column":null}},"1":{"start":{"line":30,"column":20},"end":{"line":30,"column":null}},"2":{"start":{"line":31,"column":2},"end":{"line":37,"column":null}},"3":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"5":{"start":{"line":33,"column":38},"end":{"line":33,"column":null}},"6":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"7":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"8":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"9":{"start":{"line":36,"column":15},"end":{"line":36,"column":null}},"10":{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},"11":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"12":{"start":{"line":41,"column":4},"end":{"line":46,"column":null}},"13":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"14":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"15":{"start":{"line":44,"column":20},"end":{"line":44,"column":null}},"16":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"17":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"18":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"19":{"start":{"line":52,"column":36},"end":{"line":52,"column":null}},"20":{"start":{"line":64,"column":14},"end":{"line":66,"column":null}},"21":{"start":{"line":68,"column":21},"end":{"line":68,"column":null}},"22":{"start":{"line":69,"column":14},"end":{"line":69,"column":null}},"23":{"start":{"line":69,"column":31},"end":{"line":69,"column":51}},"24":{"start":{"line":72,"column":2},"end":{"line":94,"column":null}},"25":{"start":{"line":73,"column":21},"end":{"line":80,"column":null}},"26":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"27":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"28":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"29":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"30":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"31":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"32":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}}},"fnMap":{"0":{"name":"parseRiksdagKalendariumHtml","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":44}},"loc":{"start":{"line":27,"column":75},"end":{"line":50,"column":null}},"line":27},"1":{"name":"fetchWebCalendar","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":null}},"loc":{"start":{"line":63,"column":28},"end":{"line":97,"column":null}},"line":63},"2":{"name":"(anonymous_2)","decl":{"start":{"line":69,"column":14},"end":{"line":69,"column":31}},"loc":{"start":{"line":69,"column":31},"end":{"line":69,"column":51}},"line":69}},"branchMap":{"0":{"loc":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":18},"end":{"line":32,"column":37}},{"start":{"line":32,"column":37},"end":{"line":32,"column":null}}],"line":32},"1":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":17},"end":{"line":34,"column":36}},{"start":{"line":34,"column":36},"end":{"line":34,"column":null}}],"line":34},"3":{"loc":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":36},"4":{"loc":{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":39},"5":{"loc":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":20},"end":{"line":42,"column":34}},{"start":{"line":42,"column":34},"end":{"line":42,"column":null}}],"line":42},"6":{"loc":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":19},"end":{"line":43,"column":33}},{"start":{"line":43,"column":33},"end":{"line":43,"column":null}}],"line":43},"7":{"loc":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"8":{"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"9":{"loc":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":90,"column":39},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":null}}],"line":90}},"s":{"0":11,"1":11,"2":11,"3":9,"4":9,"5":1,"6":8,"7":9,"8":9,"9":8,"10":11,"11":4,"12":4,"13":1,"14":1,"15":1,"16":1,"17":1,"18":11,"19":9,"20":8,"21":8,"22":8,"23":0,"24":8,"25":8,"26":6,"27":1,"28":5,"29":3,"30":3,"31":8,"32":5},"f":{"0":11,"1":8,"2":0},"b":{"0":[9,0],"1":[1,8],"2":[8,0],"3":[8,1],"4":[4,7],"5":[1,0],"6":[1,0],"7":[1,0],"8":[1,5],"9":[3,0]},"meta":{"lastBranch":10,"lastFunction":3,"lastStatement":33,"seen":{"f:27:16:27:44":0,"s:28:34:28:Infinity":0,"s:30:20:30:Infinity":1,"s:31:2:37:Infinity":2,"s:32:18:32:Infinity":3,"b:32:18:32:37:32:37:32:Infinity":0,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":1,"s:33:4:33:Infinity":4,"s:33:38:33:Infinity":5,"s:34:17:34:Infinity":6,"b:34:17:34:36:34:36:34:Infinity":2,"s:35:18:35:Infinity":7,"b:36:4:36:Infinity:undefined:undefined:undefined:undefined":3,"s:36:4:36:Infinity":8,"s:36:15:36:Infinity":9,"b:39:2:47:Infinity:undefined:undefined:undefined:undefined":4,"s:39:2:47:Infinity":10,"s:40:17:40:Infinity":11,"s:41:4:46:Infinity":12,"s:42:20:42:Infinity":13,"b:42:20:42:34:42:34:42:Infinity":5,"s:43:19:43:Infinity":14,"b:43:19:43:33:43:33:43:Infinity":6,"s:44:20:44:Infinity":15,"b:45:6:45:Infinity:undefined:undefined:undefined:undefined":7,"s:45:6:45:Infinity":16,"s:45:17:45:Infinity":17,"s:49:2:49:Infinity":18,"s:52:36:52:Infinity":19,"f:59:22:59:Infinity":1,"s:64:14:66:Infinity":20,"s:68:21:68:Infinity":21,"s:69:14:69:Infinity":22,"f:69:14:69:31":2,"s:69:31:69:51":23,"s:72:2:94:Infinity":24,"s:73:21:80:Infinity":25,"b:82:4:86:Infinity:undefined:undefined:undefined:undefined":8,"s:82:4:86:Infinity":26,"s:83:6:85:Infinity":27,"s:88:4:88:Infinity":28,"s:90:16:90:Infinity":29,"b:90:39:90:53:90:53:90:Infinity":9,"s:91:4:91:Infinity":30,"s:93:4:93:Infinity":31,"s:96:2:96:Infinity":32}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-article-types-doc.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-article-types-doc.ts","statementMap":{"0":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":17},"end":{"line":24,"column":null}},"3":{"start":{"line":26,"column":23},"end":{"line":26,"column":null}},"4":{"start":{"line":27,"column":21},"end":{"line":27,"column":null}},"5":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"6":{"start":{"line":34,"column":41},"end":{"line":34,"column":null}},"7":{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},"8":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"9":{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"11":{"start":{"line":42,"column":2},"end":{"line":55,"column":null}},"12":{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},"13":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"14":{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},"15":{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},"16":{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},"17":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},"19":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"20":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"21":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"22":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"23":{"start":{"line":66,"column":15},"end":{"line":69,"column":null}},"24":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"25":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"26":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"27":{"start":{"line":79,"column":19},"end":{"line":79,"column":null}},"28":{"start":{"line":80,"column":17},"end":{"line":80,"column":null}},"29":{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},"30":{"start":{"line":83,"column":4},"end":{"line":85,"column":null}},"31":{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},"32":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"33":{"start":{"line":91,"column":17},"end":{"line":91,"column":null}},"34":{"start":{"line":92,"column":16},"end":{"line":92,"column":null}},"35":{"start":{"line":94,"column":18},"end":{"line":94,"column":null}},"36":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"37":{"start":{"line":106,"column":19},"end":{"line":106,"column":null}},"38":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"39":{"start":{"line":108,"column":14},"end":{"line":108,"column":null}},"40":{"start":{"line":109,"column":18},"end":{"line":109,"column":null}},"41":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"42":{"start":{"line":114,"column":15},"end":{"line":114,"column":null}},"43":{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},"44":{"start":{"line":116,"column":2},"end":{"line":122,"column":null}},"45":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"46":{"start":{"line":118,"column":4},"end":{"line":118,"column":null}},"47":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"48":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"loadAndValidateRegistry","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":40}},"loc":{"start":{"line":32,"column":84},"end":{"line":57,"column":null}},"line":32},"1":{"name":"renderTable","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":28}},"loc":{"start":{"line":62,"column":72},"end":{"line":72,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":66,"column":21},"end":{"line":66,"column":26}},"loc":{"start":{"line":66,"column":32},"end":{"line":69,"column":3}},"line":66},"3":{"name":"replaceBetweenSentinels","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":40}},"loc":{"start":{"line":78,"column":76},"end":{"line":97,"column":null}},"line":78},"4":{"name":"generate","decl":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"loc":{"start":{"line":105,"column":8},"end":{"line":111,"column":null}},"line":105}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":36},"1":{"loc":{"start":{"line":36,"column":6},"end":{"line":36,"column":78}},"type":"binary-expr","locations":[{"start":{"line":36,"column":6},"end":{"line":36,"column":27}},{"start":{"line":36,"column":27},"end":{"line":36,"column":46}},{"start":{"line":36,"column":46},"end":{"line":36,"column":78}}],"line":36},"2":{"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":39},"3":{"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":43},"4":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":82}},"type":"binary-expr","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":17}},{"start":{"line":43,"column":17},"end":{"line":43,"column":30}},{"start":{"line":43,"column":30},"end":{"line":43,"column":55}},{"start":{"line":43,"column":55},"end":{"line":43,"column":82}}],"line":43},"5":{"loc":{"start":{"line":44,"column":82},"end":{"line":44,"column":102}},"type":"binary-expr","locations":[{"start":{"line":44,"column":82},"end":{"line":44,"column":90}},{"start":{"line":44,"column":90},"end":{"line":44,"column":102}}],"line":44},"6":{"loc":{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":4},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"7":{"loc":{"start":{"line":46,"column":8},"end":{"line":46,"column":78}},"type":"binary-expr","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":38}},{"start":{"line":46,"column":38},"end":{"line":46,"column":78}}],"line":46},"8":{"loc":{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":49},"9":{"loc":{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":52},"10":{"loc":{"start":{"line":52,"column":8},"end":{"line":52,"column":46}},"type":"binary-expr","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":27}},{"start":{"line":52,"column":27},"end":{"line":52,"column":46}}],"line":52},"11":{"loc":{"start":{"line":67,"column":17},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":34},"end":{"line":67,"column":54}},{"start":{"line":67,"column":54},"end":{"line":67,"column":null}}],"line":67},"12":{"loc":{"start":{"line":67,"column":59},"end":{"line":67,"column":83}},"type":"binary-expr","locations":[{"start":{"line":67,"column":59},"end":{"line":67,"column":79}},{"start":{"line":67,"column":79},"end":{"line":67,"column":83}}],"line":67},"13":{"loc":{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"14":{"loc":{"start":{"line":82,"column":6},"end":{"line":82,"column":40}},"type":"binary-expr","locations":[{"start":{"line":82,"column":6},"end":{"line":82,"column":25}},{"start":{"line":82,"column":25},"end":{"line":82,"column":40}}],"line":82},"15":{"loc":{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":87},"16":{"loc":{"start":{"line":103,"column":2},"end":{"line":103,"column":null}},"type":"default-arg","locations":[{"start":{"line":103,"column":25},"end":{"line":103,"column":null}}],"line":103},"17":{"loc":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"type":"default-arg","locations":[{"start":{"line":104,"column":20},"end":{"line":104,"column":null}}],"line":104},"18":{"loc":{"start":{"line":114,"column":15},"end":{"line":114,"column":null}},"type":"binary-expr","locations":[{"start":{"line":114,"column":15},"end":{"line":114,"column":34}},{"start":{"line":114,"column":34},"end":{"line":114,"column":null}}],"line":114},"19":{"loc":{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":0},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":115}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":11,"6":11,"7":11,"8":1,"9":10,"10":1,"11":9,"12":69,"13":1,"14":68,"15":1,"16":67,"17":1,"18":66,"19":1,"20":5,"21":4,"22":4,"23":4,"24":52,"25":52,"26":4,"27":6,"28":6,"29":6,"30":1,"31":5,"32":1,"33":4,"34":4,"35":4,"36":4,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":0,"45":0,"46":0,"47":0,"48":0},"f":{"0":11,"1":4,"2":52,"3":6,"4":1},"b":{"0":[1,10],"1":[11,10,10],"2":[1,9],"3":[1,68],"4":[69,69,69,68],"5":[1,0],"6":[1,67],"7":[68,67],"8":[1,66],"9":[1,65],"10":[66,61],"11":[4,48],"12":[48,0],"13":[1,5],"14":[6,5],"15":[1,4],"16":[1],"17":[1],"18":[1,1],"19":[0,1]},"meta":{"lastBranch":20,"lastFunction":5,"lastStatement":49,"seen":{"s:22:19:22:Infinity":0,"s:23:18:23:Infinity":1,"s:24:17:24:Infinity":2,"s:26:23:26:Infinity":3,"s:27:21:27:Infinity":4,"f:32:16:32:40":0,"s:33:14:33:Infinity":5,"s:34:41:34:Infinity":6,"b:36:2:38:Infinity:undefined:undefined:undefined:undefined":0,"s:36:2:38:Infinity":7,"b:36:6:36:27:36:27:36:46:36:46:36:78":1,"s:37:4:37:Infinity":8,"b:39:2:41:Infinity:undefined:undefined:undefined:undefined":2,"s:39:2:41:Infinity":9,"s:40:4:40:Infinity":10,"s:42:2:55:Infinity":11,"b:43:4:45:Infinity:undefined:undefined:undefined:undefined":3,"s:43:4:45:Infinity":12,"b:43:8:43:17:43:17:43:30:43:30:43:55:43:55:43:82":4,"s:44:6:44:Infinity":13,"b:44:82:44:90:44:90:44:102":5,"b:46:4:48:Infinity:undefined:undefined:undefined:undefined":6,"s:46:4:48:Infinity":14,"b:46:8:46:38:46:38:46:78":7,"s:47:6:47:Infinity":15,"b:49:4:51:Infinity:undefined:undefined:undefined:undefined":8,"s:49:4:51:Infinity":16,"s:50:6:50:Infinity":17,"b:52:4:54:Infinity:undefined:undefined:undefined:undefined":9,"s:52:4:54:Infinity":18,"b:52:8:52:27:52:27:52:46":10,"s:53:6:53:Infinity":19,"s:56:2:56:Infinity":20,"f:62:16:62:28":1,"s:63:17:63:Infinity":21,"s:64:20:64:Infinity":22,"s:66:15:69:Infinity":23,"f:66:21:66:26":2,"s:67:17:67:Infinity":24,"b:67:34:67:54:67:54:67:Infinity":11,"b:67:59:67:79:67:79:67:83":12,"s:68:4:68:Infinity":25,"s:71:2:71:Infinity":26,"f:78:16:78:40":3,"s:79:19:79:Infinity":27,"s:80:17:80:Infinity":28,"b:82:2:86:Infinity:undefined:undefined:undefined:undefined":13,"s:82:2:86:Infinity":29,"b:82:6:82:25:82:25:82:40":14,"s:83:4:85:Infinity":30,"b:87:2:89:Infinity:undefined:undefined:undefined:undefined":15,"s:87:2:89:Infinity":31,"s:88:4:88:Infinity":32,"s:91:17:91:Infinity":33,"s:92:16:92:Infinity":34,"s:94:18:94:Infinity":35,"s:96:2:96:Infinity":36,"f:102:16:102:Infinity":4,"b:103:25:103:Infinity":16,"b:104:20:104:Infinity":17,"s:106:19:106:Infinity":37,"s:107:16:107:Infinity":38,"s:108:14:108:Infinity":39,"s:109:18:109:Infinity":40,"s:110:2:110:Infinity":41,"s:114:15:114:Infinity":42,"b:114:15:114:34:114:34:114:Infinity":18,"b:115:0:123:Infinity:undefined:undefined:undefined:undefined":19,"s:115:0:123:Infinity":43,"s:116:2:122:Infinity":44,"s:117:4:117:Infinity":45,"s:118:4:118:Infinity":46,"s:120:4:120:Infinity":47,"s:121:4:121:Infinity":48}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-statskontoret.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/fetch-statskontoret.ts","statementMap":{"0":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"1":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"2":{"start":{"line":53,"column":28},"end":{"line":53,"column":null}},"3":{"start":{"line":56,"column":40},"end":{"line":61,"column":null}},"4":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"5":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"6":{"start":{"line":109,"column":2},"end":{"line":114,"column":null}},"7":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"8":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"9":{"start":{"line":113,"column":4},"end":{"line":113,"column":null}},"10":{"start":{"line":118,"column":14},"end":{"line":118,"column":null}},"11":{"start":{"line":119,"column":2},"end":{"line":119,"column":null}},"12":{"start":{"line":120,"column":2},"end":{"line":120,"column":null}},"13":{"start":{"line":124,"column":14},"end":{"line":124,"column":null}},"14":{"start":{"line":125,"column":2},"end":{"line":125,"column":null}},"15":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"16":{"start":{"line":157,"column":17},"end":{"line":157,"column":null}},"17":{"start":{"line":158,"column":19},"end":{"line":158,"column":null}},"18":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"19":{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},"20":{"start":{"line":162,"column":23},"end":{"line":162,"column":null}},"21":{"start":{"line":163,"column":4},"end":{"line":172,"column":null}},"22":{"start":{"line":175,"column":17},"end":{"line":175,"column":null}},"23":{"start":{"line":179,"column":2},"end":{"line":203,"column":null}},"24":{"start":{"line":180,"column":4},"end":{"line":180,"column":null}},"25":{"start":{"line":181,"column":4},"end":{"line":181,"column":null}},"26":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"27":{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},"28":{"start":{"line":185,"column":25},"end":{"line":185,"column":null}},"29":{"start":{"line":186,"column":6},"end":{"line":195,"column":null}},"30":{"start":{"line":197,"column":19},"end":{"line":197,"column":null}},"31":{"start":{"line":198,"column":4},"end":{"line":202,"column":null}},"32":{"start":{"line":205,"column":2},"end":{"line":214,"column":null}},"33":{"start":{"line":229,"column":78},"end":{"line":229,"column":null}},"34":{"start":{"line":230,"column":19},"end":{"line":230,"column":null}},"35":{"start":{"line":231,"column":17},"end":{"line":231,"column":null}},"36":{"start":{"line":232,"column":2},"end":{"line":232,"column":null}},"37":{"start":{"line":240,"column":2},"end":{"line":240,"column":null}},"38":{"start":{"line":240,"column":42},"end":{"line":240,"column":47}}},"fnMap":{"0":{"name":"cacheDir","decl":{"start":{"line":100,"column":9},"end":{"line":100,"column":18}},"loc":{"start":{"line":100,"column":80},"end":{"line":102,"column":null}},"line":100},"1":{"name":"cacheFilePath","decl":{"start":{"line":104,"column":9},"end":{"line":104,"column":23}},"loc":{"start":{"line":104,"column":85},"end":{"line":106,"column":null}},"line":104},"2":{"name":"readCacheEntry","decl":{"start":{"line":108,"column":9},"end":{"line":108,"column":24}},"loc":{"start":{"line":108,"column":66},"end":{"line":115,"column":null}},"line":108},"3":{"name":"writeCacheEntry","decl":{"start":{"line":117,"column":9},"end":{"line":117,"column":25}},"loc":{"start":{"line":117,"column":68},"end":{"line":121,"column":null}},"line":117},"4":{"name":"isCacheFresh","decl":{"start":{"line":123,"column":9},"end":{"line":123,"column":22}},"loc":{"start":{"line":123,"column":65},"end":{"line":126,"column":null}},"line":123},"5":{"name":"fetchStatskontoretCached","decl":{"start":{"line":147,"column":22},"end":{"line":147,"column":null}},"loc":{"start":{"line":150,"column":39},"end":{"line":215,"column":null}},"line":150},"6":{"name":"isStatskontoretCacheFresh","decl":{"start":{"line":225,"column":16},"end":{"line":225,"column":null}},"loc":{"start":{"line":228,"column":11},"end":{"line":233,"column":null}},"line":228},"7":{"name":"statskontoretSourceKeys","decl":{"start":{"line":239,"column":16},"end":{"line":239,"column":77}},"loc":{"start":{"line":239,"column":77},"end":{"line":241,"column":null}},"line":239},"8":{"name":"(anonymous_8)","decl":{"start":{"line":240,"column":31},"end":{"line":240,"column":36}},"loc":{"start":{"line":240,"column":42},"end":{"line":240,"column":47}},"line":240}},"branchMap":{"0":{"loc":{"start":{"line":149,"column":2},"end":{"line":149,"column":null}},"type":"default-arg","locations":[{"start":{"line":149,"column":45},"end":{"line":149,"column":null}}],"line":149},"1":{"loc":{"start":{"line":152,"column":4},"end":{"line":152,"column":null}},"type":"default-arg","locations":[{"start":{"line":152,"column":17},"end":{"line":152,"column":null}}],"line":152},"2":{"loc":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"type":"default-arg","locations":[{"start":{"line":153,"column":16},"end":{"line":153,"column":null}}],"line":153},"3":{"loc":{"start":{"line":154,"column":4},"end":{"line":154,"column":null}},"type":"default-arg","locations":[{"start":{"line":154,"column":19},"end":{"line":154,"column":null}}],"line":154},"4":{"loc":{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":2},"end":{"line":173,"column":null}},{"start":{},"end":{}}],"line":161},"5":{"loc":{"start":{"line":161,"column":6},"end":{"line":161,"column":74}},"type":"binary-expr","locations":[{"start":{"line":161,"column":6},"end":{"line":161,"column":30}},{"start":{"line":161,"column":30},"end":{"line":161,"column":74}}],"line":161},"6":{"loc":{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":184},"7":{"loc":{"start":{"line":197,"column":19},"end":{"line":197,"column":null}},"type":"cond-expr","locations":[{"start":{"line":197,"column":44},"end":{"line":197,"column":60}},{"start":{"line":197,"column":60},"end":{"line":197,"column":null}}],"line":197},"8":{"loc":{"start":{"line":227,"column":2},"end":{"line":227,"column":null}},"type":"default-arg","locations":[{"start":{"line":227,"column":79},"end":{"line":227,"column":null}}],"line":227},"9":{"loc":{"start":{"line":229,"column":10},"end":{"line":229,"column":37}},"type":"default-arg","locations":[{"start":{"line":229,"column":23},"end":{"line":229,"column":37}}],"line":229},"10":{"loc":{"start":{"line":229,"column":37},"end":{"line":229,"column":78}},"type":"default-arg","locations":[{"start":{"line":229,"column":49},"end":{"line":229,"column":78}}],"line":229},"11":{"loc":{"start":{"line":232,"column":9},"end":{"line":232,"column":null}},"type":"binary-expr","locations":[{"start":{"line":232,"column":9},"end":{"line":232,"column":33}},{"start":{"line":232,"column":33},"end":{"line":232,"column":null}}],"line":232}},"s":{"0":1,"1":1,"2":1,"3":1,"4":6,"5":6,"6":6,"7":6,"8":6,"9":2,"10":0,"11":0,"12":0,"13":4,"14":4,"15":3,"16":3,"17":3,"18":3,"19":3,"20":1,"21":1,"22":2,"23":2,"24":2,"25":0,"26":0,"27":2,"28":1,"29":1,"30":1,"31":2,"32":0,"33":3,"34":3,"35":3,"36":3,"37":1,"38":4},"f":{"0":6,"1":6,"2":6,"3":0,"4":4,"5":3,"6":3,"7":1,"8":4},"b":{"0":[3],"1":[3],"2":[3],"3":[3],"4":[1,2],"5":[3,2],"6":[1,1],"7":[1,0],"8":[3],"9":[3],"10":[3],"11":[3,2]},"meta":{"lastBranch":12,"lastFunction":9,"lastStatement":39,"seen":{"s:49:19:49:Infinity":0,"s:50:18:50:Infinity":1,"s:53:28:53:Infinity":2,"s:56:40:61:Infinity":3,"f:100:9:100:18":0,"s:101:2:101:Infinity":4,"f:104:9:104:23":1,"s:105:2:105:Infinity":5,"f:108:9:108:24":2,"s:109:2:114:Infinity":6,"s:110:16:110:Infinity":7,"s:111:4:111:Infinity":8,"s:113:4:113:Infinity":9,"f:117:9:117:25":3,"s:118:14:118:Infinity":10,"s:119:2:119:Infinity":11,"s:120:2:120:Infinity":12,"f:123:9:123:22":4,"s:124:14:124:Infinity":13,"s:125:2:125:Infinity":14,"f:147:22:147:Infinity":5,"b:149:45:149:Infinity":0,"s:155:6:155:Infinity":15,"b:152:17:152:Infinity":1,"b:153:16:153:Infinity":2,"b:154:19:154:Infinity":3,"s:157:17:157:Infinity":16,"s:158:19:158:Infinity":17,"s:160:17:160:Infinity":18,"b:161:2:173:Infinity:undefined:undefined:undefined:undefined":4,"s:161:2:173:Infinity":19,"b:161:6:161:30:161:30:161:74":5,"s:162:23:162:Infinity":20,"s:163:4:172:Infinity":21,"s:175:17:175:Infinity":22,"s:179:2:203:Infinity":23,"s:180:4:180:Infinity":24,"s:181:4:181:Infinity":25,"s:182:4:182:Infinity":26,"b:184:4:196:Infinity:undefined:undefined:undefined:undefined":6,"s:184:4:196:Infinity":27,"s:185:25:185:Infinity":28,"s:186:6:195:Infinity":29,"s:197:19:197:Infinity":30,"b:197:44:197:60:197:60:197:Infinity":7,"s:198:4:202:Infinity":31,"s:205:2:214:Infinity":32,"f:225:16:225:Infinity":6,"b:227:79:227:Infinity":8,"s:229:78:229:Infinity":33,"b:229:23:229:37":9,"b:229:49:229:78":10,"s:230:19:230:Infinity":34,"s:231:17:231:Infinity":35,"s:232:2:232:Infinity":36,"b:232:9:232:33:232:33:232:Infinity":11,"f:239:16:239:77":7,"s:240:2:240:Infinity":37,"f:240:31:240:36":8,"s:240:42:240:47":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/language-flags.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/language-flags.ts","statementMap":{"0":{"start":{"line":11,"column":54},"end":{"line":15,"column":null}},"1":{"start":{"line":18,"column":65},"end":{"line":22,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":6,"1":6},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:11:54:15:Infinity":0,"s:18:65:22:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/article-merge.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/article-merge.ts","statementMap":{"0":{"start":{"line":23,"column":52},"end":{"line":23,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":35,"column":null}},"2":{"start":{"line":26,"column":4},"end":{"line":34,"column":null}},"3":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},"5":{"start":{"line":29,"column":8},"end":{"line":29,"column":null}},"6":{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},"7":{"start":{"line":32,"column":8},"end":{"line":32,"column":null}},"8":{"start":{"line":37,"column":52},"end":{"line":37,"column":null}},"9":{"start":{"line":39,"column":2},"end":{"line":46,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":45,"column":null}},"11":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"12":{"start":{"line":42,"column":33},"end":{"line":42,"column":null}},"13":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"14":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"buildSlugToLanguagesMap","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":40}},"loc":{"start":{"line":22,"column":121},"end":{"line":49,"column":null}},"line":22},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":33},"end":{"line":25,"column":42}},"loc":{"start":{"line":25,"column":63},"end":{"line":35,"column":3}},"line":25},"2":{"name":"(anonymous_2)","decl":{"start":{"line":26,"column":13},"end":{"line":26,"column":22}},"loc":{"start":{"line":26,"column":34},"end":{"line":34,"column":5}},"line":26},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":33},"end":{"line":39,"column":42}},"loc":{"start":{"line":39,"column":63},"end":{"line":46,"column":3}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":40,"column":13},"end":{"line":40,"column":22}},"loc":{"start":{"line":40,"column":34},"end":{"line":45,"column":5}},"line":40}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":6},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":6},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":31},"2":{"loc":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":41},"3":{"loc":{"start":{"line":43,"column":40},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":40},"end":{"line":43,"column":69}},{"start":{"line":43,"column":69},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":2,"1":2,"2":28,"3":12170,"4":12170,"5":1048,"6":12170,"7":12170,"8":2,"9":2,"10":28,"11":12170,"12":12170,"13":12170,"14":2},"f":{"0":2,"1":28,"2":12170,"3":28,"4":12170},"b":{"0":[1048,11122],"1":[12170,0],"2":[12170,0],"3":[12170,0]},"meta":{"lastBranch":4,"lastFunction":5,"lastStatement":15,"seen":{"f:22:16:22:40":0,"s:23:52:23:Infinity":0,"s:25:2:35:Infinity":1,"f:25:33:25:42":1,"s:26:4:34:Infinity":2,"f:26:13:26:22":2,"s:27:31:27:Infinity":3,"b:28:6:30:Infinity:undefined:undefined:undefined:undefined":0,"s:28:6:30:Infinity":4,"s:29:8:29:Infinity":5,"b:31:6:33:Infinity:undefined:undefined:undefined:undefined":1,"s:31:6:33:Infinity":6,"s:32:8:32:Infinity":7,"s:37:52:37:Infinity":8,"s:39:2:46:Infinity":9,"f:39:33:39:42":3,"s:40:4:45:Infinity":10,"f:40:13:40:22":4,"b:41:6:44:Infinity:undefined:undefined:undefined:undefined":2,"s:41:6:44:Infinity":11,"s:42:33:42:Infinity":12,"s:43:8:43:Infinity":13,"b:43:40:43:69:43:69:43:Infinity":3,"s:48:2:48:Infinity":14}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/languages.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/constants/languages.ts","statementMap":{"0":{"start":{"line":19,"column":63},"end":{"line":300,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":8},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:19:63:300:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/frontmatter.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/frontmatter.ts","statementMap":{"0":{"start":{"line":31,"column":2},"end":{"line":39,"column":null}},"1":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"3":{"start":{"line":33,"column":22},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":21},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"6":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"9":{"start":{"line":67,"column":21},"end":{"line":69,"column":null}},"10":{"start":{"line":68,"column":10},"end":{"line":68,"column":32}},"11":{"start":{"line":69,"column":19},"end":{"line":69,"column":31}},"12":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"13":{"start":{"line":70,"column":31},"end":{"line":70,"column":null}},"14":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"15":{"start":{"line":71,"column":28},"end":{"line":71,"column":47}},"16":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"17":{"start":{"line":81,"column":29},"end":{"line":81,"column":null}},"18":{"start":{"line":82,"column":52},"end":{"line":82,"column":null}},"19":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"20":{"start":{"line":83,"column":24},"end":{"line":83,"column":null}},"21":{"start":{"line":85,"column":29},"end":{"line":85,"column":null}},"22":{"start":{"line":86,"column":52},"end":{"line":86,"column":null}},"23":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"24":{"start":{"line":87,"column":24},"end":{"line":87,"column":null}},"25":{"start":{"line":89,"column":32},"end":{"line":89,"column":null}},"26":{"start":{"line":90,"column":55},"end":{"line":90,"column":null}},"27":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"28":{"start":{"line":91,"column":27},"end":{"line":91,"column":null}},"29":{"start":{"line":93,"column":32},"end":{"line":93,"column":null}},"30":{"start":{"line":94,"column":55},"end":{"line":94,"column":null}},"31":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"32":{"start":{"line":95,"column":27},"end":{"line":95,"column":null}},"33":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}},"34":{"start":{"line":104,"column":41},"end":{"line":104,"column":null}},"35":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"36":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"37":{"start":{"line":112,"column":16},"end":{"line":112,"column":null}},"38":{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},"39":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"40":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"41":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"42":{"start":{"line":122,"column":26},"end":{"line":122,"column":null}},"43":{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},"44":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"45":{"start":{"line":127,"column":2},"end":{"line":127,"column":null}},"46":{"start":{"line":134,"column":2},"end":{"line":149,"column":null}},"47":{"start":{"line":135,"column":49},"end":{"line":135,"column":null}},"48":{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},"49":{"start":{"line":136,"column":22},"end":{"line":136,"column":null}},"50":{"start":{"line":138,"column":31},"end":{"line":138,"column":null}},"51":{"start":{"line":139,"column":49},"end":{"line":139,"column":null}},"52":{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},"53":{"start":{"line":142,"column":30},"end":{"line":142,"column":null}},"54":{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},"55":{"start":{"line":146,"column":4},"end":{"line":146,"column":null}},"56":{"start":{"line":148,"column":4},"end":{"line":148,"column":null}},"57":{"start":{"line":156,"column":41},"end":{"line":156,"column":null}},"58":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}},"59":{"start":{"line":164,"column":2},"end":{"line":210,"column":null}},"60":{"start":{"line":165,"column":28},"end":{"line":165,"column":null}},"61":{"start":{"line":166,"column":29},"end":{"line":166,"column":null}},"62":{"start":{"line":168,"column":47},"end":{"line":168,"column":null}},"63":{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},"64":{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},"65":{"start":{"line":171,"column":6},"end":{"line":171,"column":null}},"66":{"start":{"line":174,"column":25},"end":{"line":174,"column":null}},"67":{"start":{"line":177,"column":6},"end":{"line":179,"column":null}},"68":{"start":{"line":180,"column":24},"end":{"line":184,"column":null}},"69":{"start":{"line":185,"column":33},"end":{"line":185,"column":null}},"70":{"start":{"line":186,"column":19},"end":{"line":186,"column":null}},"71":{"start":{"line":187,"column":24},"end":{"line":187,"column":null}},"72":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"73":{"start":{"line":189,"column":42},"end":{"line":204,"column":null}},"74":{"start":{"line":206,"column":4},"end":{"line":206,"column":null}},"75":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"76":{"start":{"line":209,"column":4},"end":{"line":209,"column":null}}},"fnMap":{"0":{"name":"extractDescriptionFromJSONLD","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":45}},"loc":{"start":{"line":30,"column":74},"end":{"line":40,"column":null}},"line":30},"1":{"name":"stripBrandSuffix","decl":{"start":{"line":49,"column":16},"end":{"line":49,"column":33}},"loc":{"start":{"line":49,"column":56},"end":{"line":51,"column":null}},"line":49},"2":{"name":"chooseBestDescription","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":null}},"loc":{"start":{"line":66,"column":10},"end":{"line":73,"column":null}},"line":66},"3":{"name":"(anonymous_3)","decl":{"start":{"line":68,"column":5},"end":{"line":68,"column":10}},"loc":{"start":{"line":68,"column":10},"end":{"line":68,"column":32}},"line":68},"4":{"name":"(anonymous_4)","decl":{"start":{"line":69,"column":5},"end":{"line":69,"column":13}},"loc":{"start":{"line":69,"column":19},"end":{"line":69,"column":31}},"line":69},"5":{"name":"(anonymous_5)","decl":{"start":{"line":71,"column":13},"end":{"line":71,"column":19}},"loc":{"start":{"line":71,"column":28},"end":{"line":71,"column":47}},"line":71},"6":{"name":"extractMetaContent","decl":{"start":{"line":80,"column":16},"end":{"line":80,"column":35}},"loc":{"start":{"line":80,"column":82},"end":{"line":98,"column":null}},"line":80},"7":{"name":"extractTitle","decl":{"start":{"line":103,"column":16},"end":{"line":103,"column":29}},"loc":{"start":{"line":103,"column":58},"end":{"line":106,"column":null}},"line":103},"8":{"name":"normalizeDateString","decl":{"start":{"line":111,"column":16},"end":{"line":111,"column":36}},"loc":{"start":{"line":111,"column":68},"end":{"line":128,"column":null}},"line":111},"9":{"name":"extractDateFromJSONLD","decl":{"start":{"line":133,"column":16},"end":{"line":133,"column":38}},"loc":{"start":{"line":133,"column":67},"end":{"line":150,"column":null}},"line":133},"10":{"name":"extractFromFilename","decl":{"start":{"line":155,"column":16},"end":{"line":155,"column":36}},"loc":{"start":{"line":155,"column":62},"end":{"line":158,"column":null}},"line":155},"11":{"name":"parseArticleMetadata","decl":{"start":{"line":163,"column":16},"end":{"line":163,"column":37}},"loc":{"start":{"line":163,"column":83},"end":{"line":211,"column":null}},"line":163}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"1":{"loc":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":60},"end":{"line":35,"column":90}},{"start":{"line":35,"column":90},"end":{"line":35,"column":null}}],"line":35},"2":{"loc":{"start":{"line":36,"column":11},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":29},"end":{"line":36,"column":36}},{"start":{"line":36,"column":36},"end":{"line":36,"column":null}}],"line":36},"3":{"loc":{"start":{"line":68,"column":17},"end":{"line":68,"column":24}},"type":"binary-expr","locations":[{"start":{"line":68,"column":17},"end":{"line":68,"column":22}},{"start":{"line":68,"column":22},"end":{"line":68,"column":24}}],"line":68},"4":{"loc":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":70},"5":{"loc":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},{"start":{},"end":{}}],"line":83},"6":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"7":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"8":{"loc":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"9":{"loc":{"start":{"line":105,"column":9},"end":{"line":105,"column":null}},"type":"cond-expr","locations":[{"start":{"line":105,"column":17},"end":{"line":105,"column":70}},{"start":{"line":105,"column":70},"end":{"line":105,"column":null}}],"line":105},"10":{"loc":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},{"start":{},"end":{}}],"line":112},"11":{"loc":{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":114},"12":{"loc":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":118},"13":{"loc":{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":2},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":123},"14":{"loc":{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":4},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":136},"15":{"loc":{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":4},"end":{"line":144,"column":null}},{"start":{},"end":{}}],"line":141},"16":{"loc":{"start":{"line":157,"column":9},"end":{"line":157,"column":null}},"type":"cond-expr","locations":[{"start":{"line":157,"column":17},"end":{"line":157,"column":29}},{"start":{"line":157,"column":29},"end":{"line":157,"column":null}}],"line":157},"17":{"loc":{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":169,"column":4},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":169},"18":{"loc":{"start":{"line":177,"column":6},"end":{"line":179,"column":null}},"type":"binary-expr","locations":[{"start":{"line":177,"column":6},"end":{"line":177,"column":null}},{"start":{"line":178,"column":6},"end":{"line":178,"column":null}},{"start":{"line":179,"column":6},"end":{"line":179,"column":null}}],"line":177},"19":{"loc":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"type":"cond-expr","locations":[{"start":{"line":188,"column":35},"end":{"line":188,"column":76}},{"start":{"line":188,"column":76},"end":{"line":188,"column":null}}],"line":188},"20":{"loc":{"start":{"line":195,"column":8},"end":{"line":198,"column":null}},"type":"binary-expr","locations":[{"start":{"line":195,"column":8},"end":{"line":195,"column":null}},{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},{"start":{"line":197,"column":8},"end":{"line":197,"column":null}},{"start":{"line":198,"column":8},"end":{"line":198,"column":null}}],"line":195},"21":{"loc":{"start":{"line":203,"column":10},"end":{"line":203,"column":null}},"type":"cond-expr","locations":[{"start":{"line":203,"column":21},"end":{"line":203,"column":36}},{"start":{"line":203,"column":36},"end":{"line":203,"column":null}}],"line":203}},"s":{"0":30454,"1":30454,"2":30454,"3":43,"4":30411,"5":30411,"6":30454,"7":115,"8":30454,"9":30454,"10":91362,"11":91362,"12":30454,"13":14,"14":30440,"15":60913,"16":30440,"17":152524,"18":152524,"19":152524,"20":151441,"21":1083,"22":1083,"23":1083,"24":0,"25":1083,"26":1083,"27":1083,"28":0,"29":1083,"30":1083,"31":1083,"32":0,"33":1083,"34":0,"35":0,"36":30454,"37":0,"38":30454,"39":254,"40":30200,"41":30200,"42":0,"43":0,"44":0,"45":0,"46":244,"47":244,"48":244,"49":14,"50":230,"51":230,"52":230,"53":230,"54":230,"55":0,"56":0,"57":14,"58":14,"59":30465,"60":30465,"61":30465,"62":30465,"63":30465,"64":11,"65":11,"66":30454,"67":30454,"68":30465,"69":30465,"70":30465,"71":30465,"72":30465,"73":30465,"74":30465,"75":0,"76":0},"f":{"0":30454,"1":30454,"2":30454,"3":91362,"4":91362,"5":60913,"6":152524,"7":0,"8":30454,"9":244,"10":14,"11":30465},"b":{"0":[43,30411],"1":[30036,260],"2":[30036,260],"3":[91362,510],"4":[14,30440],"5":[151441,1083],"6":[0,1083],"7":[0,1083],"8":[0,1083],"9":[0,0],"10":[0,30454],"11":[254,30200],"12":[30200,0],"13":[0,0],"14":[14,230],"15":[230,0],"16":[14,0],"17":[11,30454],"18":[30454,0,0],"19":[29961,493],"20":[30465,254,244,14],"21":[29961,493]},"meta":{"lastBranch":22,"lastFunction":12,"lastStatement":77,"seen":{"f:30:16:30:45":0,"s:31:2:39:Infinity":0,"s:32:24:32:Infinity":1,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":0,"s:33:4:33:Infinity":2,"s:33:22:33:Infinity":3,"s:34:21:34:Infinity":4,"s:35:17:35:Infinity":5,"b:35:60:35:90:35:90:35:Infinity":1,"s:36:4:36:Infinity":6,"b:36:29:36:36:36:36:36:Infinity":2,"s:38:4:38:Infinity":7,"f:49:16:49:33":1,"s:50:2:50:Infinity":8,"f:62:16:62:Infinity":2,"s:67:21:69:Infinity":9,"f:68:5:68:10":3,"s:68:10:68:32":10,"b:68:17:68:22:68:22:68:24":3,"f:69:5:69:13":4,"s:69:19:69:31":11,"b:70:2:70:Infinity:undefined:undefined:undefined:undefined":4,"s:70:2:70:Infinity":12,"s:70:31:70:Infinity":13,"s:71:2:71:Infinity":14,"f:71:13:71:19":5,"s:71:28:71:47":15,"s:72:2:72:Infinity":16,"f:80:16:80:35":6,"s:81:29:81:Infinity":17,"s:82:52:82:Infinity":18,"b:83:2:83:Infinity:undefined:undefined:undefined:undefined":5,"s:83:2:83:Infinity":19,"s:83:24:83:Infinity":20,"s:85:29:85:Infinity":21,"s:86:52:86:Infinity":22,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":6,"s:87:2:87:Infinity":23,"s:87:24:87:Infinity":24,"s:89:32:89:Infinity":25,"s:90:55:90:Infinity":26,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":7,"s:91:2:91:Infinity":27,"s:91:27:91:Infinity":28,"s:93:32:93:Infinity":29,"s:94:55:94:Infinity":30,"b:95:2:95:Infinity:undefined:undefined:undefined:undefined":8,"s:95:2:95:Infinity":31,"s:95:27:95:Infinity":32,"s:97:2:97:Infinity":33,"f:103:16:103:29":7,"s:104:41:104:Infinity":34,"s:105:2:105:Infinity":35,"b:105:17:105:70:105:70:105:Infinity":9,"f:111:16:111:36":8,"b:112:2:112:Infinity:undefined:undefined:undefined:undefined":10,"s:112:2:112:Infinity":36,"s:112:16:112:Infinity":37,"b:114:2:116:Infinity:undefined:undefined:undefined:undefined":11,"s:114:2:116:Infinity":38,"s:115:4:115:Infinity":39,"b:118:2:120:Infinity:undefined:undefined:undefined:undefined":12,"s:118:2:120:Infinity":40,"s:119:4:119:Infinity":41,"s:122:26:122:Infinity":42,"b:123:2:125:Infinity:undefined:undefined:undefined:undefined":13,"s:123:2:125:Infinity":43,"s:124:4:124:Infinity":44,"s:127:2:127:Infinity":45,"f:133:16:133:38":9,"s:134:2:149:Infinity":46,"s:135:49:135:Infinity":47,"b:136:4:136:Infinity:undefined:undefined:undefined:undefined":14,"s:136:4:136:Infinity":48,"s:136:22:136:Infinity":49,"s:138:31:138:Infinity":50,"s:139:49:139:Infinity":51,"b:141:4:144:Infinity:undefined:undefined:undefined:undefined":15,"s:141:4:144:Infinity":52,"s:142:30:142:Infinity":53,"s:143:6:143:Infinity":54,"s:146:4:146:Infinity":55,"s:148:4:148:Infinity":56,"f:155:16:155:36":10,"s:156:41:156:Infinity":57,"s:157:2:157:Infinity":58,"b:157:17:157:29:157:29:157:Infinity":16,"f:163:16:163:37":11,"s:164:2:210:Infinity":59,"s:165:28:165:Infinity":60,"s:166:29:166:Infinity":61,"s:168:47:168:Infinity":62,"b:169:4:172:Infinity:undefined:undefined:undefined:undefined":17,"s:169:4:172:Infinity":63,"s:170:6:170:Infinity":64,"s:171:6:171:Infinity":65,"s:174:25:174:Infinity":66,"s:177:6:179:Infinity":67,"b:177:6:177:Infinity:178:6:178:Infinity:179:6:179:Infinity":18,"s:180:24:184:Infinity":68,"s:185:33:185:Infinity":69,"s:186:19:186:Infinity":70,"s:187:24:187:Infinity":71,"s:188:21:188:Infinity":72,"b:188:35:188:76:188:76:188:Infinity":19,"s:189:42:204:Infinity":73,"b:195:8:195:Infinity:196:8:196:Infinity:197:8:197:Infinity:198:8:198:Infinity":20,"b:203:21:203:36:203:36:203:Infinity":21,"s:206:4:206:Infinity":74,"s:208:4:208:Infinity":75,"s:209:4:209:Infinity":76}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/i18n.ts","statementMap":{"0":{"start":{"line":18,"column":23},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":28},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":26},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":2},"end":{"line":21,"column":null}},"4":{"start":{"line":32,"column":50},"end":{"line":32,"column":null}},"5":{"start":{"line":33,"column":24},"end":{"line":39,"column":null}},"6":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"7":{"start":{"line":35,"column":29},"end":{"line":35,"column":null}},"8":{"start":{"line":36,"column":32},"end":{"line":36,"column":null}},"9":{"start":{"line":37,"column":26},"end":{"line":37,"column":null}},"10":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"11":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"12":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"13":{"start":{"line":47,"column":43},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"15":{"start":{"line":50,"column":32},"end":{"line":50,"column":null}},"16":{"start":{"line":51,"column":25},"end":{"line":51,"column":null}},"17":{"start":{"line":51,"column":49},"end":{"line":51,"column":83}},"18":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"generateLanguageBadge","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":38}},"loc":{"start":{"line":17,"column":84},"end":{"line":22,"column":null}},"line":17},"1":{"name":"generateLanguageSwitcherNav","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":44}},"loc":{"start":{"line":31,"column":73},"end":{"line":41,"column":null}},"line":31},"2":{"name":"(anonymous_2)","decl":{"start":{"line":33,"column":36},"end":{"line":33,"column":41}},"loc":{"start":{"line":33,"column":58},"end":{"line":39,"column":3}},"line":33},"3":{"name":"generateAvailableLanguages","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":43}},"loc":{"start":{"line":46,"column":93},"end":{"line":54,"column":null}},"line":46},"4":{"name":"(anonymous_4)","decl":{"start":{"line":51,"column":35},"end":{"line":51,"column":40}},"loc":{"start":{"line":51,"column":49},"end":{"line":51,"column":83}},"line":51}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":52},"end":{"line":17,"column":84}},"type":"default-arg","locations":[{"start":{"line":17,"column":69},"end":{"line":17,"column":84}}],"line":17},"1":{"loc":{"start":{"line":18,"column":23},"end":{"line":18,"column":null}},"type":"binary-expr","locations":[{"start":{"line":18,"column":23},"end":{"line":18,"column":47}},{"start":{"line":18,"column":47},"end":{"line":18,"column":null}}],"line":18},"2":{"loc":{"start":{"line":20,"column":26},"end":{"line":20,"column":null}},"type":"cond-expr","locations":[{"start":{"line":20,"column":34},"end":{"line":20,"column":49}},{"start":{"line":20,"column":49},"end":{"line":20,"column":null}}],"line":20},"3":{"loc":{"start":{"line":21,"column":64},"end":{"line":21,"column":129}},"type":"binary-expr","locations":[{"start":{"line":21,"column":64},"end":{"line":21,"column":124}},{"start":{"line":21,"column":124},"end":{"line":21,"column":129}}],"line":21},"4":{"loc":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":25},"end":{"line":34,"column":49}},{"start":{"line":34,"column":49},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":29},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":45},"end":{"line":35,"column":60}},{"start":{"line":35,"column":60},"end":{"line":35,"column":null}}],"line":35},"6":{"loc":{"start":{"line":36,"column":32},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":55},"end":{"line":36,"column":67}},{"start":{"line":36,"column":67},"end":{"line":36,"column":null}}],"line":36},"7":{"loc":{"start":{"line":37,"column":26},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":42},"end":{"line":37,"column":49}},{"start":{"line":37,"column":49},"end":{"line":37,"column":null}}],"line":37},"8":{"loc":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"9":{"loc":{"start":{"line":47,"column":6},"end":{"line":47,"column":43}},"type":"binary-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":20}},{"start":{"line":47,"column":20},"end":{"line":47,"column":43}}],"line":47},"10":{"loc":{"start":{"line":50,"column":32},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":32},"end":{"line":50,"column":74}},{"start":{"line":50,"column":74},"end":{"line":50,"column":null}}],"line":50}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0},"f":{"0":0,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0]},"meta":{"lastBranch":11,"lastFunction":5,"lastStatement":19,"seen":{"f:17:16:17:38":0,"b:17:69:17:84":0,"s:18:23:18:Infinity":0,"b:18:23:18:47:18:47:18:Infinity":1,"s:19:28:19:Infinity":1,"s:20:26:20:Infinity":2,"b:20:34:20:49:20:49:20:Infinity":2,"s:21:2:21:Infinity":3,"b:21:64:21:124:21:124:21:129":3,"f:31:16:31:44":1,"s:32:50:32:Infinity":4,"s:33:24:39:Infinity":5,"f:33:36:33:41":2,"s:34:25:34:Infinity":6,"b:34:25:34:49:34:49:34:Infinity":4,"s:35:29:35:Infinity":7,"b:35:45:35:60:35:60:35:Infinity":5,"s:36:32:36:Infinity":8,"b:36:55:36:67:36:67:36:Infinity":6,"s:37:26:37:Infinity":9,"b:37:42:37:49:37:49:37:Infinity":7,"s:38:4:38:Infinity":10,"s:40:2:40:Infinity":11,"f:46:16:46:43":3,"b:47:2:47:Infinity:undefined:undefined:undefined:undefined":8,"s:47:2:47:Infinity":12,"b:47:6:47:20:47:20:47:43":9,"s:47:43:47:Infinity":13,"s:49:25:49:Infinity":14,"s:50:32:50:Infinity":15,"b:50:32:50:74:50:74:50:Infinity":10,"s:51:25:51:Infinity":16,"f:51:35:51:40":4,"s:51:49:51:83":17,"s:53:2:53:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/article-grid.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/article-grid.ts","statementMap":{"0":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"skeletonCard","decl":{"start":{"line":13,"column":9},"end":{"line":13,"column":32}},"loc":{"start":{"line":13,"column":32},"end":{"line":22,"column":null}},"line":13},"1":{"name":"renderArticleGrid","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":34}},"loc":{"start":{"line":25,"column":64},"end":{"line":44,"column":null}},"line":25}},"branchMap":{},"s":{"0":99,"1":33},"f":{"0":99,"1":33},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":2,"seen":{"f:13:9:13:32":0,"s:14:2:14:Infinity":0,"f:25:16:25:34":1,"s:26:2:42:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/path-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/path-utils.ts","statementMap":{"0":{"start":{"line":17,"column":19},"end":{"line":17,"column":null}},"1":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"2":{"start":{"line":21,"column":32},"end":{"line":21,"column":null}},"3":{"start":{"line":28,"column":27},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":18},"end":{"line":29,"column":null}},"5":{"start":{"line":30,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":32,"column":6},"end":{"line":32,"column":null}},"8":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"9":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"10":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"11":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":47,"column":30},"end":{"line":47,"column":null}},"13":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"14":{"start":{"line":51,"column":64},"end":{"line":53,"column":null}},"15":{"start":{"line":52,"column":41},"end":{"line":52,"column":51}},"16":{"start":{"line":55,"column":2},"end":{"line":65,"column":null}},"17":{"start":{"line":56,"column":49},"end":{"line":56,"column":null}},"18":{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},"19":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"20":{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},"21":{"start":{"line":62,"column":8},"end":{"line":62,"column":null}},"22":{"start":{"line":67,"column":2},"end":{"line":69,"column":null}},"23":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"24":{"start":{"line":68,"column":41},"end":{"line":68,"column":96}},"25":{"start":{"line":71,"column":31},"end":{"line":73,"column":null}},"26":{"start":{"line":72,"column":25},"end":{"line":72,"column":39}},"27":{"start":{"line":73,"column":26},"end":{"line":73,"column":63}},"28":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"29":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}}},"fnMap":{"0":{"name":"collectArticleFiles","decl":{"start":{"line":27,"column":9},"end":{"line":27,"column":29}},"loc":{"start":{"line":27,"column":52},"end":{"line":38,"column":null}},"line":27},"1":{"name":"scanNewsArticles","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":74}},"loc":{"start":{"line":44,"column":74},"end":{"line":77,"column":null}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":52,"column":27},"end":{"line":52,"column":32}},"loc":{"start":{"line":52,"column":41},"end":{"line":52,"column":51}},"line":52},"3":{"name":"(anonymous_3)","decl":{"start":{"line":55,"column":12},"end":{"line":55,"column":21}},"loc":{"start":{"line":55,"column":34},"end":{"line":65,"column":3}},"line":55},"4":{"name":"(anonymous_4)","decl":{"start":{"line":67,"column":30},"end":{"line":67,"column":39}},"loc":{"start":{"line":67,"column":48},"end":{"line":69,"column":3}},"line":67},"5":{"name":"(anonymous_5)","decl":{"start":{"line":68,"column":26},"end":{"line":68,"column":32}},"loc":{"start":{"line":68,"column":41},"end":{"line":68,"column":96}},"line":68},"6":{"name":"(anonymous_6)","decl":{"start":{"line":72,"column":5},"end":{"line":72,"column":13}},"loc":{"start":{"line":72,"column":25},"end":{"line":72,"column":39}},"line":72},"7":{"name":"(anonymous_7)","decl":{"start":{"line":73,"column":5},"end":{"line":73,"column":10}},"loc":{"start":{"line":73,"column":26},"end":{"line":73,"column":63}},"line":73}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":35,"column":null}},{"start":{"line":33,"column":11},"end":{"line":35,"column":null}}],"line":31},"1":{"loc":{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":11},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33},"2":{"loc":{"start":{"line":33,"column":15},"end":{"line":33,"column":98}},"type":"binary-expr","locations":[{"start":{"line":33,"column":15},"end":{"line":33,"column":33}},{"start":{"line":33,"column":33},"end":{"line":33,"column":65}},{"start":{"line":33,"column":65},"end":{"line":33,"column":98}}],"line":33},"3":{"loc":{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":58},"4":{"loc":{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":6},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"5":{"loc":{"start":{"line":74,"column":44},"end":{"line":74,"column":106}},"type":"cond-expr","locations":[{"start":{"line":74,"column":68},"end":{"line":74,"column":92}},{"start":{"line":74,"column":92},"end":{"line":74,"column":106}}],"line":74}},"s":{"0":5,"1":5,"2":5,"3":40,"4":40,"5":40,"6":30731,"7":35,"8":30696,"9":30435,"10":40,"11":5,"12":5,"13":5,"14":5,"15":70,"16":5,"17":30435,"18":30435,"19":30425,"20":30425,"21":30425,"22":5,"23":70,"24":147430,"25":5,"26":70,"27":70,"28":5,"29":5},"f":{"0":40,"1":5,"2":70,"3":30435,"4":70,"5":147430,"6":70,"7":70},"b":{"0":[35,30696],"1":[30435,261],"2":[30696,30696,30561],"3":[30425,10],"4":[30425,0],"5":[5,0]},"meta":{"lastBranch":6,"lastFunction":8,"lastStatement":30,"seen":{"s:17:19:17:Infinity":0,"s:18:18:18:Infinity":1,"s:21:32:21:Infinity":2,"f:27:9:27:29":0,"s:28:27:28:Infinity":3,"s:29:18:29:Infinity":4,"s:30:2:36:Infinity":5,"b:31:4:35:Infinity:33:11:35:Infinity":0,"s:31:4:35:Infinity":6,"s:32:6:32:Infinity":7,"b:33:11:35:Infinity:undefined:undefined:undefined:undefined":1,"s:33:11:35:Infinity":8,"b:33:15:33:33:33:33:33:65:33:65:33:98":2,"s:34:6:34:Infinity":9,"s:37:2:37:Infinity":10,"f:44:16:44:74":1,"s:45:2:45:Infinity":11,"s:47:30:47:Infinity":12,"s:49:2:49:Infinity":13,"s:51:64:53:Infinity":14,"f:52:27:52:32":2,"s:52:41:52:51":15,"s:55:2:65:Infinity":16,"f:55:12:55:21":3,"s:56:49:56:Infinity":17,"b:58:4:64:Infinity:undefined:undefined:undefined:undefined":3,"s:58:4:64:Infinity":18,"s:59:6:59:Infinity":19,"b:61:6:63:Infinity:undefined:undefined:undefined:undefined":4,"s:61:6:63:Infinity":20,"s:62:8:62:Infinity":21,"s:67:2:69:Infinity":22,"f:67:30:67:39":4,"s:68:4:68:Infinity":23,"f:68:26:68:32":5,"s:68:41:68:96":24,"s:71:31:73:Infinity":25,"f:72:5:72:13":6,"s:72:25:72:39":26,"f:73:5:73:10":7,"s:73:26:73:63":27,"s:74:2:74:Infinity":28,"b:74:68:74:92:74:92:74:106":5,"s:76:2:76:Infinity":29}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/slug.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/helpers/slug.ts","statementMap":{"0":{"start":{"line":20,"column":19},"end":{"line":20,"column":null}},"1":{"start":{"line":23,"column":38},"end":{"line":23,"column":null}},"2":{"start":{"line":25,"column":75},"end":{"line":33,"column":null}},"3":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},"5":{"start":{"line":45,"column":17},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":18},"end":{"line":46,"column":null}},"7":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"8":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"9":{"start":{"line":48,"column":52},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":42},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"13":{"start":{"line":50,"column":49},"end":{"line":50,"column":null}},"14":{"start":{"line":52,"column":18},"end":{"line":52,"column":null}},"15":{"start":{"line":53,"column":4},"end":{"line":61,"column":null}},"16":{"start":{"line":53,"column":17},"end":{"line":53,"column":35}},"17":{"start":{"line":54,"column":21},"end":{"line":54,"column":null}},"18":{"start":{"line":55,"column":26},"end":{"line":55,"column":null}},"19":{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},"20":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"21":{"start":{"line":57,"column":60},"end":{"line":57,"column":null}},"22":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"23":{"start":{"line":58,"column":50},"end":{"line":58,"column":null}},"24":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"25":{"start":{"line":59,"column":57},"end":{"line":59,"column":null}},"26":{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},"27":{"start":{"line":65,"column":22},"end":{"line":65,"column":null}},"28":{"start":{"line":66,"column":25},"end":{"line":66,"column":null}},"29":{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},"30":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"31":{"start":{"line":69,"column":20},"end":{"line":69,"column":null}},"32":{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},"33":{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},"34":{"start":{"line":71,"column":54},"end":{"line":71,"column":null}},"35":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"36":{"start":{"line":72,"column":44},"end":{"line":72,"column":null}},"37":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"38":{"start":{"line":73,"column":51},"end":{"line":73,"column":null}},"39":{"start":{"line":78,"column":31},"end":{"line":78,"column":null}},"40":{"start":{"line":80,"column":40},"end":{"line":95,"column":null}},"41":{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},"42":{"start":{"line":97,"column":110},"end":{"line":97,"column":149}},"43":{"start":{"line":98,"column":4},"end":{"line":98,"column":null}},"44":{"start":{"line":101,"column":37},"end":{"line":116,"column":null}},"45":{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},"46":{"start":{"line":120,"column":36},"end":{"line":120,"column":75}},"47":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"48":{"start":{"line":124,"column":37},"end":{"line":139,"column":null}},"49":{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},"50":{"start":{"line":141,"column":69},"end":{"line":141,"column":108}},"51":{"start":{"line":142,"column":4},"end":{"line":142,"column":null}},"52":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"53":{"start":{"line":153,"column":27},"end":{"line":153,"column":null}},"54":{"start":{"line":154,"column":21},"end":{"line":154,"column":null}},"55":{"start":{"line":157,"column":2},"end":{"line":166,"column":null}},"56":{"start":{"line":158,"column":24},"end":{"line":158,"column":null}},"57":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"58":{"start":{"line":159,"column":28},"end":{"line":159,"column":null}},"59":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"60":{"start":{"line":160,"column":214},"end":{"line":160,"column":null}},"61":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"62":{"start":{"line":161,"column":308},"end":{"line":161,"column":null}},"63":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"64":{"start":{"line":162,"column":373},"end":{"line":162,"column":null}},"65":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"66":{"start":{"line":163,"column":352},"end":{"line":163,"column":null}},"67":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"68":{"start":{"line":164,"column":374},"end":{"line":164,"column":null}},"69":{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},"70":{"start":{"line":165,"column":352},"end":{"line":165,"column":null}},"71":{"start":{"line":168,"column":23},"end":{"line":168,"column":null}},"72":{"start":{"line":169,"column":2},"end":{"line":171,"column":null}},"73":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"74":{"start":{"line":170,"column":36},"end":{"line":170,"column":null}},"75":{"start":{"line":173,"column":2},"end":{"line":173,"column":null}},"76":{"start":{"line":180,"column":25},"end":{"line":180,"column":null}},"77":{"start":{"line":181,"column":21},"end":{"line":181,"column":null}},"78":{"start":{"line":184,"column":2},"end":{"line":186,"column":null}},"79":{"start":{"line":185,"column":4},"end":{"line":185,"column":null}},"80":{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},"81":{"start":{"line":189,"column":4},"end":{"line":189,"column":null}},"82":{"start":{"line":190,"column":25},"end":{"line":190,"column":null}},"83":{"start":{"line":191,"column":4},"end":{"line":191,"column":null}},"84":{"start":{"line":194,"column":2},"end":{"line":194,"column":null}},"85":{"start":{"line":194,"column":42},"end":{"line":194,"column":63}}},"fnMap":{"0":{"name":"classifyArticleType","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":36}},"loc":{"start":{"line":42,"column":112},"end":{"line":146,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":97,"column":97},"end":{"line":97,"column":103}},"loc":{"start":{"line":97,"column":110},"end":{"line":97,"column":149}},"line":97},"2":{"name":"(anonymous_2)","decl":{"start":{"line":120,"column":23},"end":{"line":120,"column":29}},"loc":{"start":{"line":120,"column":36},"end":{"line":120,"column":75}},"line":120},"3":{"name":"(anonymous_3)","decl":{"start":{"line":141,"column":56},"end":{"line":141,"column":62}},"loc":{"start":{"line":141,"column":69},"end":{"line":141,"column":108}},"line":141},"4":{"name":"extractTopics","decl":{"start":{"line":152,"column":16},"end":{"line":152,"column":30}},"loc":{"start":{"line":152,"column":80},"end":{"line":174,"column":null}},"line":152},"5":{"name":"extractTags","decl":{"start":{"line":179,"column":16},"end":{"line":179,"column":28}},"loc":{"start":{"line":179,"column":105},"end":{"line":195,"column":null}},"line":179},"6":{"name":"(anonymous_6)","decl":{"start":{"line":194,"column":26},"end":{"line":194,"column":34}},"loc":{"start":{"line":194,"column":42},"end":{"line":194,"column":63}},"line":194}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"4":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"5":{"loc":{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57},"7":{"loc":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"8":{"loc":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"9":{"loc":{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":64},"10":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":50}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":22}},{"start":{"line":64,"column":22},"end":{"line":64,"column":50}}],"line":64},"11":{"loc":{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":67},"12":{"loc":{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":6},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":70},"13":{"loc":{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":8},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":71},"14":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"15":{"loc":{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":8},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"16":{"loc":{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":2},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":97},"17":{"loc":{"start":{"line":97,"column":6},"end":{"line":97,"column":152}},"type":"binary-expr","locations":[{"start":{"line":97,"column":6},"end":{"line":97,"column":41}},{"start":{"line":97,"column":41},"end":{"line":97,"column":77}},{"start":{"line":97,"column":77},"end":{"line":97,"column":152}}],"line":97},"18":{"loc":{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":122,"column":null}},{"start":{},"end":{}}],"line":118},"19":{"loc":{"start":{"line":118,"column":6},"end":{"line":120,"column":78}},"type":"binary-expr","locations":[{"start":{"line":118,"column":6},"end":{"line":118,"column":48}},{"start":{"line":118,"column":48},"end":{"line":118,"column":85}},{"start":{"line":118,"column":85},"end":{"line":118,"column":null}},{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},{"start":{"line":120,"column":6},"end":{"line":120,"column":78}}],"line":118},"20":{"loc":{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":2},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":141},"21":{"loc":{"start":{"line":141,"column":6},"end":{"line":141,"column":111}},"type":"binary-expr","locations":[{"start":{"line":141,"column":6},"end":{"line":141,"column":39}},{"start":{"line":141,"column":39},"end":{"line":141,"column":111}}],"line":141},"22":{"loc":{"start":{"line":152,"column":47},"end":{"line":152,"column":80}},"type":"default-arg","locations":[{"start":{"line":152,"column":66},"end":{"line":152,"column":80}}],"line":152},"23":{"loc":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"type":"if","locations":[{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},{"start":{},"end":{}}],"line":159},"24":{"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":160},"25":{"loc":{"start":{"line":160,"column":8},"end":{"line":160,"column":214}},"type":"binary-expr","locations":[{"start":{"line":160,"column":8},"end":{"line":160,"column":38}},{"start":{"line":160,"column":38},"end":{"line":160,"column":65}},{"start":{"line":160,"column":65},"end":{"line":160,"column":96}},{"start":{"line":160,"column":96},"end":{"line":160,"column":118}},{"start":{"line":160,"column":118},"end":{"line":160,"column":140}},{"start":{"line":160,"column":140},"end":{"line":160,"column":162}},{"start":{"line":160,"column":162},"end":{"line":160,"column":190}},{"start":{"line":160,"column":190},"end":{"line":160,"column":214}}],"line":160},"26":{"loc":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":161},"27":{"loc":{"start":{"line":161,"column":8},"end":{"line":161,"column":308}},"type":"binary-expr","locations":[{"start":{"line":161,"column":8},"end":{"line":161,"column":38}},{"start":{"line":161,"column":38},"end":{"line":161,"column":66}},{"start":{"line":161,"column":66},"end":{"line":161,"column":97}},{"start":{"line":161,"column":97},"end":{"line":161,"column":125}},{"start":{"line":161,"column":125},"end":{"line":161,"column":154}},{"start":{"line":161,"column":154},"end":{"line":161,"column":186}},{"start":{"line":161,"column":186},"end":{"line":161,"column":214}},{"start":{"line":161,"column":214},"end":{"line":161,"column":236}},{"start":{"line":161,"column":236},"end":{"line":161,"column":258}},{"start":{"line":161,"column":258},"end":{"line":161,"column":285}},{"start":{"line":161,"column":285},"end":{"line":161,"column":308}}],"line":161},"28":{"loc":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},{"start":{},"end":{}}],"line":162},"29":{"loc":{"start":{"line":162,"column":8},"end":{"line":162,"column":373}},"type":"binary-expr","locations":[{"start":{"line":162,"column":8},"end":{"line":162,"column":35}},{"start":{"line":162,"column":35},"end":{"line":162,"column":62}},{"start":{"line":162,"column":62},"end":{"line":162,"column":89}},{"start":{"line":162,"column":89},"end":{"line":162,"column":116}},{"start":{"line":162,"column":116},"end":{"line":162,"column":145}},{"start":{"line":162,"column":145},"end":{"line":162,"column":177}},{"start":{"line":162,"column":177},"end":{"line":162,"column":204}},{"start":{"line":162,"column":204},"end":{"line":162,"column":231}},{"start":{"line":162,"column":231},"end":{"line":162,"column":259}},{"start":{"line":162,"column":259},"end":{"line":162,"column":285}},{"start":{"line":162,"column":285},"end":{"line":162,"column":309}},{"start":{"line":162,"column":309},"end":{"line":162,"column":331}},{"start":{"line":162,"column":331},"end":{"line":162,"column":353}},{"start":{"line":162,"column":353},"end":{"line":162,"column":373}}],"line":162},"30":{"loc":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"31":{"loc":{"start":{"line":163,"column":8},"end":{"line":163,"column":352}},"type":"binary-expr","locations":[{"start":{"line":163,"column":8},"end":{"line":163,"column":39}},{"start":{"line":163,"column":39},"end":{"line":163,"column":64}},{"start":{"line":163,"column":64},"end":{"line":163,"column":89}},{"start":{"line":163,"column":89},"end":{"line":163,"column":118}},{"start":{"line":163,"column":118},"end":{"line":163,"column":144}},{"start":{"line":163,"column":144},"end":{"line":163,"column":177}},{"start":{"line":163,"column":177},"end":{"line":163,"column":211}},{"start":{"line":163,"column":211},"end":{"line":163,"column":237}},{"start":{"line":163,"column":237},"end":{"line":163,"column":263}},{"start":{"line":163,"column":263},"end":{"line":163,"column":288}},{"start":{"line":163,"column":288},"end":{"line":163,"column":310}},{"start":{"line":163,"column":310},"end":{"line":163,"column":332}},{"start":{"line":163,"column":332},"end":{"line":163,"column":352}}],"line":163},"32":{"loc":{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":164,"column":4},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":164},"33":{"loc":{"start":{"line":164,"column":8},"end":{"line":164,"column":374}},"type":"binary-expr","locations":[{"start":{"line":164,"column":8},"end":{"line":164,"column":37}},{"start":{"line":164,"column":37},"end":{"line":164,"column":64}},{"start":{"line":164,"column":64},"end":{"line":164,"column":90}},{"start":{"line":164,"column":90},"end":{"line":164,"column":116}},{"start":{"line":164,"column":116},"end":{"line":164,"column":145}},{"start":{"line":164,"column":145},"end":{"line":164,"column":174}},{"start":{"line":164,"column":174},"end":{"line":164,"column":204}},{"start":{"line":164,"column":204},"end":{"line":164,"column":230}},{"start":{"line":164,"column":230},"end":{"line":164,"column":259}},{"start":{"line":164,"column":259},"end":{"line":164,"column":283}},{"start":{"line":164,"column":283},"end":{"line":164,"column":307}},{"start":{"line":164,"column":307},"end":{"line":164,"column":330}},{"start":{"line":164,"column":330},"end":{"line":164,"column":353}},{"start":{"line":164,"column":353},"end":{"line":164,"column":374}}],"line":164},"34":{"loc":{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":165,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":165},"35":{"loc":{"start":{"line":165,"column":8},"end":{"line":165,"column":352}},"type":"binary-expr","locations":[{"start":{"line":165,"column":8},"end":{"line":165,"column":39}},{"start":{"line":165,"column":39},"end":{"line":165,"column":71}},{"start":{"line":165,"column":71},"end":{"line":165,"column":101}},{"start":{"line":165,"column":101},"end":{"line":165,"column":133}},{"start":{"line":165,"column":133},"end":{"line":165,"column":165}},{"start":{"line":165,"column":165},"end":{"line":165,"column":196}},{"start":{"line":165,"column":196},"end":{"line":165,"column":227}},{"start":{"line":165,"column":227},"end":{"line":165,"column":256}},{"start":{"line":165,"column":256},"end":{"line":165,"column":285}},{"start":{"line":165,"column":285},"end":{"line":165,"column":310}},{"start":{"line":165,"column":310},"end":{"line":165,"column":332}},{"start":{"line":165,"column":332},"end":{"line":165,"column":352}}],"line":165},"36":{"loc":{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},"type":"if","locations":[{"start":{"line":170,"column":4},"end":{"line":170,"column":null}},{"start":{},"end":{}}],"line":170},"37":{"loc":{"start":{"line":179,"column":45},"end":{"line":179,"column":68}},"type":"default-arg","locations":[{"start":{"line":179,"column":64},"end":{"line":179,"column":68}}],"line":179},"38":{"loc":{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":188,"column":2},"end":{"line":192,"column":null}},{"start":{},"end":{}}],"line":188}},"s":{"0":5,"1":5,"2":5,"3":49242,"4":49242,"5":49172,"6":49172,"7":49172,"8":29679,"9":4947,"10":24732,"11":15442,"12":9290,"13":9290,"14":19493,"15":19493,"16":19493,"17":23178,"18":23178,"19":23178,"20":3975,"21":3965,"22":10,"23":10,"24":0,"25":0,"26":15588,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":15588,"40":15588,"41":15588,"42":60731,"43":15546,"44":42,"45":42,"46":1745,"47":5,"48":37,"49":37,"50":1242,"51":4,"52":33,"53":30454,"54":30454,"55":30454,"56":17996,"57":17996,"58":101,"59":17996,"60":1054,"61":17996,"62":2298,"63":17996,"64":256,"65":17996,"66":27,"67":17996,"68":2907,"69":17996,"70":15,"71":30454,"72":30454,"73":213178,"74":79746,"75":30454,"76":30454,"77":30454,"78":30454,"79":17996,"80":30454,"81":18788,"82":18788,"83":18788,"84":30454,"85":86586},"f":{"0":49242,"1":60731,"2":1745,"3":1242,"4":30454,"5":30454,"6":86586},"b":{"0":[49172,70],"1":[29679,19493],"2":[4947,24732],"3":[15442,9290],"4":[9290,0],"5":[3975,19203],"6":[3965,10],"7":[10,0],"8":[0,0],"9":[0,15588],"10":[15588,11092],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[15546,42],"17":[15588,15578,15578],"18":[5,37],"19":[42,42,42,42,42],"20":[4,33],"21":[37,37],"22":[30454],"23":[101,17895],"24":[1054,16942],"25":[17996,17459,16944,16944,16943,16943,16943,16942],"26":[2298,15698],"27":[17996,17170,16735,16620,16620,16489,16359,16359,16109,15944,15818],"28":[256,17740],"29":[17996,17906,17761,17746,17741,17741,17740,17740,17740,17740,17740,17740,17740,17740],"30":[27,17969],"31":[17996,17980,17970,17970,17970,17970,17970,17970,17970,17969,17969,17969,17969],"32":[2907,15089],"33":[17996,16471,16426,16266,16261,16131,15970,15810,15805,15650,15650,15520,15374,15224],"34":[15,17981],"35":[17996,17991,17981,17981,17981,17981,17981,17981,17981,17981,17981,17981],"36":[79746,133432],"37":[30454],"38":[18788,11666]},"meta":{"lastBranch":39,"lastFunction":7,"lastStatement":86,"seen":{"s:20:19:20:Infinity":0,"s:23:38:23:Infinity":1,"s:25:75:33:Infinity":2,"f:42:16:42:36":0,"s:43:20:43:Infinity":3,"b:44:2:62:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:62:Infinity":4,"s:45:17:45:Infinity":5,"s:46:18:46:Infinity":6,"b:47:4:51:Infinity:undefined:undefined:undefined:undefined":1,"s:47:4:51:Infinity":7,"b:48:6:48:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:48:Infinity":8,"s:48:52:48:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":3,"s:49:6:49:Infinity":10,"s:49:42:49:Infinity":11,"b:50:6:50:Infinity:undefined:undefined:undefined:undefined":4,"s:50:6:50:Infinity":12,"s:50:49:50:Infinity":13,"s:52:18:52:Infinity":14,"s:53:4:61:Infinity":15,"s:53:17:53:35":16,"s:54:21:54:Infinity":17,"s:55:26:55:Infinity":18,"b:56:6:60:Infinity:undefined:undefined:undefined:undefined":5,"s:56:6:60:Infinity":19,"b:57:8:57:Infinity:undefined:undefined:undefined:undefined":6,"s:57:8:57:Infinity":20,"s:57:60:57:Infinity":21,"b:58:8:58:Infinity:undefined:undefined:undefined:undefined":7,"s:58:8:58:Infinity":22,"s:58:50:58:Infinity":23,"b:59:8:59:Infinity:undefined:undefined:undefined:undefined":8,"s:59:8:59:Infinity":24,"s:59:57:59:Infinity":25,"b:64:2:76:Infinity:undefined:undefined:undefined:undefined":9,"s:64:2:76:Infinity":26,"b:64:6:64:22:64:22:64:50":10,"s:65:22:65:Infinity":27,"s:66:25:66:Infinity":28,"b:67:4:75:Infinity:undefined:undefined:undefined:undefined":11,"s:67:4:75:Infinity":29,"s:68:22:68:Infinity":30,"s:69:20:69:Infinity":31,"b:70:6:74:Infinity:undefined:undefined:undefined:undefined":12,"s:70:6:74:Infinity":32,"b:71:8:71:Infinity:undefined:undefined:undefined:undefined":13,"s:71:8:71:Infinity":33,"s:71:54:71:Infinity":34,"b:72:8:72:Infinity:undefined:undefined:undefined:undefined":14,"s:72:8:72:Infinity":35,"s:72:44:72:Infinity":36,"b:73:8:73:Infinity:undefined:undefined:undefined:undefined":15,"s:73:8:73:Infinity":37,"s:73:51:73:Infinity":38,"s:78:31:78:Infinity":39,"s:80:40:95:Infinity":40,"b:97:2:99:Infinity:undefined:undefined:undefined:undefined":16,"s:97:2:99:Infinity":41,"b:97:6:97:41:97:41:97:77:97:77:97:152":17,"f:97:97:97:103":1,"s:97:110:97:149":42,"s:98:4:98:Infinity":43,"s:101:37:116:Infinity":44,"b:118:2:122:Infinity:undefined:undefined:undefined:undefined":18,"s:118:2:122:Infinity":45,"b:118:6:118:48:118:48:118:85:118:85:118:Infinity:119:6:119:Infinity:120:6:120:78":19,"f:120:23:120:29":2,"s:120:36:120:75":46,"s:121:4:121:Infinity":47,"s:124:37:139:Infinity":48,"b:141:2:143:Infinity:undefined:undefined:undefined:undefined":20,"s:141:2:143:Infinity":49,"b:141:6:141:39:141:39:141:111":21,"f:141:56:141:62":3,"s:141:69:141:108":50,"s:142:4:142:Infinity":51,"s:145:2:145:Infinity":52,"f:152:16:152:30":4,"b:152:66:152:80":22,"s:153:27:153:Infinity":53,"s:154:21:154:Infinity":54,"s:157:2:166:Infinity":55,"s:158:24:158:Infinity":56,"b:159:4:159:Infinity:undefined:undefined:undefined:undefined":23,"s:159:4:159:Infinity":57,"s:159:28:159:Infinity":58,"b:160:4:160:Infinity:undefined:undefined:undefined:undefined":24,"s:160:4:160:Infinity":59,"b:160:8:160:38:160:38:160:65:160:65:160:96:160:96:160:118:160:118:160:140:160:140:160:162:160:162:160:190:160:190:160:214":25,"s:160:214:160:Infinity":60,"b:161:4:161:Infinity:undefined:undefined:undefined:undefined":26,"s:161:4:161:Infinity":61,"b:161:8:161:38:161:38:161:66:161:66:161:97:161:97:161:125:161:125:161:154:161:154:161:186:161:186:161:214:161:214:161:236:161:236:161:258:161:258:161:285:161:285:161:308":27,"s:161:308:161:Infinity":62,"b:162:4:162:Infinity:undefined:undefined:undefined:undefined":28,"s:162:4:162:Infinity":63,"b:162:8:162:35:162:35:162:62:162:62:162:89:162:89:162:116:162:116:162:145:162:145:162:177:162:177:162:204:162:204:162:231:162:231:162:259:162:259:162:285:162:285:162:309:162:309:162:331:162:331:162:353:162:353:162:373":29,"s:162:373:162:Infinity":64,"b:163:4:163:Infinity:undefined:undefined:undefined:undefined":30,"s:163:4:163:Infinity":65,"b:163:8:163:39:163:39:163:64:163:64:163:89:163:89:163:118:163:118:163:144:163:144:163:177:163:177:163:211:163:211:163:237:163:237:163:263:163:263:163:288:163:288:163:310:163:310:163:332:163:332:163:352":31,"s:163:352:163:Infinity":66,"b:164:4:164:Infinity:undefined:undefined:undefined:undefined":32,"s:164:4:164:Infinity":67,"b:164:8:164:37:164:37:164:64:164:64:164:90:164:90:164:116:164:116:164:145:164:145:164:174:164:174:164:204:164:204:164:230:164:230:164:259:164:259:164:283:164:283:164:307:164:307:164:330:164:330:164:353:164:353:164:374":33,"s:164:374:164:Infinity":68,"b:165:4:165:Infinity:undefined:undefined:undefined:undefined":34,"s:165:4:165:Infinity":69,"b:165:8:165:39:165:39:165:71:165:71:165:101:165:101:165:133:165:133:165:165:165:165:165:196:165:196:165:227:165:227:165:256:165:256:165:285:165:285:165:310:165:310:165:332:165:332:165:352":35,"s:165:352:165:Infinity":70,"s:168:23:168:Infinity":71,"s:169:2:171:Infinity":72,"b:170:4:170:Infinity:undefined:undefined:undefined:undefined":36,"s:170:4:170:Infinity":73,"s:170:36:170:Infinity":74,"s:173:2:173:Infinity":75,"f:179:16:179:28":5,"b:179:64:179:68":37,"s:180:25:180:Infinity":76,"s:181:21:181:Infinity":77,"s:184:2:186:Infinity":78,"s:185:4:185:Infinity":79,"b:188:2:192:Infinity:undefined:undefined:undefined:undefined":38,"s:188:2:192:Infinity":80,"s:189:4:189:Infinity":81,"s:190:25:190:Infinity":82,"s:191:4:191:Infinity":83,"s:194:2:194:Infinity":84,"f:194:26:194:34":6,"s:194:42:194:63":85}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-prelude.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-prelude.ts","statementMap":{"0":{"start":{"line":30,"column":26},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":21},"end":{"line":36,"column":null}},"2":{"start":{"line":38,"column":23},"end":{"line":38,"column":null}},"3":{"start":{"line":39,"column":26},"end":{"line":39,"column":null}},"4":{"start":{"line":41,"column":2},"end":{"line":61,"column":null}}},"fnMap":{"0":{"name":"buildPrelude","decl":{"start":{"line":29,"column":16},"end":{"line":29,"column":29}},"loc":{"start":{"line":29,"column":90},"end":{"line":62,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":37},"end":{"line":39,"column":89}},"type":"binary-expr","locations":[{"start":{"line":39,"column":37},"end":{"line":39,"column":75}},{"start":{"line":39,"column":75},"end":{"line":39,"column":89}}],"line":39}},"s":{"0":33,"1":33,"2":33,"3":33,"4":33},"f":{"0":33},"b":{"0":[33,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":5,"seen":{"f:29:16:29:29":0,"s:30:26:30:Infinity":0,"s:31:21:36:Infinity":1,"s:38:23:38:Infinity":2,"s:39:26:39:Infinity":3,"b:39:37:39:75:39:75:39:89":0,"s:41:2:61:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/filtering.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/filtering.ts","statementMap":{"0":{"start":{"line":12,"column":25},"end":{"line":12,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:12:25:12:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/helpers.ts","statementMap":{"0":{"start":{"line":13,"column":32},"end":{"line":13,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:13:32:13:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/index.ts","statementMap":{"0":{"start":{"line":24,"column":35},"end":{"line":24,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:24:35:24:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/rendering.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/rendering.ts","statementMap":{"0":{"start":{"line":12,"column":25},"end":{"line":12,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:12:25:12:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/search.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/search.ts","statementMap":{"0":{"start":{"line":14,"column":22},"end":{"line":14,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:14:22:14:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/sorting.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script-runtime/sorting.ts","statementMap":{"0":{"start":{"line":15,"column":23},"end":{"line":15,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":7},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:15:23:15:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/client-script.ts","statementMap":{"0":{"start":{"line":23,"column":18},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}}},"fnMap":{"0":{"name":"renderClientScript","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":35}},"loc":{"start":{"line":22,"column":69},"end":{"line":32,"column":null}},"line":22}},"branchMap":{},"s":{"0":33,"1":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":2,"seen":{"f:22:16:22:35":0,"s:23:18:28:Infinity":0,"s:29:2:31:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/constants.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/constants.ts","statementMap":{"0":{"start":{"line":10,"column":36},"end":{"line":10,"column":null}},"1":{"start":{"line":13,"column":24},"end":{"line":13,"column":null}},"2":{"start":{"line":17,"column":8},"end":{"line":17,"column":null}},"3":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}}},"fnMap":{"0":{"name":"appVersionMarker","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":43}},"loc":{"start":{"line":16,"column":43},"end":{"line":19,"column":null}},"line":16}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":19},"end":{"line":17,"column":74}},"type":"binary-expr","locations":[{"start":{"line":17,"column":19},"end":{"line":17,"column":54}},{"start":{"line":17,"column":54},"end":{"line":17,"column":74}}],"line":17}},"s":{"0":6,"1":6,"2":33,"3":33},"f":{"0":33},"b":{"0":[33,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":4,"seen":{"s:10:36:10:Infinity":0,"s:13:24:13:Infinity":1,"f:16:16:16:43":0,"s:17:8:17:Infinity":2,"b:17:19:17:54:17:54:17:74":0,"s:18:2:18:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/filters.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/filters.ts","statementMap":{"0":{"start":{"line":14,"column":26},"end":{"line":14,"column":null}},"1":{"start":{"line":15,"column":2},"end":{"line":64,"column":null}}},"fnMap":{"0":{"name":"renderFilterBar","decl":{"start":{"line":13,"column":16},"end":{"line":13,"column":32}},"loc":{"start":{"line":13,"column":89},"end":{"line":69,"column":null}},"line":13}},"branchMap":{},"s":{"0":33,"1":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":2,"seen":{"f:13:16:13:32":0,"s:14:26:14:Infinity":0,"s:15:2:64:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hero.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hero.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"renderHero","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"loc":{"start":{"line":20,"column":10},"end":{"line":40,"column":null}},"line":20}},"branchMap":{},"s":{"0":33},"f":{"0":33},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:15:16:15:Infinity":0,"s:21:2:36:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/hreflang.ts","statementMap":{"0":{"start":{"line":16,"column":25},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":2},"end":{"line":22,"column":null}},"2":{"start":{"line":19,"column":21},"end":{"line":19,"column":null}},"3":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"4":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"5":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"6":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}}},"fnMap":{"0":{"name":"generateHreflangTags","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":47}},"loc":{"start":{"line":15,"column":47},"end":{"line":27,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":21},"end":{"line":19,"column":null}},"type":"cond-expr","locations":[{"start":{"line":19,"column":40},"end":{"line":19,"column":55}},{"start":{"line":19,"column":55},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":19,"column":64},"end":{"line":19,"column":98}},"type":"cond-expr","locations":[{"start":{"line":19,"column":83},"end":{"line":19,"column":90}},{"start":{"line":19,"column":90},"end":{"line":19,"column":98}}],"line":19}},"s":{"0":4,"1":4,"2":56,"3":56,"4":56,"5":4,"6":4},"f":{"0":4},"b":{"0":[4,52],"1":[4,48]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":7,"seen":{"f:15:16:15:47":0,"s:16:25:16:Infinity":0,"s:18:2:22:Infinity":1,"s:19:21:19:Infinity":2,"b:19:40:19:55:19:55:19:Infinity":0,"b:19:83:19:90:19:90:19:98":1,"s:20:22:20:Infinity":3,"s:21:4:21:Infinity":4,"s:24:2:24:Infinity":5,"s:26:2:26:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/language-notice.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/language-notice.ts","statementMap":{"0":{"start":{"line":12,"column":73},"end":{"line":25,"column":null}},"1":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"3":{"start":{"line":34,"column":12},"end":{"line":34,"column":null}},"4":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"5":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}}},"fnMap":{"0":{"name":"generateLanguageNotice","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":39}},"loc":{"start":{"line":32,"column":64},"end":{"line":43,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"1":{"loc":{"start":{"line":40,"column":51},"end":{"line":40,"column":77}},"type":"cond-expr","locations":[{"start":{"line":40,"column":59},"end":{"line":40,"column":74}},{"start":{"line":40,"column":74},"end":{"line":40,"column":77}}],"line":40}},"s":{"0":6,"1":19,"2":19,"3":2,"4":17,"5":17},"f":{"0":19},"b":{"0":[2,17],"1":[4,13]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":6,"seen":{"s:12:73:25:Infinity":0,"f:32:16:32:39":0,"s:33:14:33:Infinity":1,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:2:34:Infinity":2,"s:34:12:34:Infinity":3,"s:36:16:36:Infinity":4,"s:38:2:40:Infinity":5,"b:40:59:40:74:40:74:40:77":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/i18n.ts","statementMap":{"0":{"start":{"line":16,"column":70},"end":{"line":31,"column":null}},"1":{"start":{"line":34,"column":120},"end":{"line":49,"column":null}},"2":{"start":{"line":52,"column":136},"end":{"line":67,"column":null}},"3":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"4":{"start":{"line":76,"column":14},"end":{"line":76,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":81,"column":null}},"6":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"7":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"8":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"9":{"start":{"line":96,"column":13},"end":{"line":96,"column":null}},"10":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}}},"fnMap":{"0":{"name":"localizeClearFilters","decl":{"start":{"line":70,"column":16},"end":{"line":70,"column":37}},"loc":{"start":{"line":70,"column":62},"end":{"line":72,"column":null}},"line":70},"1":{"name":"buildRecencyLabels","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":35}},"loc":{"start":{"line":75,"column":76},"end":{"line":82,"column":null}},"line":75},"2":{"name":"heroMetricLabels","decl":{"start":{"line":85,"column":16},"end":{"line":85,"column":33}},"loc":{"start":{"line":85,"column":126},"end":{"line":87,"column":null}},"line":85},"3":{"name":"toChromeLang","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":29}},"loc":{"start":{"line":90,"column":56},"end":{"line":92,"column":null}},"line":90},"4":{"name":"toBcp47","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":24}},"loc":{"start":{"line":95,"column":76},"end":{"line":98,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":71,"column":9},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":9},"end":{"line":71,"column":42}},{"start":{"line":71,"column":42},"end":{"line":71,"column":null}}],"line":71},"1":{"loc":{"start":{"line":76,"column":14},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":14},"end":{"line":76,"column":41}},{"start":{"line":76,"column":41},"end":{"line":76,"column":null}}],"line":76},"2":{"loc":{"start":{"line":86,"column":9},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":9},"end":{"line":86,"column":40}},{"start":{"line":86,"column":40},"end":{"line":86,"column":null}}],"line":86},"3":{"loc":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"4":{"loc":{"start":{"line":97,"column":9},"end":{"line":97,"column":null}},"type":"cond-expr","locations":[{"start":{"line":97,"column":25},"end":{"line":97,"column":32}},{"start":{"line":97,"column":32},"end":{"line":97,"column":null}}],"line":97}},"s":{"0":7,"1":7,"2":7,"3":34,"4":34,"5":34,"6":34,"7":495,"8":369,"9":2,"10":367},"f":{"0":34,"1":34,"2":34,"3":495,"4":369},"b":{"0":[34,1],"1":[34,1],"2":[34,1],"3":[2,367],"4":[21,346]},"meta":{"lastBranch":5,"lastFunction":5,"lastStatement":11,"seen":{"s:16:70:31:Infinity":0,"s:34:120:49:Infinity":1,"s:52:136:67:Infinity":2,"f:70:16:70:37":0,"s:71:2:71:Infinity":3,"b:71:9:71:42:71:42:71:Infinity":0,"f:75:16:75:35":1,"s:76:14:76:Infinity":4,"b:76:14:76:41:76:41:76:Infinity":1,"s:77:2:81:Infinity":5,"f:85:16:85:33":2,"s:86:2:86:Infinity":6,"b:86:9:86:40:86:40:86:Infinity":2,"f:90:16:90:29":3,"s:91:2:91:Infinity":7,"f:95:16:95:24":4,"b:96:2:96:Infinity:undefined:undefined:undefined:undefined":3,"s:96:2:96:Infinity":8,"s:96:13:96:Infinity":9,"s:97:2:97:Infinity":10,"b:97:25:97:32:97:32:97:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/index.ts","statementMap":{"0":{"start":{"line":33,"column":39},"end":{"line":33,"column":null}},"1":{"start":{"line":34,"column":22},"end":{"line":34,"column":null}},"2":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"3":{"start":{"line":38,"column":24},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"5":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":43},"end":{"line":44,"column":null}},"7":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":60,"column":null}},"9":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"10":{"start":{"line":65,"column":29},"end":{"line":65,"column":null}},"11":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"12":{"start":{"line":66,"column":29},"end":{"line":66,"column":35}},"13":{"start":{"line":66,"column":52},"end":{"line":66,"column":70}},"14":{"start":{"line":71,"column":49},"end":{"line":71,"column":null}},"15":{"start":{"line":72,"column":2},"end":{"line":74,"column":null}},"16":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"17":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"18":{"start":{"line":81,"column":19},"end":{"line":81,"column":null}},"19":{"start":{"line":96,"column":32},"end":{"line":96,"column":null}},"20":{"start":{"line":97,"column":19},"end":{"line":97,"column":null}},"21":{"start":{"line":98,"column":16},"end":{"line":98,"column":null}},"22":{"start":{"line":99,"column":30},"end":{"line":99,"column":null}},"23":{"start":{"line":101,"column":26},"end":{"line":101,"column":null}},"24":{"start":{"line":102,"column":22},"end":{"line":102,"column":null}},"25":{"start":{"line":103,"column":21},"end":{"line":103,"column":null}},"26":{"start":{"line":104,"column":23},"end":{"line":104,"column":null}},"27":{"start":{"line":106,"column":21},"end":{"line":106,"column":null}},"28":{"start":{"line":107,"column":19},"end":{"line":107,"column":null}},"29":{"start":{"line":108,"column":17},"end":{"line":108,"column":null}},"30":{"start":{"line":110,"column":17},"end":{"line":131,"column":null}},"31":{"start":{"line":133,"column":15},"end":{"line":133,"column":null}},"32":{"start":{"line":134,"column":18},"end":{"line":134,"column":null}},"33":{"start":{"line":135,"column":15},"end":{"line":135,"column":null}},"34":{"start":{"line":136,"column":17},"end":{"line":136,"column":null}},"35":{"start":{"line":137,"column":22},"end":{"line":137,"column":null}},"36":{"start":{"line":138,"column":21},"end":{"line":138,"column":null}},"37":{"start":{"line":139,"column":14},"end":{"line":139,"column":null}},"38":{"start":{"line":144,"column":15},"end":{"line":164,"column":null}},"39":{"start":{"line":166,"column":2},"end":{"line":169,"column":null}}},"fnMap":{"0":{"name":"indexFilename","decl":{"start":{"line":37,"column":9},"end":{"line":37,"column":23}},"loc":{"start":{"line":37,"column":48},"end":{"line":40,"column":null}},"line":37},"1":{"name":"buildExcerpt","decl":{"start":{"line":43,"column":9},"end":{"line":43,"column":22}},"loc":{"start":{"line":43,"column":51},"end":{"line":46,"column":null}},"line":43},"2":{"name":"toDisplayData","decl":{"start":{"line":49,"column":9},"end":{"line":49,"column":23}},"loc":{"start":{"line":49,"column":67},"end":{"line":61,"column":null}},"line":49},"3":{"name":"pickLatestDate","decl":{"start":{"line":64,"column":9},"end":{"line":64,"column":24}},"loc":{"start":{"line":64,"column":74},"end":{"line":67,"column":null}},"line":64},"4":{"name":"(anonymous_4)","decl":{"start":{"line":66,"column":18},"end":{"line":66,"column":23}},"loc":{"start":{"line":66,"column":29},"end":{"line":66,"column":35}},"line":66},"5":{"name":"(anonymous_5)","decl":{"start":{"line":66,"column":37},"end":{"line":66,"column":43}},"loc":{"start":{"line":66,"column":52},"end":{"line":66,"column":70}},"line":66},"6":{"name":"buildHreflangAlternates","decl":{"start":{"line":70,"column":9},"end":{"line":70,"column":70}},"loc":{"start":{"line":70,"column":70},"end":{"line":76,"column":null}},"line":70},"7":{"name":"generateIndexHTML","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"loc":{"start":{"line":95,"column":10},"end":{"line":170,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},{"start":{},"end":{}}],"line":38},"1":{"loc":{"start":{"line":39,"column":18},"end":{"line":39,"column":52}},"type":"cond-expr","locations":[{"start":{"line":39,"column":37},"end":{"line":39,"column":44}},{"start":{"line":39,"column":44},"end":{"line":39,"column":52}}],"line":39},"2":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"3":{"loc":{"start":{"line":56,"column":24},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":24},"end":{"line":56,"column":48}},{"start":{"line":56,"column":48},"end":{"line":56,"column":null}}],"line":56},"4":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"5":{"loc":{"start":{"line":119,"column":13},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":32},"end":{"line":119,"column":45}},{"start":{"line":119,"column":45},"end":{"line":119,"column":null}}],"line":119},"6":{"loc":{"start":{"line":121,"column":50},"end":{"line":121,"column":110}},"type":"cond-expr","locations":[{"start":{"line":121,"column":69},"end":{"line":121,"column":84}},{"start":{"line":121,"column":84},"end":{"line":121,"column":110}}],"line":121},"7":{"loc":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":145,"column":24},"end":{"line":145,"column":58}},{"start":{"line":145,"column":58},"end":{"line":145,"column":null}}],"line":145}},"s":{"0":6,"1":6,"2":495,"3":39,"4":456,"5":12245,"6":11953,"7":292,"8":12245,"9":33,"10":0,"11":33,"12":12245,"13":12212,"14":33,"15":33,"16":462,"17":33,"18":6,"19":33,"20":33,"21":33,"22":33,"23":33,"24":33,"25":33,"26":33,"27":33,"28":33,"29":33,"30":33,"31":33,"32":33,"33":33,"34":33,"35":33,"36":33,"37":33,"38":33,"39":33},"f":{"0":495,"1":12245,"2":12245,"3":33,"4":12245,"5":12212,"6":33,"7":33},"b":{"0":[39,456],"1":[35,421],"2":[11953,292],"3":[12245,75],"4":[0,33],"5":[6,27],"6":[6,27],"7":[0,33]},"meta":{"lastBranch":8,"lastFunction":8,"lastStatement":40,"seen":{"s:33:39:33:Infinity":0,"s:34:22:34:Infinity":1,"f:37:9:37:23":0,"b:38:2:38:Infinity:undefined:undefined:undefined:undefined":0,"s:38:2:38:Infinity":2,"s:38:24:38:Infinity":3,"s:39:2:39:Infinity":4,"b:39:37:39:44:39:44:39:52":1,"f:43:9:43:22":1,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":2,"s:44:2:44:Infinity":5,"s:44:43:44:Infinity":6,"s:45:2:45:Infinity":7,"f:49:9:49:23":2,"s:50:2:60:Infinity":8,"b:56:24:56:48:56:48:56:Infinity":3,"f:64:9:64:24":3,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":4,"s:65:2:65:Infinity":9,"s:65:29:65:Infinity":10,"s:66:2:66:Infinity":11,"f:66:18:66:23":4,"s:66:29:66:35":12,"f:66:37:66:43":5,"s:66:52:66:70":13,"f:70:9:70:70":6,"s:71:49:71:Infinity":14,"s:72:2:74:Infinity":15,"s:73:4:73:Infinity":16,"s:75:2:75:Infinity":17,"s:81:19:81:Infinity":18,"f:91:16:91:Infinity":7,"s:96:32:96:Infinity":19,"s:97:19:97:Infinity":20,"s:98:16:98:Infinity":21,"s:99:30:99:Infinity":22,"s:101:26:101:Infinity":23,"s:102:22:102:Infinity":24,"s:103:21:103:Infinity":25,"s:104:23:104:Infinity":26,"s:106:21:106:Infinity":27,"s:107:19:107:Infinity":28,"s:108:17:108:Infinity":29,"s:110:17:131:Infinity":30,"b:119:32:119:45:119:45:119:Infinity":5,"b:121:69:121:84:121:84:121:110":6,"s:133:15:133:Infinity":31,"s:134:18:134:Infinity":32,"s:135:15:135:Infinity":33,"s:136:17:136:Infinity":34,"s:137:22:137:Infinity":35,"s:138:21:138:Infinity":36,"s:139:14:139:Infinity":37,"s:144:15:164:Infinity":38,"b:145:24:145:58:145:58:145:Infinity":7,"s:166:2:169:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/page-sections.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/page-sections.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":31,"column":16},"end":{"line":34,"column":null}},"2":{"start":{"line":31,"column":36},"end":{"line":34,"column":18}},"3":{"start":{"line":35,"column":2},"end":{"line":38,"column":null}}},"fnMap":{"0":{"name":"renderAiNewsroomSection","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":40}},"loc":{"start":{"line":20,"column":70},"end":{"line":27,"column":null}},"line":20},"1":{"name":"renderFaqSection","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":33}},"loc":{"start":{"line":30,"column":93},"end":{"line":41,"column":null}},"line":30},"2":{"name":"(anonymous_2)","decl":{"start":{"line":31,"column":25},"end":{"line":31,"column":30}},"loc":{"start":{"line":31,"column":36},"end":{"line":34,"column":18}},"line":31}},"branchMap":{},"s":{"0":33,"1":33,"2":165,"3":33},"f":{"0":33,"1":33,"2":165},"b":{},"meta":{"lastBranch":0,"lastFunction":3,"lastStatement":4,"seen":{"f:20:16:20:40":0,"s:21:2:24:Infinity":0,"f:30:16:30:33":1,"s:31:16:34:Infinity":1,"f:31:25:31:30":2,"s:31:36:34:18":2,"s:35:2:38:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/rtl.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/rtl.ts","statementMap":{"0":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"1":{"start":{"line":13,"column":14},"end":{"line":13,"column":null}},"2":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":47,"column":null}}},"fnMap":{"0":{"name":"generateRTLStyles","decl":{"start":{"line":12,"column":16},"end":{"line":12,"column":34}},"loc":{"start":{"line":12,"column":70},"end":{"line":32,"column":null}},"line":12},"1":{"name":"newsPageExtraRtlStyle","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":38}},"loc":{"start":{"line":39,"column":62},"end":{"line":48,"column":null}},"line":39}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"type":"if","locations":[{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},{"start":{},"end":{}}],"line":13},"1":{"loc":{"start":{"line":40,"column":9},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":17},"end":{"line":47,"column":null}},{"start":{"line":47,"column":4},"end":{"line":47,"column":null}}],"line":40}},"s":{"0":4,"1":2,"2":2,"3":33},"f":{"0":4,"1":33},"b":{"0":[2,2],"1":[4,29]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":4,"seen":{"f:12:16:12:34":0,"b:13:2:13:Infinity:undefined:undefined:undefined:undefined":0,"s:13:2:13:Infinity":0,"s:13:14:13:Infinity":1,"s:15:2:15:Infinity":2,"f:39:16:39:38":1,"s:40:2:47:Infinity":3,"b:40:17:47:Infinity:47:4:47:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/seo-fallback.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/seo-fallback.ts","statementMap":{"0":{"start":{"line":20,"column":27},"end":{"line":20,"column":null}},"1":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":16},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":16},"end":{"line":31,"column":161}},"4":{"start":{"line":33,"column":19},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}}},"fnMap":{"0":{"name":"renderSeoFallback","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":null}},"loc":{"start":{"line":27,"column":10},"end":{"line":42,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":31,"column":5},"end":{"line":31,"column":10}},"loc":{"start":{"line":31,"column":16},"end":{"line":31,"column":161}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":19},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},{"start":{"line":35,"column":6},"end":{"line":35,"column":null}}],"line":33},"1":{"loc":{"start":{"line":34,"column":36},"end":{"line":34,"column":74}},"type":"cond-expr","locations":[{"start":{"line":34,"column":55},"end":{"line":34,"column":60}},{"start":{"line":34,"column":60},"end":{"line":34,"column":74}}],"line":34}},"s":{"0":6,"1":33,"2":33,"3":5675,"4":33,"5":33},"f":{"0":33,"1":5675},"b":{"0":[28,5],"1":[2,26]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":6,"seen":{"s:20:27:20:Infinity":0,"f:23:16:23:Infinity":0,"s:28:22:28:Infinity":1,"s:29:16:32:Infinity":2,"f:31:5:31:10":1,"s:31:16:31:161":3,"s:33:19:35:Infinity":4,"b:34:6:34:Infinity:35:6:35:Infinity":0,"b:34:55:34:60:34:60:34:74":1,"s:36:2:40:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/horizon-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/horizon-context.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":18},"end":{"line":39,"column":null}},"2":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"3":{"start":{"line":100,"column":42},"end":{"line":100,"column":null}},"4":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"5":{"start":{"line":106,"column":14},"end":{"line":106,"column":null}},"6":{"start":{"line":107,"column":15},"end":{"line":107,"column":null}},"7":{"start":{"line":108,"column":14},"end":{"line":108,"column":null}},"8":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"9":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"10":{"start":{"line":117,"column":14},"end":{"line":117,"column":null}},"11":{"start":{"line":118,"column":16},"end":{"line":118,"column":null}},"12":{"start":{"line":118,"column":38},"end":{"line":118,"column":49}},"13":{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},"14":{"start":{"line":120,"column":4},"end":{"line":122,"column":null}},"15":{"start":{"line":121,"column":67},"end":{"line":121,"column":71}},"16":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"17":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"18":{"start":{"line":133,"column":15},"end":{"line":133,"column":null}},"19":{"start":{"line":134,"column":16},"end":{"line":134,"column":null}},"20":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"21":{"start":{"line":143,"column":14},"end":{"line":143,"column":null}},"22":{"start":{"line":144,"column":15},"end":{"line":144,"column":null}},"23":{"start":{"line":145,"column":20},"end":{"line":145,"column":null}},"24":{"start":{"line":146,"column":18},"end":{"line":146,"column":null}},"25":{"start":{"line":147,"column":2},"end":{"line":147,"column":null}},"26":{"start":{"line":160,"column":12},"end":{"line":160,"column":null}},"27":{"start":{"line":161,"column":15},"end":{"line":161,"column":null}},"28":{"start":{"line":162,"column":16},"end":{"line":162,"column":null}},"29":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"30":{"start":{"line":163,"column":19},"end":{"line":163,"column":null}},"31":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"32":{"start":{"line":164,"column":18},"end":{"line":164,"column":null}},"33":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"34":{"start":{"line":176,"column":12},"end":{"line":176,"column":null}},"35":{"start":{"line":177,"column":12},"end":{"line":177,"column":null}},"36":{"start":{"line":178,"column":14},"end":{"line":178,"column":null}},"37":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"38":{"start":{"line":179,"column":65},"end":{"line":179,"column":null}},"39":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"40":{"start":{"line":180,"column":42},"end":{"line":180,"column":null}},"41":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"42":{"start":{"line":181,"column":73},"end":{"line":181,"column":null}},"43":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"44":{"start":{"line":199,"column":22},"end":{"line":199,"column":null}},"45":{"start":{"line":200,"column":14},"end":{"line":200,"column":null}},"46":{"start":{"line":201,"column":2},"end":{"line":208,"column":null}},"47":{"start":{"line":215,"column":37},"end":{"line":223,"column":null}},"48":{"start":{"line":236,"column":13},"end":{"line":236,"column":null}},"49":{"start":{"line":237,"column":6},"end":{"line":243,"column":null}},"50":{"start":{"line":238,"column":2},"end":{"line":242,"column":null}},"51":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"52":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"53":{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},"54":{"start":{"line":245,"column":32},"end":{"line":245,"column":null}},"55":{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},"56":{"start":{"line":247,"column":4},"end":{"line":247,"column":null}},"57":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"58":{"start":{"line":250,"column":14},"end":{"line":250,"column":null}},"59":{"start":{"line":251,"column":2},"end":{"line":251,"column":null}}},"fnMap":{"0":{"name":"loadRegistry","decl":{"start":{"line":105,"column":16},"end":{"line":105,"column":53}},"loc":{"start":{"line":105,"column":53},"end":{"line":111,"column":null}},"line":105},"1":{"name":"getArticleType","decl":{"start":{"line":116,"column":16},"end":{"line":116,"column":31}},"loc":{"start":{"line":116,"column":61},"end":{"line":125,"column":null}},"line":116},"2":{"name":"(anonymous_2)","decl":{"start":{"line":118,"column":26},"end":{"line":118,"column":32}},"loc":{"start":{"line":118,"column":38},"end":{"line":118,"column":49}},"line":118},"3":{"name":"(anonymous_3)","decl":{"start":{"line":121,"column":56},"end":{"line":121,"column":61}},"loc":{"start":{"line":121,"column":67},"end":{"line":121,"column":71}},"line":121},"4":{"name":"daysToElection","decl":{"start":{"line":131,"column":16},"end":{"line":131,"column":31}},"loc":{"start":{"line":131,"column":60},"end":{"line":136,"column":null}},"line":131},"5":{"name":"activeCycleAnchor","decl":{"start":{"line":142,"column":16},"end":{"line":142,"column":34}},"loc":{"start":{"line":142,"column":75},"end":{"line":148,"column":null}},"line":142},"6":{"name":"weoVintage","decl":{"start":{"line":159,"column":16},"end":{"line":159,"column":27}},"loc":{"start":{"line":159,"column":56},"end":{"line":166,"column":null}},"line":159},"7":{"name":"sessionPhase","decl":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"loc":{"start":{"line":175,"column":57},"end":{"line":183,"column":null}},"line":175},"8":{"name":"horizonContext","decl":{"start":{"line":198,"column":16},"end":{"line":198,"column":31}},"loc":{"start":{"line":198,"column":84},"end":{"line":209,"column":null}},"line":198},"9":{"name":"(anonymous_9)","decl":{"start":{"line":237,"column":6},"end":{"line":237,"column":22}},"loc":{"start":{"line":237,"column":22},"end":{"line":243,"column":1}},"line":237}},"branchMap":{"0":{"loc":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":106},"1":{"loc":{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":2},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":119},"2":{"loc":{"start":{"line":147,"column":9},"end":{"line":147,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":47},"end":{"line":147,"column":56}},{"start":{"line":147,"column":56},"end":{"line":147,"column":null}}],"line":147},"3":{"loc":{"start":{"line":147,"column":9},"end":{"line":147,"column":47}},"type":"binary-expr","locations":[{"start":{"line":147,"column":9},"end":{"line":147,"column":30}},{"start":{"line":147,"column":30},"end":{"line":147,"column":47}}],"line":147},"4":{"loc":{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":2},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"5":{"loc":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":164},"6":{"loc":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":179},"7":{"loc":{"start":{"line":179,"column":6},"end":{"line":179,"column":65}},"type":"binary-expr","locations":[{"start":{"line":179,"column":6},"end":{"line":179,"column":17}},{"start":{"line":179,"column":17},"end":{"line":179,"column":29}},{"start":{"line":179,"column":29},"end":{"line":179,"column":42}},{"start":{"line":179,"column":42},"end":{"line":179,"column":54}},{"start":{"line":179,"column":54},"end":{"line":179,"column":65}}],"line":179},"8":{"loc":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},{"start":{},"end":{}}],"line":180},"9":{"loc":{"start":{"line":180,"column":7},"end":{"line":180,"column":42}},"type":"binary-expr","locations":[{"start":{"line":180,"column":7},"end":{"line":180,"column":19}},{"start":{"line":180,"column":19},"end":{"line":180,"column":33}},{"start":{"line":180,"column":33},"end":{"line":180,"column":42}}],"line":180},"10":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"11":{"loc":{"start":{"line":181,"column":6},"end":{"line":181,"column":73}},"type":"binary-expr","locations":[{"start":{"line":181,"column":6},"end":{"line":181,"column":17}},{"start":{"line":181,"column":17},"end":{"line":181,"column":28}},{"start":{"line":181,"column":28},"end":{"line":181,"column":39}},{"start":{"line":181,"column":39},"end":{"line":181,"column":51}},{"start":{"line":181,"column":51},"end":{"line":181,"column":62}},{"start":{"line":181,"column":62},"end":{"line":181,"column":73}}],"line":181},"12":{"loc":{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},"type":"if","locations":[{"start":{"line":244,"column":0},"end":{"line":252,"column":null}},{"start":{},"end":{}}],"line":244},"13":{"loc":{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},"type":"if","locations":[{"start":{"line":246,"column":2},"end":{"line":249,"column":null}},{"start":{},"end":{}}],"line":246},"14":{"loc":{"start":{"line":246,"column":6},"end":{"line":246,"column":31}},"type":"binary-expr","locations":[{"start":{"line":246,"column":6},"end":{"line":246,"column":17}},{"start":{"line":246,"column":17},"end":{"line":246,"column":31}}],"line":246}},"s":{"0":1,"1":1,"2":1,"3":1,"4":21,"5":20,"6":1,"7":1,"8":1,"9":1,"10":6,"11":6,"12":63,"13":6,"14":1,"15":13,"16":5,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"23":6,"24":6,"25":6,"26":10,"27":10,"28":10,"29":10,"30":2,"31":8,"32":8,"33":2,"34":12,"35":12,"36":12,"37":12,"38":3,"39":9,"40":2,"41":7,"42":3,"43":4,"44":3,"45":3,"46":3,"47":1,"48":1,"49":1,"50":1,"51":1,"52":0,"53":1,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0},"f":{"0":21,"1":6,"2":63,"3":13,"4":6,"5":6,"6":10,"7":12,"8":3,"9":1},"b":{"0":[20,1],"1":[1,5],"2":[2,4],"3":[6,2],"4":[2,8],"5":[6,2],"6":[3,9],"7":[12,11,11,10,2],"8":[2,7],"9":[9,1,8],"10":[3,4],"11":[7,7,6,6,4,0],"12":[0,1],"13":[0,0],"14":[0,0]},"meta":{"lastBranch":15,"lastFunction":10,"lastStatement":60,"seen":{"s:38:19:38:Infinity":0,"s:39:18:39:Infinity":1,"s:40:17:40:Infinity":2,"s:100:42:100:Infinity":3,"f:105:16:105:53":0,"b:106:2:106:Infinity:undefined:undefined:undefined:undefined":0,"s:106:2:106:Infinity":4,"s:106:14:106:Infinity":5,"s:107:15:107:Infinity":6,"s:108:14:108:Infinity":7,"s:109:2:109:Infinity":8,"s:110:2:110:Infinity":9,"f:116:16:116:31":1,"s:117:14:117:Infinity":10,"s:118:16:118:Infinity":11,"f:118:26:118:32":2,"s:118:38:118:49":12,"b:119:2:123:Infinity:undefined:undefined:undefined:undefined":1,"s:119:2:123:Infinity":13,"s:120:4:122:Infinity":14,"f:121:56:121:61":3,"s:121:67:121:71":15,"s:124:2:124:Infinity":16,"f:131:16:131:31":4,"s:132:14:132:Infinity":17,"s:133:15:133:Infinity":18,"s:134:16:134:Infinity":19,"s:135:2:135:Infinity":20,"f:142:16:142:34":5,"s:143:14:143:Infinity":21,"s:144:15:144:Infinity":22,"s:145:20:145:Infinity":23,"s:146:18:146:Infinity":24,"s:147:2:147:Infinity":25,"b:147:47:147:56:147:56:147:Infinity":2,"b:147:9:147:30:147:30:147:47":3,"f:159:16:159:27":6,"s:160:12:160:Infinity":26,"s:161:15:161:Infinity":27,"s:162:16:162:Infinity":28,"b:163:2:163:Infinity:undefined:undefined:undefined:undefined":4,"s:163:2:163:Infinity":29,"s:163:19:163:Infinity":30,"b:164:2:164:Infinity:undefined:undefined:undefined:undefined":5,"s:164:2:164:Infinity":31,"s:164:18:164:Infinity":32,"s:165:2:165:Infinity":33,"f:173:16:173:Infinity":7,"s:176:12:176:Infinity":34,"s:177:12:177:Infinity":35,"s:178:14:178:Infinity":36,"b:179:2:179:Infinity:undefined:undefined:undefined:undefined":6,"s:179:2:179:Infinity":37,"b:179:6:179:17:179:17:179:29:179:29:179:42:179:42:179:54:179:54:179:65":7,"s:179:65:179:Infinity":38,"b:180:2:180:Infinity:undefined:undefined:undefined:undefined":8,"s:180:2:180:Infinity":39,"b:180:7:180:19:180:19:180:33:180:33:180:42":9,"s:180:42:180:Infinity":40,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":10,"s:181:2:181:Infinity":41,"b:181:6:181:17:181:17:181:28:181:28:181:39:181:39:181:51:181:51:181:62:181:62:181:73":11,"s:181:73:181:Infinity":42,"s:182:2:182:Infinity":43,"f:198:16:198:31":8,"s:199:22:199:Infinity":44,"s:200:14:200:Infinity":45,"s:201:2:208:Infinity":46,"s:215:37:223:Infinity":47,"s:236:13:236:Infinity":48,"s:237:6:243:Infinity":49,"f:237:6:237:22":9,"s:238:2:242:Infinity":50,"s:239:4:239:Infinity":51,"s:241:4:241:Infinity":52,"b:244:0:252:Infinity:undefined:undefined:undefined:undefined":12,"s:244:0:252:Infinity":53,"s:245:32:245:Infinity":54,"b:246:2:249:Infinity:undefined:undefined:undefined:undefined":13,"s:246:2:249:Infinity":55,"b:246:6:246:17:246:17:246:31":14,"s:247:4:247:Infinity":56,"s:248:4:248:Infinity":57,"s:250:14:250:Infinity":58,"s:251:2:251:Infinity":59}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/schema-ld.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/generate-news-indexes/template/schema-ld.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":60,"column":null}},"1":{"start":{"line":24,"column":75},"end":{"line":59,"column":6}},"2":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}},"3":{"start":{"line":77,"column":2},"end":{"line":83,"column":null}},"4":{"start":{"line":88,"column":2},"end":{"line":106,"column":null}},"5":{"start":{"line":115,"column":2},"end":{"line":120,"column":null}}},"fnMap":{"0":{"name":"buildItemListLd","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":null}},"loc":{"start":{"line":17,"column":11},"end":{"line":61,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":24,"column":50},"end":{"line":24,"column":55}},"loc":{"start":{"line":24,"column":75},"end":{"line":59,"column":6}},"line":24},"2":{"name":"buildBreadcrumbLd","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":34}},"loc":{"start":{"line":64,"column":83},"end":{"line":73,"column":null}},"line":64},"3":{"name":"buildOrganizationLd","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":47}},"loc":{"start":{"line":76,"column":47},"end":{"line":84,"column":null}},"line":76},"4":{"name":"buildWebsiteLd","decl":{"start":{"line":87,"column":16},"end":{"line":87,"column":31}},"loc":{"start":{"line":87,"column":80},"end":{"line":107,"column":null}},"line":87},"5":{"name":"buildAllJsonLd","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"loc":{"start":{"line":114,"column":13},"end":{"line":121,"column":null}},"line":114}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":21},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":12},"end":{"line":36,"column":null}},{"start":{"line":37,"column":12},"end":{"line":37,"column":null}}],"line":35},"1":{"loc":{"start":{"line":38,"column":28},"end":{"line":38,"column":55}},"type":"binary-expr","locations":[{"start":{"line":38,"column":28},"end":{"line":38,"column":44}},{"start":{"line":38,"column":44},"end":{"line":38,"column":55}}],"line":38},"2":{"loc":{"start":{"line":51,"column":12},"end":{"line":51,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":31},"end":{"line":51,"column":64}},{"start":{"line":51,"column":64},"end":{"line":51,"column":null}}],"line":51},"3":{"loc":{"start":{"line":94,"column":17},"end":{"line":94,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":17},"end":{"line":94,"column":43}},{"start":{"line":94,"column":43},"end":{"line":94,"column":null}}],"line":94}},"s":{"0":33,"1":330,"2":33,"3":33,"4":33,"5":33},"f":{"0":33,"1":330,"2":33,"3":33,"4":33,"5":33},"b":{"0":[192,138],"1":[330,0],"2":[280,50],"3":[33,0]},"meta":{"lastBranch":4,"lastFunction":6,"lastStatement":6,"seen":{"f:14:16:14:Infinity":0,"s:18:2:60:Infinity":0,"f:24:50:24:55":1,"s:24:75:59:6":1,"b:36:12:36:Infinity:37:12:37:Infinity":0,"b:38:28:38:44:38:44:38:55":1,"b:51:31:51:64:51:64:51:Infinity":2,"f:64:16:64:34":2,"s:65:2:72:Infinity":2,"f:76:16:76:47":3,"s:77:2:83:Infinity":3,"f:87:16:87:31":4,"s:88:2:106:Infinity":4,"b:94:17:94:43:94:43:94:Infinity":3,"f:110:16:110:Infinity":5,"s:115:2:120:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/html-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/html-utils.ts","statementMap":{"0":{"start":{"line":10,"column":58},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":28},"end":{"line":18,"column":null}},"2":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":28,"column":13},"end":{"line":28,"column":null}},"4":{"start":{"line":29,"column":2},"end":{"line":32,"column":null}},"5":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"6":{"start":{"line":36,"column":59},"end":{"line":50,"column":null}},"7":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"8":{"start":{"line":63,"column":13},"end":{"line":63,"column":null}},"9":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"10":{"start":{"line":67,"column":2},"end":{"line":74,"column":null}},"11":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"12":{"start":{"line":69,"column":4},"end":{"line":73,"column":null}},"13":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"14":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"15":{"start":{"line":76,"column":2},"end":{"line":83,"column":null}},"16":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"17":{"start":{"line":78,"column":4},"end":{"line":82,"column":null}},"18":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"19":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"20":{"start":{"line":85,"column":2},"end":{"line":88,"column":null}},"21":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"22":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}}},"fnMap":{"0":{"name":"escapeHtml","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":27}},"loc":{"start":{"line":27,"column":77},"end":{"line":33,"column":null}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"loc":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"line":31},"2":{"name":"decodeHtmlEntities","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":35}},"loc":{"start":{"line":62,"column":76},"end":{"line":91,"column":null}},"line":62},"3":{"name":"(anonymous_3)","decl":{"start":{"line":67,"column":26},"end":{"line":67,"column":40}},"loc":{"start":{"line":67,"column":81},"end":{"line":74,"column":3}},"line":67},"4":{"name":"(anonymous_4)","decl":{"start":{"line":76,"column":26},"end":{"line":76,"column":50}},"loc":{"start":{"line":76,"column":90},"end":{"line":83,"column":3}},"line":76},"5":{"name":"(anonymous_5)","decl":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"loc":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"line":87}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":31,"column":27},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":27},"end":{"line":31,"column":49}},{"start":{"line":31,"column":49},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"3":{"loc":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"type":"binary-expr","locations":[{"start":{"line":87,"column":27},"end":{"line":87,"column":50}},{"start":{"line":87,"column":50},"end":{"line":87,"column":null}}],"line":87}},"s":{"0":66,"1":66,"2":24741,"3":3,"4":24738,"5":826,"6":66,"7":121864,"8":17,"9":121847,"10":121847,"11":5887,"12":5887,"13":5887,"14":0,"15":121847,"16":7,"17":7,"18":7,"19":0,"20":121847,"21":1925,"22":121847},"f":{"0":24741,"1":826,"2":121864,"3":5887,"4":7,"5":1925},"b":{"0":[3,24738],"1":[826,0],"2":[17,121847],"3":[1925,0]},"meta":{"lastBranch":4,"lastFunction":6,"lastStatement":23,"seen":{"s:10:58:16:Infinity":0,"s:18:28:18:Infinity":1,"f:27:16:27:27":0,"b:28:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:28:Infinity":2,"s:28:13:28:Infinity":3,"s:29:2:32:Infinity":4,"f:30:4:30:Infinity":1,"s:31:27:31:Infinity":5,"b:31:27:31:49:31:49:31:Infinity":1,"s:36:59:50:Infinity":6,"f:62:16:62:35":2,"b:63:2:63:Infinity:undefined:undefined:undefined:undefined":2,"s:63:2:63:Infinity":7,"s:63:13:63:Infinity":8,"s:65:15:65:Infinity":9,"s:67:2:74:Infinity":10,"f:67:26:67:40":3,"s:68:22:68:Infinity":11,"s:69:4:73:Infinity":12,"s:70:6:70:Infinity":13,"s:72:6:72:Infinity":14,"s:76:2:83:Infinity":15,"f:76:26:76:50":4,"s:77:22:77:Infinity":16,"s:78:4:82:Infinity":17,"s:79:6:79:Infinity":18,"s:81:6:81:Infinity":19,"s:85:2:88:Infinity":20,"f:86:4:86:Infinity":5,"s:87:27:87:Infinity":21,"b:87:27:87:50:87:50:87:Infinity":3,"s:90:2:90:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-codes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-codes.ts","statementMap":{"0":{"start":{"line":36,"column":29},"end":{"line":46,"column":null}},"1":{"start":{"line":56,"column":66},"end":{"line":74,"column":null}},"2":{"start":{"line":81,"column":66},"end":{"line":83,"column":null}},"3":{"start":{"line":82,"column":76},"end":{"line":82,"column":88}},"4":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"5":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"6":{"start":{"line":101,"column":16},"end":{"line":101,"column":null}},"7":{"start":{"line":102,"column":15},"end":{"line":102,"column":null}},"8":{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},"9":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"10":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"11":{"start":{"line":115,"column":2},"end":{"line":115,"column":null}},"12":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"13":{"start":{"line":128,"column":66},"end":{"line":148,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":82,"column":54},"end":{"line":82,"column":59}},"loc":{"start":{"line":82,"column":76},"end":{"line":82,"column":88}},"line":82},"1":{"name":"toDatamapperCode","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":33}},"loc":{"start":{"line":90,"column":55},"end":{"line":93,"column":null}},"line":90},"2":{"name":"toImfAreaCode","decl":{"start":{"line":100,"column":16},"end":{"line":100,"column":30}},"loc":{"start":{"line":100,"column":52},"end":{"line":111,"column":null}},"line":100},"3":{"name":"isKnownIso3","decl":{"start":{"line":114,"column":16},"end":{"line":114,"column":28}},"loc":{"start":{"line":114,"column":51},"end":{"line":116,"column":null}},"line":114},"4":{"name":"listKnownIso3Codes","decl":{"start":{"line":123,"column":16},"end":{"line":123,"column":56}},"loc":{"start":{"line":123,"column":56},"end":{"line":125,"column":null}},"line":123}},"branchMap":{"0":{"loc":{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":2},"end":{"line":109,"column":null}},{"start":{},"end":{}}],"line":103}},"s":{"0":20,"1":20,"2":20,"3":340,"4":38,"5":38,"6":6,"7":6,"8":6,"9":3,"10":3,"11":4,"12":3,"13":20},"f":{"0":340,"1":38,"2":6,"3":4,"4":3},"b":{"0":[3,3]},"meta":{"lastBranch":1,"lastFunction":5,"lastStatement":14,"seen":{"s:36:29:46:Infinity":0,"s:56:66:74:Infinity":1,"s:81:66:83:Infinity":2,"f:82:54:82:59":0,"s:82:76:82:88":3,"f:90:16:90:33":1,"s:91:16:91:Infinity":4,"s:92:2:92:Infinity":5,"f:100:16:100:30":2,"s:101:16:101:Infinity":6,"s:102:15:102:Infinity":7,"b:103:2:109:Infinity:undefined:undefined:undefined:undefined":0,"s:103:2:109:Infinity":8,"s:104:4:108:Infinity":9,"s:110:2:110:Infinity":10,"f:114:16:114:28":3,"s:115:2:115:Infinity":11,"f:123:16:123:56":4,"s:124:2:124:Infinity":12,"s:128:66:148:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf-context.ts","statementMap":{"0":{"start":{"line":83,"column":62},"end":{"line":321,"column":null}},"1":{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},"2":{"start":{"line":331,"column":34},"end":{"line":331,"column":null}},"3":{"start":{"line":332,"column":18},"end":{"line":332,"column":null}},"4":{"start":{"line":332,"column":43},"end":{"line":332,"column":58}},"5":{"start":{"line":333,"column":2},"end":{"line":337,"column":null}},"6":{"start":{"line":334,"column":4},"end":{"line":336,"column":null}},"7":{"start":{"line":335,"column":6},"end":{"line":335,"column":null}},"8":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"9":{"start":{"line":344,"column":16},"end":{"line":344,"column":null}},"10":{"start":{"line":345,"column":2},"end":{"line":347,"column":null}},"11":{"start":{"line":346,"column":4},"end":{"line":346,"column":null}},"12":{"start":{"line":346,"column":37},"end":{"line":346,"column":62}},"13":{"start":{"line":351,"column":32},"end":{"line":357,"column":null}},"14":{"start":{"line":361,"column":2},"end":{"line":361,"column":null}},"15":{"start":{"line":369,"column":2},"end":{"line":369,"column":null}},"16":{"start":{"line":388,"column":18},"end":{"line":388,"column":null}},"17":{"start":{"line":389,"column":18},"end":{"line":389,"column":null}},"18":{"start":{"line":390,"column":2},"end":{"line":392,"column":null}},"19":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"20":{"start":{"line":403,"column":14},"end":{"line":403,"column":null}},"21":{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},"22":{"start":{"line":404,"column":47},"end":{"line":404,"column":null}},"23":{"start":{"line":405,"column":13},"end":{"line":405,"column":null}},"24":{"start":{"line":406,"column":13},"end":{"line":406,"column":null}},"25":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"26":{"start":{"line":416,"column":2},"end":{"line":416,"column":null}},"27":{"start":{"line":416,"column":45},"end":{"line":416,"column":57}},"28":{"start":{"line":435,"column":17},"end":{"line":435,"column":null}},"29":{"start":{"line":436,"column":2},"end":{"line":443,"column":null}},"30":{"start":{"line":437,"column":21},"end":{"line":437,"column":null}},"31":{"start":{"line":438,"column":4},"end":{"line":442,"column":null}},"32":{"start":{"line":439,"column":18},"end":{"line":439,"column":null}},"33":{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},"34":{"start":{"line":440,"column":28},"end":{"line":440,"column":null}},"35":{"start":{"line":441,"column":6},"end":{"line":441,"column":null}},"36":{"start":{"line":444,"column":14},"end":{"line":444,"column":null}},"37":{"start":{"line":445,"column":2},"end":{"line":447,"column":null}},"38":{"start":{"line":446,"column":4},"end":{"line":446,"column":null}},"39":{"start":{"line":448,"column":2},"end":{"line":448,"column":null}},"40":{"start":{"line":457,"column":2},"end":{"line":459,"column":null}},"41":{"start":{"line":458,"column":32},"end":{"line":458,"column":74}}},"fnMap":{"0":{"name":"findImfIndicatorsForDomains","decl":{"start":{"line":328,"column":16},"end":{"line":328,"column":null}},"loc":{"start":{"line":330,"column":34},"end":{"line":338,"column":null}},"line":330},"1":{"name":"(anonymous_1)","decl":{"start":{"line":332,"column":32},"end":{"line":332,"column":37}},"loc":{"start":{"line":332,"column":43},"end":{"line":332,"column":58}},"line":332},"2":{"name":"(anonymous_2)","decl":{"start":{"line":333,"column":24},"end":{"line":333,"column":32}},"loc":{"start":{"line":334,"column":4},"end":{"line":336,"column":null}},"line":334},"3":{"name":"(anonymous_3)","decl":{"start":{"line":334,"column":26},"end":{"line":334,"column":32}},"loc":{"start":{"line":335,"column":6},"end":{"line":335,"column":null}},"line":335},"4":{"name":"(anonymous_4)","decl":{"start":{"line":335,"column":14},"end":{"line":335,"column":20}},"loc":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"line":335},"5":{"name":"findImfIndicatorsForCommittee","decl":{"start":{"line":341,"column":16},"end":{"line":341,"column":null}},"loc":{"start":{"line":343,"column":34},"end":{"line":348,"column":null}},"line":343},"6":{"name":"(anonymous_6)","decl":{"start":{"line":345,"column":24},"end":{"line":345,"column":32}},"loc":{"start":{"line":346,"column":4},"end":{"line":346,"column":null}},"line":346},"7":{"name":"(anonymous_7)","decl":{"start":{"line":346,"column":25},"end":{"line":346,"column":31}},"loc":{"start":{"line":346,"column":37},"end":{"line":346,"column":62}},"line":346},"8":{"name":"imfCountryNameEn","decl":{"start":{"line":360,"column":16},"end":{"line":360,"column":33}},"loc":{"start":{"line":360,"column":55},"end":{"line":362,"column":null}},"line":360},"9":{"name":"imfCitation","decl":{"start":{"line":368,"column":16},"end":{"line":368,"column":28}},"loc":{"start":{"line":368,"column":80},"end":{"line":370,"column":null}},"line":368},"10":{"name":"findImfIndicatorByCode","decl":{"start":{"line":384,"column":16},"end":{"line":384,"column":null}},"loc":{"start":{"line":387,"column":35},"end":{"line":393,"column":null}},"line":387},"11":{"name":"(anonymous_11)","decl":{"start":{"line":390,"column":24},"end":{"line":390,"column":null}},"loc":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"line":391},"12":{"name":"findImfIndicatorByCitation","decl":{"start":{"line":400,"column":16},"end":{"line":400,"column":null}},"loc":{"start":{"line":402,"column":35},"end":{"line":408,"column":null}},"line":402},"13":{"name":"getImfDatabasesInUse","decl":{"start":{"line":415,"column":16},"end":{"line":415,"column":65}},"loc":{"start":{"line":415,"column":65},"end":{"line":417,"column":null}},"line":415},"14":{"name":"(anonymous_14)","decl":{"start":{"line":416,"column":32},"end":{"line":416,"column":37}},"loc":{"start":{"line":416,"column":45},"end":{"line":416,"column":57}},"line":416},"15":{"name":"getImfCommitteeMatrix","decl":{"start":{"line":434,"column":16},"end":{"line":434,"column":80}},"loc":{"start":{"line":434,"column":80},"end":{"line":449,"column":null}},"line":434},"16":{"name":"listImfCitations","decl":{"start":{"line":456,"column":16},"end":{"line":456,"column":54}},"loc":{"start":{"line":456,"column":54},"end":{"line":460,"column":null}},"line":456},"17":{"name":"(anonymous_17)","decl":{"start":{"line":458,"column":19},"end":{"line":458,"column":24}},"loc":{"start":{"line":458,"column":32},"end":{"line":458,"column":74}},"line":458}},"branchMap":{"0":{"loc":{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},"type":"if","locations":[{"start":{"line":331,"column":2},"end":{"line":331,"column":null}},{"start":{},"end":{}}],"line":331},"1":{"loc":{"start":{"line":335,"column":26},"end":{"line":335,"column":90}},"type":"binary-expr","locations":[{"start":{"line":335,"column":26},"end":{"line":335,"column":60}},{"start":{"line":335,"column":60},"end":{"line":335,"column":90}}],"line":335},"2":{"loc":{"start":{"line":361,"column":9},"end":{"line":361,"column":null}},"type":"binary-expr","locations":[{"start":{"line":361,"column":9},"end":{"line":361,"column":49}},{"start":{"line":361,"column":49},"end":{"line":361,"column":null}}],"line":361},"3":{"loc":{"start":{"line":391,"column":13},"end":{"line":391,"column":null}},"type":"binary-expr","locations":[{"start":{"line":391,"column":13},"end":{"line":391,"column":41}},{"start":{"line":391,"column":41},"end":{"line":391,"column":null}}],"line":391},"4":{"loc":{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},"type":"if","locations":[{"start":{"line":404,"column":2},"end":{"line":404,"column":null}},{"start":{},"end":{}}],"line":404},"5":{"loc":{"start":{"line":404,"column":6},"end":{"line":404,"column":47}},"type":"binary-expr","locations":[{"start":{"line":404,"column":6},"end":{"line":404,"column":18}},{"start":{"line":404,"column":18},"end":{"line":404,"column":47}}],"line":404},"6":{"loc":{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},"type":"if","locations":[{"start":{"line":440,"column":6},"end":{"line":440,"column":null}},{"start":{},"end":{}}],"line":440}},"s":{"0":1,"1":5,"2":1,"3":4,"4":4,"5":4,"6":80,"7":161,"8":161,"9":4,"10":4,"11":80,"12":134,"13":1,"14":3,"15":163,"16":32,"17":32,"18":32,"19":314,"20":26,"21":26,"22":4,"23":22,"24":22,"25":22,"26":2,"27":40,"28":5,"29":5,"30":100,"31":100,"32":200,"33":200,"34":50,"35":200,"36":5,"37":5,"38":50,"39":5,"40":2,"41":40},"f":{"0":5,"1":4,"2":80,"3":161,"4":161,"5":4,"6":80,"7":134,"8":3,"9":163,"10":32,"11":314,"12":26,"13":2,"14":40,"15":5,"16":2,"17":40},"b":{"0":[1,4],"1":[161,151],"2":[3,1],"3":[314,109],"4":[4,22],"5":[26,23],"6":[50,150]},"meta":{"lastBranch":7,"lastFunction":18,"lastStatement":42,"seen":{"s:83:62:321:Infinity":0,"f:328:16:328:Infinity":0,"b:331:2:331:Infinity:undefined:undefined:undefined:undefined":0,"s:331:2:331:Infinity":1,"s:331:34:331:Infinity":2,"s:332:18:332:Infinity":3,"f:332:32:332:37":1,"s:332:43:332:58":4,"s:333:2:337:Infinity":5,"f:333:24:333:32":2,"s:334:4:336:Infinity":6,"f:334:26:334:32":3,"s:335:6:335:Infinity":7,"f:335:14:335:20":4,"s:335:26:335:90":8,"b:335:26:335:60:335:60:335:90":1,"f:341:16:341:Infinity":5,"s:344:16:344:Infinity":9,"s:345:2:347:Infinity":10,"f:345:24:345:32":6,"s:346:4:346:Infinity":11,"f:346:25:346:31":7,"s:346:37:346:62":12,"s:351:32:357:Infinity":13,"f:360:16:360:33":8,"s:361:2:361:Infinity":14,"b:361:9:361:49:361:49:361:Infinity":2,"f:368:16:368:28":9,"s:369:2:369:Infinity":15,"f:384:16:384:Infinity":10,"s:388:18:388:Infinity":16,"s:389:18:389:Infinity":17,"s:390:2:392:Infinity":18,"f:390:24:390:Infinity":11,"s:391:13:391:Infinity":19,"b:391:13:391:41:391:41:391:Infinity":3,"f:400:16:400:Infinity":12,"s:403:14:403:Infinity":20,"b:404:2:404:Infinity:undefined:undefined:undefined:undefined":4,"s:404:2:404:Infinity":21,"b:404:6:404:18:404:18:404:47":5,"s:404:47:404:Infinity":22,"s:405:13:405:Infinity":23,"s:406:13:406:Infinity":24,"s:407:2:407:Infinity":25,"f:415:16:415:65":13,"s:416:2:416:Infinity":26,"f:416:32:416:37":14,"s:416:45:416:57":27,"f:434:16:434:80":15,"s:435:17:435:Infinity":28,"s:436:2:443:Infinity":29,"s:437:21:437:Infinity":30,"s:438:4:442:Infinity":31,"s:439:18:439:Infinity":32,"b:440:6:440:Infinity:undefined:undefined:undefined:undefined":6,"s:440:6:440:Infinity":33,"s:440:28:440:Infinity":34,"s:441:6:441:Infinity":35,"s:444:14:444:Infinity":36,"s:445:2:447:Infinity":37,"s:446:4:446:Infinity":38,"s:448:2:448:Infinity":39,"f:456:16:456:54":16,"s:457:2:459:Infinity":40,"f:458:19:458:24":17,"s:458:32:458:74":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/client.ts","statementMap":{"0":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"1":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"2":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"3":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"4":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"5":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"6":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"7":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"8":{"start":{"line":95,"column":4},"end":{"line":101,"column":null}},"9":{"start":{"line":110,"column":4},"end":{"line":116,"column":null}},"10":{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},"11":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"12":{"start":{"line":133,"column":16},"end":{"line":133,"column":null}},"13":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"14":{"start":{"line":135,"column":6},"end":{"line":145,"column":null}},"15":{"start":{"line":136,"column":23},"end":{"line":136,"column":null}},"16":{"start":{"line":137,"column":8},"end":{"line":137,"column":null}},"17":{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},"18":{"start":{"line":140,"column":10},"end":{"line":140,"column":null}},"19":{"start":{"line":141,"column":10},"end":{"line":141,"column":null}},"20":{"start":{"line":142,"column":10},"end":{"line":142,"column":null}},"21":{"start":{"line":144,"column":8},"end":{"line":144,"column":null}},"22":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"23":{"start":{"line":159,"column":19},"end":{"line":159,"column":null}},"24":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"25":{"start":{"line":160,"column":29},"end":{"line":160,"column":null}},"26":{"start":{"line":161,"column":20},"end":{"line":161,"column":null}},"27":{"start":{"line":161,"column":41},"end":{"line":161,"column":54}},"28":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"29":{"start":{"line":174,"column":16},"end":{"line":174,"column":null}},"30":{"start":{"line":175,"column":4},"end":{"line":182,"column":null}},"31":{"start":{"line":176,"column":6},"end":{"line":181,"column":null}},"32":{"start":{"line":177,"column":23},"end":{"line":177,"column":null}},"33":{"start":{"line":178,"column":8},"end":{"line":178,"column":null}},"34":{"start":{"line":180,"column":8},"end":{"line":180,"column":null}},"35":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"36":{"start":{"line":192,"column":4},"end":{"line":198,"column":null}},"37":{"start":{"line":202,"column":41},"end":{"line":202,"column":null}},"38":{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},"39":{"start":{"line":207,"column":4},"end":{"line":207,"column":null}},"40":{"start":{"line":209,"column":2},"end":{"line":209,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":72,"column":2},"end":{"line":72,"column":14}},"loc":{"start":{"line":72,"column":44},"end":{"line":81,"column":null}},"line":72},"1":{"name":"(anonymous_1)","decl":{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},"loc":{"start":{"line":94,"column":29},"end":{"line":102,"column":null}},"line":94},"2":{"name":"(anonymous_2)","decl":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"loc":{"start":{"line":109,"column":85},"end":{"line":117,"column":null}},"line":109},"3":{"name":"(anonymous_3)","decl":{"start":{"line":124,"column":8},"end":{"line":124,"column":null}},"loc":{"start":{"line":128,"column":51},"end":{"line":148,"column":null}},"line":128},"4":{"name":"(anonymous_4)","decl":{"start":{"line":155,"column":8},"end":{"line":155,"column":null}},"loc":{"start":{"line":158,"column":34},"end":{"line":163,"column":null}},"line":158},"5":{"name":"(anonymous_5)","decl":{"start":{"line":161,"column":27},"end":{"line":161,"column":35}},"loc":{"start":{"line":161,"column":41},"end":{"line":161,"column":54}},"line":161},"6":{"name":"(anonymous_6)","decl":{"start":{"line":170,"column":8},"end":{"line":170,"column":null}},"loc":{"start":{"line":173,"column":47},"end":{"line":184,"column":null}},"line":173},"7":{"name":"(anonymous_7)","decl":{"start":{"line":191,"column":8},"end":{"line":191,"column":18}},"loc":{"start":{"line":191,"column":59},"end":{"line":199,"column":null}},"line":191},"8":{"name":"getDefaultImfClient","decl":{"start":{"line":205,"column":16},"end":{"line":205,"column":49}},"loc":{"start":{"line":205,"column":49},"end":{"line":210,"column":null}},"line":205}},"branchMap":{"0":{"loc":{"start":{"line":72,"column":14},"end":{"line":72,"column":44}},"type":"default-arg","locations":[{"start":{"line":72,"column":40},"end":{"line":72,"column":44}}],"line":72},"1":{"loc":{"start":{"line":73,"column":29},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":29},"end":{"line":73,"column":57}},{"start":{"line":73,"column":57},"end":{"line":73,"column":null}}],"line":73},"2":{"loc":{"start":{"line":74,"column":23},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":45}},{"start":{"line":74,"column":45},"end":{"line":74,"column":null}}],"line":74},"3":{"loc":{"start":{"line":75,"column":19},"end":{"line":75,"column":null}},"type":"binary-expr","locations":[{"start":{"line":75,"column":19},"end":{"line":75,"column":37}},{"start":{"line":75,"column":37},"end":{"line":75,"column":null}}],"line":75},"4":{"loc":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":22},"end":{"line":76,"column":43}},{"start":{"line":76,"column":43},"end":{"line":76,"column":null}}],"line":76},"5":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"type":"binary-expr","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":41}},{"start":{"line":77,"column":41},"end":{"line":77,"column":null}}],"line":77},"6":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"type":"binary-expr","locations":[{"start":{"line":78,"column":22},"end":{"line":78,"column":43}},{"start":{"line":78,"column":43},"end":{"line":78,"column":null}}],"line":78},"7":{"loc":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"type":"default-arg","locations":[{"start":{"line":93,"column":12},"end":{"line":93,"column":null}}],"line":93},"8":{"loc":{"start":{"line":127,"column":4},"end":{"line":127,"column":null}},"type":"default-arg","locations":[{"start":{"line":127,"column":12},"end":{"line":127,"column":null}}],"line":127},"9":{"loc":{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":129,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":129},"10":{"loc":{"start":{"line":129,"column":8},"end":{"line":129,"column":47}},"type":"binary-expr","locations":[{"start":{"line":129,"column":8},"end":{"line":129,"column":21}},{"start":{"line":129,"column":21},"end":{"line":129,"column":47}}],"line":129},"11":{"loc":{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":139,"column":8},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":139},"12":{"loc":{"start":{"line":139,"column":12},"end":{"line":139,"column":96}},"type":"binary-expr","locations":[{"start":{"line":139,"column":12},"end":{"line":139,"column":45}},{"start":{"line":139,"column":45},"end":{"line":139,"column":78}},{"start":{"line":139,"column":78},"end":{"line":139,"column":96}}],"line":139},"13":{"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":160},"14":{"loc":{"start":{"line":162,"column":11},"end":{"line":162,"column":null}},"type":"binary-expr","locations":[{"start":{"line":162,"column":11},"end":{"line":162,"column":25}},{"start":{"line":162,"column":25},"end":{"line":162,"column":null}}],"line":162},"15":{"loc":{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":2},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":206}},"s":{"0":53,"1":53,"2":53,"3":53,"4":53,"5":53,"6":53,"7":53,"8":36,"9":1,"10":7,"11":1,"12":6,"13":6,"14":10,"15":10,"16":5,"17":5,"18":3,"19":3,"20":3,"21":2,"22":4,"23":6,"24":5,"25":3,"26":2,"27":5,"28":2,"29":1,"30":1,"31":3,"32":3,"33":2,"34":1,"35":1,"36":9,"37":19,"38":2,"39":1,"40":2},"f":{"0":53,"1":36,"2":1,"3":7,"4":6,"5":5,"6":1,"7":9,"8":2},"b":{"0":[53],"1":[53,52],"2":[53,52],"3":[53,12],"4":[53,6],"5":[53,52],"6":[53,20],"7":[36],"8":[7],"9":[1,6],"10":[7,6],"11":[3,2],"12":[5,4,3],"13":[3,2],"14":[2,1],"15":[1,1]},"meta":{"lastBranch":16,"lastFunction":9,"lastStatement":41,"seen":{"f:72:2:72:14":0,"b:72:40:72:44":0,"s:73:4:73:Infinity":0,"b:73:29:73:57:73:57:73:Infinity":1,"s:74:4:74:Infinity":1,"b:74:23:74:45:74:45:74:Infinity":2,"s:75:4:75:Infinity":2,"b:75:19:75:37:75:37:75:Infinity":3,"s:76:4:76:Infinity":3,"b:76:22:76:43:76:43:76:Infinity":4,"s:77:4:77:Infinity":4,"b:77:21:77:41:77:41:77:Infinity":5,"s:78:4:78:Infinity":5,"b:78:22:78:43:78:43:78:Infinity":6,"s:79:4:79:Infinity":6,"s:80:4:80:Infinity":7,"f:90:8:90:Infinity":1,"b:93:12:93:Infinity":7,"s:95:4:101:Infinity":8,"f:109:8:109:85":2,"s:110:4:116:Infinity":9,"f:124:8:124:Infinity":3,"b:127:12:127:Infinity":8,"b:129:4:131:Infinity:undefined:undefined:undefined:undefined":9,"s:129:4:131:Infinity":10,"b:129:8:129:21:129:21:129:47":10,"s:130:6:130:Infinity":11,"s:133:16:133:Infinity":12,"s:134:4:146:Infinity":13,"s:135:6:145:Infinity":14,"s:136:23:136:Infinity":15,"s:137:8:137:Infinity":16,"b:139:8:143:Infinity:undefined:undefined:undefined:undefined":11,"s:139:8:143:Infinity":17,"b:139:12:139:45:139:45:139:78:139:78:139:96":12,"s:140:10:140:Infinity":18,"s:141:10:141:Infinity":19,"s:142:10:142:Infinity":20,"s:144:8:144:Infinity":21,"s:147:4:147:Infinity":22,"f:155:8:155:Infinity":4,"s:159:19:159:Infinity":23,"b:160:4:160:Infinity:undefined:undefined:undefined:undefined":13,"s:160:4:160:Infinity":24,"s:160:29:160:Infinity":25,"s:161:20:161:Infinity":26,"f:161:27:161:35":5,"s:161:41:161:54":27,"s:162:4:162:Infinity":28,"b:162:11:162:25:162:25:162:Infinity":14,"f:170:8:170:Infinity":6,"s:174:16:174:Infinity":29,"s:175:4:182:Infinity":30,"s:176:6:181:Infinity":31,"s:177:23:177:Infinity":32,"s:178:8:178:Infinity":33,"s:180:8:180:Infinity":34,"s:183:4:183:Infinity":35,"f:191:8:191:18":7,"s:192:4:198:Infinity":36,"s:202:41:202:Infinity":37,"f:205:16:205:49":8,"b:206:2:208:Infinity:undefined:undefined:undefined:undefined":15,"s:206:2:208:Infinity":38,"s:207:4:207:Infinity":39,"s:209:2:209:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/auth.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/auth.ts","statementMap":{"0":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"1":{"start":{"line":43,"column":30},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}}},"fnMap":{"0":{"name":"resolveSdmxSubscriptionKey","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":43}},"loc":{"start":{"line":42,"column":70},"end":{"line":45,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":44,"column":9},"end":{"line":44,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":9},"end":{"line":44,"column":53}},{"start":{"line":44,"column":53},"end":{"line":44,"column":null}}],"line":44}},"s":{"0":53,"1":5,"2":48},"f":{"0":53},"b":{"0":[5,48],"1":[48,47]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":3,"seen":{"f:42:16:42:43":0,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":0,"s:43:30:43:Infinity":1,"s:44:2:44:Infinity":2,"b:44:9:44:53:44:53:44:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/defaults.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/config/defaults.ts","statementMap":{"0":{"start":{"line":14,"column":43},"end":{"line":14,"column":null}},"1":{"start":{"line":15,"column":37},"end":{"line":15,"column":null}},"2":{"start":{"line":16,"column":31},"end":{"line":16,"column":null}},"3":{"start":{"line":17,"column":35},"end":{"line":17,"column":null}},"4":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"5":{"start":{"line":27,"column":35},"end":{"line":27,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":20,"1":20,"2":20,"3":20,"4":20,"5":20},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":6,"seen":{"s:14:43:14:Infinity":0,"s:15:37:15:Infinity":1,"s:16:31:16:Infinity":2,"s:17:35:17:Infinity":3,"s:19:2:19:Infinity":4,"s:27:35:27:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/http-error.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/http-error.ts","statementMap":{"0":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":24},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":23},"end":{"line":34,"column":null}},"5":{"start":{"line":35,"column":10},"end":{"line":38,"column":null}},"6":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"7":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"8":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"9":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":29,"column":2},"end":{"line":29,"column":14}},"loc":{"start":{"line":29,"column":84},"end":{"line":44,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":29,"column":55},"end":{"line":29,"column":84}},"type":"default-arg","locations":[{"start":{"line":29,"column":77},"end":{"line":29,"column":84}}],"line":29},"1":{"loc":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":16},"end":{"line":30,"column":32}},{"start":{"line":30,"column":32},"end":{"line":30,"column":46}},{"start":{"line":30,"column":46},"end":{"line":30,"column":null}}],"line":30},"2":{"loc":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":26},"end":{"line":32,"column":53}},{"start":{"line":32,"column":53},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":32},"end":{"line":33,"column":59}},{"start":{"line":33,"column":59},"end":{"line":33,"column":null}}],"line":33},"4":{"loc":{"start":{"line":34,"column":23},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":23},"end":{"line":34,"column":72}},{"start":{"line":34,"column":72},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":10},"end":{"line":38,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":null}},{"start":{"line":38,"column":10},"end":{"line":38,"column":null}}],"line":35},"6":{"loc":{"start":{"line":35,"column":10},"end":{"line":36,"column":null}},"type":"binary-expr","locations":[{"start":{"line":36,"column":7},"end":{"line":36,"column":24}},{"start":{"line":36,"column":24},"end":{"line":36,"column":48}},{"start":{"line":36,"column":48},"end":{"line":36,"column":null}}],"line":35},"7":{"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":48}},{"start":{"line":42,"column":48},"end":{"line":42,"column":null}}],"line":42}},"s":{"0":17,"1":17,"2":17,"3":17,"4":17,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17},"f":{"0":17},"b":{"0":[17],"1":[17,17,3],"2":[17,16],"3":[17,6],"4":[17,12],"5":[4,13],"6":[17,15,6],"7":[17,14]},"meta":{"lastBranch":8,"lastFunction":1,"lastStatement":11,"seen":{"f:29:2:29:14":0,"b:29:77:29:84":0,"s:30:16:30:Infinity":0,"b:30:16:30:32:30:32:30:46:30:46:30:Infinity":1,"s:31:24:31:Infinity":1,"s:32:26:32:Infinity":2,"b:32:26:32:53:32:53:32:Infinity":2,"s:33:32:33:Infinity":3,"b:33:32:33:59:33:59:33:Infinity":3,"s:34:23:34:Infinity":4,"b:34:23:34:72:34:72:34:Infinity":4,"s:35:10:38:Infinity":5,"b:37:10:37:Infinity:38:10:38:Infinity":5,"b:36:7:36:24:36:24:36:48:36:48:36:Infinity":6,"s:39:4:39:Infinity":6,"s:40:4:40:Infinity":7,"s:41:4:41:Infinity":8,"s:42:4:42:Infinity":9,"b:42:21:42:48:42:48:42:Infinity":7,"s:43:4:43:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/weo-sdmx-only.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/errors/weo-sdmx-only.ts","statementMap":{"0":{"start":{"line":23,"column":27},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":4},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"6":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":22,"column":2},"end":{"line":22,"column":14}},"loc":{"start":{"line":22,"column":45},"end":{"line":34,"column":null}},"line":22}},"branchMap":{},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4},"f":{"0":4},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":7,"seen":{"f:22:2:22:14":0,"s:23:27:23:Infinity":0,"s:24:21:24:Infinity":1,"s:25:4:29:Infinity":2,"s:30:4:30:Infinity":3,"s:31:4:31:Infinity":4,"s:32:4:32:Infinity":5,"s:33:4:33:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/cofog-codes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/cofog-codes.ts","statementMap":{"0":{"start":{"line":16,"column":29},"end":{"line":16,"column":null}},"1":{"start":{"line":18,"column":28},"end":{"line":18,"column":null}},"2":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":39},"end":{"line":22,"column":null}},"4":{"start":{"line":28,"column":35},"end":{"line":33,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":15,"1":15,"2":15,"3":15,"4":15},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":5,"seen":{"s:16:29:16:Infinity":0,"s:18:28:18:Infinity":1,"s:20:31:20:Infinity":2,"s:22:39:22:Infinity":3,"s:28:35:33:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/fm.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/fm.ts","statementMap":{"0":{"start":{"line":16,"column":33},"end":{"line":21,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":17},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:16:33:21:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/parsers/datamapper-envelope.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/parsers/datamapper-envelope.ts","statementMap":{"0":{"start":{"line":84,"column":24},"end":{"line":84,"column":null}},"1":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"2":{"start":{"line":85,"column":22},"end":{"line":85,"column":null}},"3":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"4":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"5":{"start":{"line":87,"column":20},"end":{"line":87,"column":null}},"6":{"start":{"line":89,"column":22},"end":{"line":89,"column":null}},"7":{"start":{"line":90,"column":33},"end":{"line":90,"column":null}},"8":{"start":{"line":91,"column":2},"end":{"line":111,"column":null}},"9":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"10":{"start":{"line":92,"column":53},"end":{"line":92,"column":null}},"11":{"start":{"line":93,"column":20},"end":{"line":93,"column":null}},"12":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"13":{"start":{"line":94,"column":35},"end":{"line":94,"column":null}},"14":{"start":{"line":95,"column":20},"end":{"line":95,"column":null}},"15":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"16":{"start":{"line":96,"column":35},"end":{"line":96,"column":null}},"17":{"start":{"line":97,"column":25},"end":{"line":97,"column":null}},"18":{"start":{"line":98,"column":29},"end":{"line":109,"column":null}},"19":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"20":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"21":{"start":{"line":113,"column":24},"end":{"line":113,"column":81}},"22":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"23":{"start":{"line":124,"column":14},"end":{"line":124,"column":null}},"24":{"start":{"line":125,"column":21},"end":{"line":125,"column":null}},"25":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"26":{"start":{"line":126,"column":19},"end":{"line":126,"column":null}},"27":{"start":{"line":127,"column":2},"end":{"line":140,"column":null}},"28":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"29":{"start":{"line":128,"column":43},"end":{"line":128,"column":null}},"30":{"start":{"line":129,"column":20},"end":{"line":129,"column":null}},"31":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"32":{"start":{"line":130,"column":18},"end":{"line":130,"column":null}},"33":{"start":{"line":131,"column":4},"end":{"line":139,"column":null}},"34":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}}},"fnMap":{"0":{"name":"parseDatamapperValues","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":null}},"loc":{"start":{"line":83,"column":18},"end":{"line":115,"column":null}},"line":83},"1":{"name":"(anonymous_1)","decl":{"start":{"line":113,"column":9},"end":{"line":113,"column":15}},"loc":{"start":{"line":113,"column":24},"end":{"line":113,"column":81}},"line":113},"2":{"name":"parseDatamapperIndicators","decl":{"start":{"line":121,"column":16},"end":{"line":121,"column":null}},"loc":{"start":{"line":123,"column":43},"end":{"line":142,"column":null}},"line":123}},"branchMap":{"0":{"loc":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":85},"1":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"2":{"loc":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92},"3":{"loc":{"start":{"line":92,"column":8},"end":{"line":92,"column":53}},"type":"binary-expr","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":29}},{"start":{"line":92,"column":29},"end":{"line":92,"column":53}}],"line":92},"4":{"loc":{"start":{"line":93,"column":20},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":51},"end":{"line":93,"column":62}},{"start":{"line":93,"column":62},"end":{"line":93,"column":null}}],"line":93},"5":{"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":94},"6":{"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":96},"7":{"loc":{"start":{"line":108,"column":10},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":25},"end":{"line":108,"column":61}},{"start":{"line":108,"column":61},"end":{"line":108,"column":null}}],"line":108},"8":{"loc":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},{"start":{},"end":{}}],"line":126},"9":{"loc":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":128},"10":{"loc":{"start":{"line":128,"column":8},"end":{"line":128,"column":43}},"type":"binary-expr","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":17}},{"start":{"line":128,"column":17},"end":{"line":128,"column":43}}],"line":128},"11":{"loc":{"start":{"line":129,"column":20},"end":{"line":129,"column":null}},"type":"cond-expr","locations":[{"start":{"line":129,"column":55},"end":{"line":129,"column":70}},{"start":{"line":129,"column":70},"end":{"line":129,"column":null}}],"line":129},"12":{"loc":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":130},"13":{"loc":{"start":{"line":133,"column":13},"end":{"line":133,"column":null}},"type":"cond-expr","locations":[{"start":{"line":133,"column":46},"end":{"line":133,"column":59}},{"start":{"line":133,"column":59},"end":{"line":133,"column":null}}],"line":133},"14":{"loc":{"start":{"line":134,"column":19},"end":{"line":134,"column":null}},"type":"cond-expr","locations":[{"start":{"line":134,"column":58},"end":{"line":134,"column":77}},{"start":{"line":134,"column":77},"end":{"line":134,"column":null}}],"line":134},"15":{"loc":{"start":{"line":135,"column":14},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":135,"column":48},"end":{"line":135,"column":62}},{"start":{"line":135,"column":62},"end":{"line":135,"column":null}}],"line":135},"16":{"loc":{"start":{"line":136,"column":12},"end":{"line":136,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":44},"end":{"line":136,"column":56}},{"start":{"line":136,"column":56},"end":{"line":136,"column":null}}],"line":136},"17":{"loc":{"start":{"line":138,"column":10},"end":{"line":138,"column":null}},"type":"cond-expr","locations":[{"start":{"line":138,"column":48},"end":{"line":138,"column":82}},{"start":{"line":138,"column":82},"end":{"line":138,"column":null}}],"line":138}},"s":{"0":34,"1":34,"2":10,"3":24,"4":24,"5":4,"6":20,"7":20,"8":20,"9":45,"10":2,"11":43,"12":45,"13":2,"14":41,"15":41,"16":1,"17":40,"18":40,"19":45,"20":20,"21":34,"22":20,"23":7,"24":7,"25":7,"26":3,"27":4,"28":9,"29":1,"30":8,"31":9,"32":1,"33":7,"34":4},"f":{"0":34,"1":34,"2":7},"b":{"0":[10,24],"1":[4,20],"2":[2,43],"3":[45,43],"4":[41,2],"5":[2,43],"6":[1,40],"7":[6,34],"8":[3,4],"9":[1,8],"10":[9,8],"11":[7,1],"12":[1,8],"13":[7,0],"14":[0,7],"15":[0,7],"16":[2,5],"17":[1,6]},"meta":{"lastBranch":18,"lastFunction":3,"lastStatement":35,"seen":{"f:78:16:78:Infinity":0,"s:84:24:84:Infinity":0,"b:85:2:85:Infinity:undefined:undefined:undefined:undefined":0,"s:85:2:85:Infinity":1,"s:85:22:85:Infinity":2,"s:86:22:86:Infinity":3,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":1,"s:87:2:87:Infinity":4,"s:87:20:87:Infinity":5,"s:89:22:89:Infinity":6,"s:90:33:90:Infinity":7,"s:91:2:111:Infinity":8,"b:92:4:92:Infinity:undefined:undefined:undefined:undefined":2,"s:92:4:92:Infinity":9,"b:92:8:92:29:92:29:92:53":3,"s:92:53:92:Infinity":10,"s:93:20:93:Infinity":11,"b:93:51:93:62:93:62:93:Infinity":4,"b:94:4:94:Infinity:undefined:undefined:undefined:undefined":5,"s:94:4:94:Infinity":12,"s:94:35:94:Infinity":13,"s:95:20:95:Infinity":14,"b:96:4:96:Infinity:undefined:undefined:undefined:undefined":6,"s:96:4:96:Infinity":15,"s:96:35:96:Infinity":16,"s:97:25:97:Infinity":17,"s:98:29:109:Infinity":18,"b:108:25:108:61:108:61:108:Infinity":7,"s:110:4:110:Infinity":19,"s:113:2:113:Infinity":20,"f:113:9:113:15":1,"s:113:24:113:81":21,"s:114:2:114:Infinity":22,"f:121:16:121:Infinity":2,"s:124:14:124:Infinity":23,"s:125:21:125:Infinity":24,"b:126:2:126:Infinity:undefined:undefined:undefined:undefined":8,"s:126:2:126:Infinity":25,"s:126:19:126:Infinity":26,"s:127:2:140:Infinity":27,"b:128:4:128:Infinity:undefined:undefined:undefined:undefined":9,"s:128:4:128:Infinity":28,"b:128:8:128:17:128:17:128:43":10,"s:128:43:128:Infinity":29,"s:129:20:129:Infinity":30,"b:129:55:129:70:129:70:129:Infinity":11,"b:130:4:130:Infinity:undefined:undefined:undefined:undefined":12,"s:130:4:130:Infinity":31,"s:130:18:130:Infinity":32,"s:131:4:139:Infinity":33,"b:133:46:133:59:133:59:133:Infinity":13,"b:134:58:134:77:134:77:134:Infinity":14,"b:135:48:135:62:135:62:135:Infinity":15,"b:136:44:136:56:136:56:136:Infinity":16,"b:138:48:138:82:138:82:138:Infinity":17,"s:141:2:141:Infinity":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/weo.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/indicators/weo.ts","statementMap":{"0":{"start":{"line":25,"column":34},"end":{"line":50,"column":null}},"1":{"start":{"line":60,"column":65},"end":{"line":70,"column":null}},"2":{"start":{"line":80,"column":54},"end":{"line":85,"column":null}},"3":{"start":{"line":96,"column":12},"end":{"line":96,"column":null}},"4":{"start":{"line":97,"column":12},"end":{"line":97,"column":null}},"5":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"weoSdmxPath","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":28}},"loc":{"start":{"line":95,"column":67},"end":{"line":99,"column":null}},"line":95}},"branchMap":{},"s":{"0":19,"1":19,"2":19,"3":7,"4":7,"5":7},"f":{"0":7},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":6,"seen":{"s:25:34:50:Infinity":0,"s:60:65:70:Infinity":1,"s:80:54:85:Infinity":2,"f:95:16:95:28":0,"s:96:12:96:Infinity":3,"s:97:12:97:Infinity":4,"s:98:2:98:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/datamapper.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/datamapper.ts","statementMap":{"0":{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},"1":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"2":{"start":{"line":52,"column":15},"end":{"line":52,"column":null}},"3":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"4":{"start":{"line":54,"column":15},"end":{"line":58,"column":null}},"5":{"start":{"line":60,"column":17},"end":{"line":60,"column":null}},"6":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"7":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":64,"column":null}},"9":{"start":{"line":71,"column":14},"end":{"line":71,"column":null}},"10":{"start":{"line":72,"column":15},"end":{"line":76,"column":null}},"11":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}}},"fnMap":{"0":{"name":"fetchDatamapperWeoIndicator","decl":{"start":{"line":43,"column":22},"end":{"line":43,"column":null}},"loc":{"start":{"line":48,"column":27},"end":{"line":65,"column":null}},"line":48},"1":{"name":"fetchDatamapperIndicators","decl":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"loc":{"start":{"line":70,"column":52},"end":{"line":78,"column":null}},"line":70}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":49},"1":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":45}},"type":"binary-expr","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":19}},{"start":{"line":49,"column":19},"end":{"line":49,"column":45}}],"line":49},"2":{"loc":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"3":{"loc":{"start":{"line":61,"column":6},"end":{"line":61,"column":61}},"type":"binary-expr","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":29}},{"start":{"line":61,"column":29},"end":{"line":61,"column":61}}],"line":61}},"s":{"0":36,"1":3,"2":33,"3":33,"4":33,"5":23,"6":23,"7":2,"8":21,"9":1,"10":1,"11":1},"f":{"0":36,"1":1},"b":{"0":[3,33],"1":[36,34],"2":[2,21],"3":[23,7]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":12,"seen":{"f:43:22:43:Infinity":0,"b:49:2:51:Infinity:undefined:undefined:undefined:undefined":0,"s:49:2:51:Infinity":0,"b:49:6:49:19:49:19:49:45":1,"s:50:4:50:Infinity":1,"s:52:15:52:Infinity":2,"s:53:14:53:Infinity":3,"s:54:15:58:Infinity":4,"s:60:17:60:Infinity":5,"b:61:2:63:Infinity:undefined:undefined:undefined:undefined":2,"s:61:2:63:Infinity":6,"b:61:6:61:29:61:29:61:61":3,"s:62:4:62:Infinity":7,"s:64:2:64:Infinity":8,"f:68:22:68:Infinity":1,"s:71:14:71:Infinity":9,"s:72:15:76:Infinity":10,"s:77:2:77:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/path-normaliser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/path-normaliser.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"3":{"start":{"line":25,"column":4},"end":{"line":25,"column":null}},"4":{"start":{"line":27,"column":13},"end":{"line":27,"column":null}},"5":{"start":{"line":28,"column":12},"end":{"line":28,"column":null}},"6":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},"7":{"start":{"line":30,"column":4},"end":{"line":30,"column":null}},"8":{"start":{"line":32,"column":64},"end":{"line":32,"column":null}},"9":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}}},"fnMap":{"0":{"name":"normalizeSdmxPathForBase","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":41}},"loc":{"start":{"line":20,"column":89},"end":{"line":34,"column":null}},"line":20}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":21},"1":{"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":26,"column":null}},{"start":{},"end":{}}],"line":24},"2":{"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":29},"3":{"loc":{"start":{"line":33,"column":63},"end":{"line":33,"column":79}},"type":"binary-expr","locations":[{"start":{"line":33,"column":63},"end":{"line":33,"column":74}},{"start":{"line":33,"column":74},"end":{"line":33,"column":79}}],"line":33},"4":{"loc":{"start":{"line":33,"column":79},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":79},"end":{"line":33,"column":88}},{"start":{"line":33,"column":88},"end":{"line":33,"column":null}}],"line":33}},"s":{"0":17,"1":1,"2":16,"3":1,"4":15,"5":15,"6":15,"7":2,"8":13,"9":13},"f":{"0":17},"b":{"0":[1,16],"1":[1,15],"2":[2,13],"3":[13,1],"4":[17,12]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":10,"seen":{"f:20:16:20:41":0,"b:21:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:21:2:23:Infinity":0,"s:22:4:22:Infinity":1,"b:24:2:26:Infinity:undefined:undefined:undefined:undefined":1,"s:24:2:26:Infinity":2,"s:25:4:25:Infinity":3,"s:27:13:27:Infinity":4,"s:28:12:28:Infinity":5,"b:29:2:31:Infinity:undefined:undefined:undefined:undefined":2,"s:29:2:31:Infinity":6,"s:30:4:30:Infinity":7,"s:32:64:32:Infinity":8,"s:33:2:33:Infinity":9,"b:33:63:33:74:33:74:33:79":3,"b:33:79:33:88:33:88:33:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/fetch-with-retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/fetch-with-retry.ts","statementMap":{"0":{"start":{"line":43,"column":64},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"2":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"3":{"start":{"line":45,"column":37},"end":{"line":45,"column":57}},"4":{"start":{"line":46,"column":2},"end":{"line":73,"column":null}},"5":{"start":{"line":47,"column":21},"end":{"line":54,"column":null}},"6":{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},"7":{"start":{"line":57,"column":34},"end":{"line":57,"column":null}},"8":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"9":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"10":{"start":{"line":63,"column":29},"end":{"line":63,"column":null}},"11":{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},"12":{"start":{"line":65,"column":20},"end":{"line":65,"column":null}},"13":{"start":{"line":66,"column":6},"end":{"line":66,"column":null}},"14":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"15":{"start":{"line":67,"column":37},"end":{"line":67,"column":63}},"16":{"start":{"line":68,"column":6},"end":{"line":68,"column":null}},"17":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"18":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"fetchWithRetry","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":20},"end":{"line":74,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":20},"end":{"line":45,"column":37}},"loc":{"start":{"line":45,"column":37},"end":{"line":45,"column":57}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":67,"column":16},"end":{"line":67,"column":25}},"loc":{"start":{"line":67,"column":37},"end":{"line":67,"column":63}},"line":67}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"type":"default-arg","locations":[{"start":{"line":41,"column":12},"end":{"line":41,"column":null}}],"line":41},"1":{"loc":{"start":{"line":43,"column":42},"end":{"line":43,"column":64}},"type":"default-arg","locations":[{"start":{"line":43,"column":57},"end":{"line":43,"column":64}}],"line":43},"2":{"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":56},"3":{"loc":{"start":{"line":63,"column":29},"end":{"line":63,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":61},"end":{"line":63,"column":86}},{"start":{"line":63,"column":86},"end":{"line":63,"column":null}}],"line":63},"4":{"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":64},"5":{"loc":{"start":{"line":64,"column":8},"end":{"line":64,"column":57}},"type":"binary-expr","locations":[{"start":{"line":64,"column":8},"end":{"line":64,"column":32}},{"start":{"line":64,"column":32},"end":{"line":64,"column":57}}],"line":64}},"s":{"0":45,"1":45,"2":45,"3":0,"4":45,"5":45,"6":42,"7":13,"8":13,"9":29,"10":17,"11":17,"12":2,"13":2,"14":2,"15":2,"16":2,"17":15,"18":45},"f":{"0":45,"1":0,"2":2},"b":{"0":[45],"1":[45],"2":[13,29],"3":[13,4],"4":[2,15],"5":[17,5]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":19,"seen":{"f:38:22:38:Infinity":0,"b:41:12:41:Infinity":0,"s:43:64:43:Infinity":0,"b:43:57:43:64":1,"s:44:21:44:Infinity":1,"s:45:20:45:Infinity":2,"f:45:20:45:37":1,"s:45:37:45:57":3,"s:46:2:73:Infinity":4,"s:47:21:54:Infinity":5,"b:56:4:59:Infinity:undefined:undefined:undefined:undefined":2,"s:56:4:59:Infinity":6,"s:57:34:57:Infinity":7,"s:58:6:58:Infinity":8,"s:61:4:61:Infinity":9,"s:63:29:63:Infinity":10,"b:63:61:63:86:63:86:63:Infinity":3,"b:64:4:69:Infinity:undefined:undefined:undefined:undefined":4,"s:64:4:69:Infinity":11,"b:64:8:64:32:64:32:64:57":5,"s:65:20:65:Infinity":12,"s:66:6:66:Infinity":13,"s:67:6:67:Infinity":14,"f:67:16:67:25":2,"s:67:37:67:63":15,"s:68:6:68:Infinity":16,"s:70:4:70:Infinity":17,"s:72:4:72:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/retry.ts","statementMap":{"0":{"start":{"line":21,"column":28},"end":{"line":21,"column":null}},"1":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":36},"end":{"line":36,"column":null}},"3":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":48,"column":25},"end":{"line":48,"column":null}},"6":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"8":{"start":{"line":50,"column":61},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"10":{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},"11":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"12":{"start":{"line":57,"column":57},"end":{"line":57,"column":84}},"13":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"14":{"start":{"line":59,"column":30},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"16":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"17":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"18":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}}},"fnMap":{"0":{"name":"calculateRetryDelay","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":null}},"loc":{"start":{"line":46,"column":10},"end":{"line":52,"column":null}},"line":46},"1":{"name":"isTransientFetchError","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":38}},"loc":{"start":{"line":55,"column":63},"end":{"line":61,"column":null}},"line":55},"2":{"name":"(anonymous_2)","decl":{"start":{"line":57,"column":39},"end":{"line":57,"column":45}},"loc":{"start":{"line":57,"column":57},"end":{"line":57,"column":84}},"line":57},"3":{"name":"isRetryableError","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":33}},"loc":{"start":{"line":64,"column":58},"end":{"line":69,"column":null}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"1":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"2":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":61}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":41}},{"start":{"line":50,"column":41},"end":{"line":50,"column":61}}],"line":50},"3":{"loc":{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":56},"4":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65}},"s":{"0":20,"1":20,"2":20,"3":17,"4":17,"5":12,"6":5,"7":5,"8":3,"9":2,"10":7,"11":3,"12":9,"13":4,"14":4,"15":0,"16":5,"17":3,"18":2},"f":{"0":17,"1":7,"2":9,"3":5},"b":{"0":[12,5],"1":[3,2],"2":[5,4],"3":[3,4],"4":[4,0],"5":[3,2]},"meta":{"lastBranch":6,"lastFunction":4,"lastStatement":19,"seen":{"s:21:28:21:Infinity":0,"s:29:34:29:Infinity":1,"s:31:36:36:Infinity":2,"f:43:16:43:Infinity":0,"s:47:22:47:Infinity":3,"b:48:2:48:Infinity:undefined:undefined:undefined:undefined":0,"s:48:2:48:Infinity":4,"s:48:25:48:Infinity":5,"s:49:24:49:Infinity":6,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":1,"s:50:2:50:Infinity":7,"b:50:6:50:41:50:41:50:61":2,"s:50:61:50:Infinity":8,"s:51:2:51:Infinity":9,"f:55:16:55:38":1,"b:56:2:58:Infinity:undefined:undefined:undefined:undefined":3,"s:56:2:58:Infinity":10,"s:57:4:57:Infinity":11,"f:57:39:57:45":2,"s:57:57:57:84":12,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":4,"s:59:2:59:Infinity":13,"s:59:30:59:Infinity":14,"s:60:2:60:Infinity":15,"f:64:16:64:33":3,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":5,"s:65:2:67:Infinity":16,"s:66:4:66:Infinity":17,"s:68:2:68:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/sdmx.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/imf/transport/sdmx.ts","statementMap":{"0":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"1":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":14},"end":{"line":44,"column":null}},"3":{"start":{"line":45,"column":42},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"5":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"6":{"start":{"line":51,"column":2},"end":{"line":56,"column":null}}},"fnMap":{"0":{"name":"sdmxFetch","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":41,"column":20},"end":{"line":57,"column":null}},"line":41}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"type":"cond-expr","locations":[{"start":{"line":43,"column":49},"end":{"line":43,"column":54}},{"start":{"line":43,"column":54},"end":{"line":43,"column":null}}],"line":43},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":48}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":4,"6":9},"f":{"0":9},"b":{"0":[8,1],"1":[4,5]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":7,"seen":{"f:38:22:38:Infinity":0,"s:42:21:42:Infinity":0,"s:43:20:43:Infinity":1,"b:43:49:43:54:43:54:43:Infinity":0,"s:44:14:44:Infinity":2,"s:45:42:47:Infinity":3,"b:48:2:50:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:50:Infinity":4,"s:49:4:49:Infinity":5,"s:51:2:56:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/auth.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/auth.ts","statementMap":{"0":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"1":{"start":{"line":39,"column":37},"end":{"line":39,"column":null}},"2":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"3":{"start":{"line":40,"column":42},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"5":{"start":{"line":43,"column":2},"end":{"line":59,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},"7":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"8":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":21},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":18},"end":{"line":49,"column":null}},"12":{"start":{"line":51,"column":25},"end":{"line":51,"column":null}},"13":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"14":{"start":{"line":53,"column":22},"end":{"line":53,"column":null}},"15":{"start":{"line":54,"column":25},"end":{"line":54,"column":null}},"16":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"17":{"start":{"line":55,"column":22},"end":{"line":55,"column":null}},"18":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"19":{"start":{"line":67,"column":46},"end":{"line":67,"column":null}},"20":{"start":{"line":79,"column":16},"end":{"line":79,"column":null}},"21":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}}},"fnMap":{"0":{"name":"getDefaultAuthToken","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":46}},"loc":{"start":{"line":38,"column":46},"end":{"line":61,"column":null}},"line":38},"1":{"name":"hasMcpGatewayApiKey","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":47}},"loc":{"start":{"line":78,"column":47},"end":{"line":81,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"2":{"loc":{"start":{"line":42,"column":21},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":56}},{"start":{"line":42,"column":56},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"5":{"loc":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"6":{"loc":{"start":{"line":80,"column":9},"end":{"line":80,"column":null}},"type":"binary-expr","locations":[{"start":{"line":80,"column":9},"end":{"line":80,"column":38}},{"start":{"line":80,"column":38},"end":{"line":80,"column":null}}],"line":80}},"s":{"0":40,"1":1,"2":39,"3":4,"4":35,"5":40,"6":40,"7":9,"8":9,"9":9,"10":9,"11":5,"12":3,"13":3,"14":9,"15":9,"16":9,"17":2,"18":28,"19":40,"20":39,"21":39},"f":{"0":40,"1":39},"b":{"0":[1,39],"1":[4,35],"2":[35,24],"3":[9,31],"4":[5,4],"5":[2,7],"6":[39,4]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":22,"seen":{"f:38:16:38:46":0,"b:39:2:39:Infinity:undefined:undefined:undefined:undefined":0,"s:39:2:39:Infinity":0,"s:39:37:39:Infinity":1,"b:40:2:40:Infinity:undefined:undefined:undefined:undefined":1,"s:40:2:40:Infinity":2,"s:40:42:40:Infinity":3,"s:42:21:42:Infinity":4,"b:42:21:42:56:42:56:42:Infinity":2,"s:43:2:59:Infinity":5,"b:44:4:56:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:56:Infinity":6,"s:45:18:45:Infinity":7,"s:47:22:47:Infinity":8,"s:48:21:48:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":4,"s:49:6:49:Infinity":10,"s:49:18:49:Infinity":11,"s:51:25:51:Infinity":12,"s:52:23:52:Infinity":13,"s:53:22:53:Infinity":14,"s:54:25:54:Infinity":15,"b:55:6:55:Infinity:undefined:undefined:undefined:undefined":5,"s:55:6:55:Infinity":16,"s:55:22:55:Infinity":17,"s:60:2:60:Infinity":18,"s:67:46:67:Infinity":19,"f:78:16:78:47":1,"s:79:16:79:Infinity":20,"s:80:2:80:Infinity":21,"b:80:9:80:38:80:38:80:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/defaults.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/defaults.ts","statementMap":{"0":{"start":{"line":13,"column":35},"end":{"line":13,"column":null}},"1":{"start":{"line":14,"column":27},"end":{"line":14,"column":null}},"2":{"start":{"line":20,"column":46},"end":{"line":20,"column":69}},"3":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}}},"fnMap":{"0":{"name":"getDefaultTimeout","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":44}},"loc":{"start":{"line":26,"column":44},"end":{"line":29,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":9},"end":{"line":28,"column":null}},"type":"cond-expr","locations":[{"start":{"line":28,"column":19},"end":{"line":28,"column":60}},{"start":{"line":28,"column":60},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":28,"column":19},"end":{"line":28,"column":60}},"type":"binary-expr","locations":[{"start":{"line":28,"column":19},"end":{"line":28,"column":50}},{"start":{"line":28,"column":50},"end":{"line":28,"column":60}}],"line":28}},"s":{"0":38,"1":38,"2":38,"3":135,"4":135},"f":{"0":135},"b":{"0":[2,133],"1":[2,1]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":5,"seen":{"s:13:35:13:Infinity":0,"s:14:27:14:Infinity":1,"s:20:46:20:69":2,"f:26:16:26:44":0,"s:27:17:27:Infinity":3,"s:28:2:28:Infinity":4,"b:28:19:28:60:28:60:28:Infinity":0,"b:28:19:28:50:28:50:28:60":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/lagradet-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/lagradet-fetch.ts","statementMap":{"0":{"start":{"line":34,"column":18},"end":{"line":34,"column":null}},"1":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":39},"end":{"line":36,"column":null}},"3":{"start":{"line":37,"column":34},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":43},"end":{"line":38,"column":null}},"5":{"start":{"line":39,"column":16},"end":{"line":39,"column":null}},"6":{"start":{"line":40,"column":15},"end":{"line":40,"column":null}},"7":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"9":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"10":{"start":{"line":61,"column":19},"end":{"line":61,"column":null}},"11":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"12":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"13":{"start":{"line":67,"column":35},"end":{"line":67,"column":null}},"14":{"start":{"line":68,"column":17},"end":{"line":68,"column":null}},"15":{"start":{"line":69,"column":2},"end":{"line":79,"column":null}},"16":{"start":{"line":70,"column":17},"end":{"line":70,"column":null}},"17":{"start":{"line":71,"column":18},"end":{"line":71,"column":null}},"18":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"19":{"start":{"line":72,"column":25},"end":{"line":72,"column":null}},"20":{"start":{"line":73,"column":21},"end":{"line":73,"column":null}},"21":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"22":{"start":{"line":74,"column":45},"end":{"line":74,"column":null}},"23":{"start":{"line":75,"column":4},"end":{"line":78,"column":null}},"24":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"25":{"start":{"line":84,"column":15},"end":{"line":84,"column":null}},"26":{"start":{"line":85,"column":35},"end":{"line":85,"column":null}},"27":{"start":{"line":86,"column":2},"end":{"line":91,"column":null}},"28":{"start":{"line":87,"column":16},"end":{"line":87,"column":null}},"29":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"30":{"start":{"line":88,"column":23},"end":{"line":88,"column":null}},"31":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"32":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"33":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"34":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"35":{"start":{"line":97,"column":20},"end":{"line":97,"column":null}},"36":{"start":{"line":98,"column":30},"end":{"line":98,"column":null}},"37":{"start":{"line":99,"column":22},"end":{"line":101,"column":null}},"38":{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},"39":{"start":{"line":104,"column":4},"end":{"line":112,"column":null}},"40":{"start":{"line":115,"column":18},"end":{"line":115,"column":null}},"41":{"start":{"line":116,"column":21},"end":{"line":116,"column":null}},"42":{"start":{"line":117,"column":16},"end":{"line":117,"column":null}},"43":{"start":{"line":117,"column":33},"end":{"line":117,"column":53}},"44":{"start":{"line":118,"column":2},"end":{"line":160,"column":null}},"45":{"start":{"line":119,"column":21},"end":{"line":125,"column":null}},"46":{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},"47":{"start":{"line":127,"column":6},"end":{"line":135,"column":null}},"48":{"start":{"line":137,"column":17},"end":{"line":137,"column":null}},"49":{"start":{"line":138,"column":20},"end":{"line":138,"column":null}},"50":{"start":{"line":139,"column":4},"end":{"line":147,"column":null}},"51":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"52":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"53":{"start":{"line":164,"column":2},"end":{"line":164,"column":null}},"54":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"55":{"start":{"line":166,"column":2},"end":{"line":166,"column":null}},"56":{"start":{"line":170,"column":33},"end":{"line":170,"column":null}},"57":{"start":{"line":171,"column":15},"end":{"line":171,"column":null}},"58":{"start":{"line":172,"column":16},"end":{"line":172,"column":null}},"59":{"start":{"line":173,"column":2},"end":{"line":188,"column":null}},"60":{"start":{"line":173,"column":15},"end":{"line":173,"column":18}},"61":{"start":{"line":174,"column":18},"end":{"line":174,"column":null}},"62":{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},"63":{"start":{"line":176,"column":6},"end":{"line":176,"column":null}},"64":{"start":{"line":177,"column":6},"end":{"line":177,"column":null}},"65":{"start":{"line":178,"column":6},"end":{"line":178,"column":null}},"66":{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},"67":{"start":{"line":181,"column":6},"end":{"line":181,"column":null}},"68":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"69":{"start":{"line":183,"column":6},"end":{"line":183,"column":null}},"70":{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},"71":{"start":{"line":186,"column":6},"end":{"line":186,"column":null}},"72":{"start":{"line":189,"column":2},"end":{"line":189,"column":null}},"73":{"start":{"line":193,"column":15},"end":{"line":193,"column":null}},"74":{"start":{"line":194,"column":17},"end":{"line":194,"column":null}},"75":{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},"76":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"77":{"start":{"line":198,"column":2},"end":{"line":198,"column":null}},"78":{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},"79":{"start":{"line":202,"column":2},"end":{"line":205,"column":null}},"80":{"start":{"line":203,"column":4},"end":{"line":203,"column":null}},"81":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}}},"fnMap":{"0":{"name":"stripHtml","decl":{"start":{"line":42,"column":9},"end":{"line":42,"column":19}},"loc":{"start":{"line":42,"column":41},"end":{"line":44,"column":null}},"line":42},"1":{"name":"escapeRegExp","decl":{"start":{"line":46,"column":9},"end":{"line":46,"column":22}},"loc":{"start":{"line":46,"column":45},"end":{"line":48,"column":null}},"line":46},"2":{"name":"referenceMatches","decl":{"start":{"line":55,"column":9},"end":{"line":55,"column":26}},"loc":{"start":{"line":55,"column":72},"end":{"line":64,"column":null}},"line":55},"3":{"name":"extractLagradetMatches","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":39}},"loc":{"start":{"line":66,"column":126},"end":{"line":81,"column":null}},"line":66},"4":{"name":"dedupeMatches","decl":{"start":{"line":83,"column":9},"end":{"line":83,"column":23}},"loc":{"start":{"line":83,"column":75},"end":{"line":93,"column":null}},"line":83},"5":{"name":"fetchLagradetStatus","decl":{"start":{"line":95,"column":22},"end":{"line":95,"column":42}},"loc":{"start":{"line":95,"column":127},"end":{"line":161,"column":null}},"line":95},"6":{"name":"(anonymous_6)","decl":{"start":{"line":117,"column":16},"end":{"line":117,"column":33}},"loc":{"start":{"line":117,"column":33},"end":{"line":117,"column":53}},"line":117},"7":{"name":"persistLagradetStatus","decl":{"start":{"line":163,"column":16},"end":{"line":163,"column":38}},"loc":{"start":{"line":163,"column":108},"end":{"line":167,"column":null}},"line":163},"8":{"name":"parseArgs","decl":{"start":{"line":169,"column":9},"end":{"line":169,"column":19}},"loc":{"start":{"line":169,"column":108},"end":{"line":190,"column":null}},"line":169},"9":{"name":"main","decl":{"start":{"line":192,"column":15},"end":{"line":192,"column":37}},"loc":{"start":{"line":192,"column":37},"end":{"line":199,"column":null}},"line":192},"10":{"name":"(anonymous_10)","decl":{"start":{"line":202,"column":9},"end":{"line":202,"column":16}},"loc":{"start":{"line":202,"column":35},"end":{"line":205,"column":3}},"line":202}},"branchMap":{"0":{"loc":{"start":{"line":66,"column":72},"end":{"line":66,"column":126}},"type":"default-arg","locations":[{"start":{"line":66,"column":82},"end":{"line":66,"column":126}}],"line":66},"1":{"loc":{"start":{"line":71,"column":28},"end":{"line":71,"column":42}},"type":"binary-expr","locations":[{"start":{"line":71,"column":28},"end":{"line":71,"column":40}},{"start":{"line":71,"column":40},"end":{"line":71,"column":42}}],"line":71},"2":{"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"3":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":25}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":17}},{"start":{"line":72,"column":17},"end":{"line":72,"column":25}}],"line":72},"4":{"loc":{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74},"5":{"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":88},"6":{"loc":{"start":{"line":95,"column":68},"end":{"line":95,"column":127}},"type":"default-arg","locations":[{"start":{"line":95,"column":98},"end":{"line":95,"column":127}}],"line":95},"7":{"loc":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":96,"column":18},"end":{"line":96,"column":36}},{"start":{"line":96,"column":36},"end":{"line":96,"column":null}}],"line":96},"8":{"loc":{"start":{"line":97,"column":20},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":20},"end":{"line":97,"column":38}},{"start":{"line":97,"column":38},"end":{"line":97,"column":null}}],"line":97},"9":{"loc":{"start":{"line":98,"column":30},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":30},"end":{"line":98,"column":51}},{"start":{"line":98,"column":51},"end":{"line":98,"column":null}}],"line":98},"10":{"loc":{"start":{"line":99,"column":22},"end":{"line":101,"column":null}},"type":"cond-expr","locations":[{"start":{"line":100,"column":6},"end":{"line":100,"column":null}},{"start":{"line":101,"column":6},"end":{"line":101,"column":null}}],"line":99},"11":{"loc":{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":103},"12":{"loc":{"start":{"line":115,"column":18},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":18},"end":{"line":115,"column":36}},{"start":{"line":115,"column":36},"end":{"line":115,"column":null}}],"line":115},"13":{"loc":{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":126},"14":{"loc":{"start":{"line":144,"column":14},"end":{"line":144,"column":null}},"type":"cond-expr","locations":[{"start":{"line":144,"column":35},"end":{"line":144,"column":45}},{"start":{"line":144,"column":45},"end":{"line":144,"column":null}}],"line":144},"15":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":33},"end":{"line":146,"column":108}},{"start":{"line":146,"column":108},"end":{"line":146,"column":null}}],"line":146},"16":{"loc":{"start":{"line":156,"column":13},"end":{"line":156,"column":null}},"type":"cond-expr","locations":[{"start":{"line":156,"column":38},"end":{"line":156,"column":54}},{"start":{"line":156,"column":54},"end":{"line":156,"column":null}}],"line":156},"17":{"loc":{"start":{"line":163,"column":62},"end":{"line":163,"column":108}},"type":"default-arg","locations":[{"start":{"line":163,"column":75},"end":{"line":163,"column":108}}],"line":163},"18":{"loc":{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":175},"19":{"loc":{"start":{"line":176,"column":18},"end":{"line":176,"column":null}},"type":"binary-expr","locations":[{"start":{"line":176,"column":18},"end":{"line":176,"column":33}},{"start":{"line":176,"column":33},"end":{"line":176,"column":null}}],"line":176},"20":{"loc":{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":4},"end":{"line":184,"column":null}},{"start":{},"end":{}}],"line":180},"21":{"loc":{"start":{"line":181,"column":15},"end":{"line":181,"column":null}},"type":"binary-expr","locations":[{"start":{"line":181,"column":15},"end":{"line":181,"column":30}},{"start":{"line":181,"column":30},"end":{"line":181,"column":null}}],"line":181},"22":{"loc":{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":185,"column":4},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":185},"23":{"loc":{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":195,"column":2},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":195},"24":{"loc":{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},"type":"if","locations":[{"start":{"line":201,"column":0},"end":{"line":206,"column":null}},{"start":{},"end":{}}],"line":201},"25":{"loc":{"start":{"line":201,"column":66},"end":{"line":201,"column":87}},"type":"binary-expr","locations":[{"start":{"line":201,"column":66},"end":{"line":201,"column":85}},{"start":{"line":201,"column":85},"end":{"line":201,"column":87}}],"line":201},"26":{"loc":{"start":{"line":203,"column":37},"end":{"line":203,"column":93}},"type":"cond-expr","locations":[{"start":{"line":203,"column":62},"end":{"line":203,"column":78}},{"start":{"line":203,"column":78},"end":{"line":203,"column":93}}],"line":203}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":4,"8":4,"9":4,"10":4,"11":4,"12":4,"13":2,"14":2,"15":2,"16":4,"17":4,"18":4,"19":0,"20":4,"21":4,"22":3,"23":1,"24":2,"25":2,"26":2,"27":2,"28":1,"29":1,"30":0,"31":1,"32":1,"33":2,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":0,"41":1,"42":1,"43":0,"44":1,"45":1,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":1,"79":0,"80":0,"81":0},"f":{"0":4,"1":4,"2":4,"3":2,"4":2,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[2],"1":[4,0],"2":[0,4],"3":[4,4],"4":[3,1],"5":[0,1],"6":[1],"7":[1,1],"8":[1,1],"9":[1,1],"10":[0,1],"11":[1,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0],"18":[0,0],"19":[0,0],"20":[0,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[0,1],"25":[1,0],"26":[0,0]},"meta":{"lastBranch":27,"lastFunction":11,"lastStatement":82,"seen":{"s:34:18:34:Infinity":0,"s:35:18:35:Infinity":1,"s:36:39:36:Infinity":2,"s:37:34:37:Infinity":3,"s:38:43:38:Infinity":4,"s:39:16:39:Infinity":5,"s:40:15:40:Infinity":6,"f:42:9:42:19":0,"s:43:2:43:Infinity":7,"f:46:9:46:22":1,"s:47:2:47:Infinity":8,"f:55:9:55:26":2,"s:60:18:60:Infinity":9,"s:61:19:61:Infinity":10,"s:62:19:62:Infinity":11,"s:63:2:63:Infinity":12,"f:66:16:66:39":3,"b:66:82:66:126":0,"s:67:35:67:Infinity":13,"s:68:17:68:Infinity":14,"s:69:2:79:Infinity":15,"s:70:17:70:Infinity":16,"s:71:18:71:Infinity":17,"b:71:28:71:40:71:40:71:42":1,"b:72:4:72:Infinity:undefined:undefined:undefined:undefined":2,"s:72:4:72:Infinity":18,"b:72:8:72:17:72:17:72:25":3,"s:72:25:72:Infinity":19,"s:73:21:73:Infinity":20,"b:74:4:74:Infinity:undefined:undefined:undefined:undefined":4,"s:74:4:74:Infinity":21,"s:74:45:74:Infinity":22,"s:75:4:78:Infinity":23,"s:80:2:80:Infinity":24,"f:83:9:83:23":4,"s:84:15:84:Infinity":25,"s:85:35:85:Infinity":26,"s:86:2:91:Infinity":27,"s:87:16:87:Infinity":28,"b:88:4:88:Infinity:undefined:undefined:undefined:undefined":5,"s:88:4:88:Infinity":29,"s:88:23:88:Infinity":30,"s:89:4:89:Infinity":31,"s:90:4:90:Infinity":32,"s:92:2:92:Infinity":33,"f:95:22:95:42":5,"b:95:98:95:127":6,"s:96:18:96:Infinity":34,"b:96:18:96:36:96:36:96:Infinity":7,"s:97:20:97:Infinity":35,"b:97:20:97:38:97:38:97:Infinity":8,"s:98:30:98:Infinity":36,"b:98:30:98:51:98:51:98:Infinity":9,"s:99:22:101:Infinity":37,"b:100:6:100:Infinity:101:6:101:Infinity":10,"b:103:2:113:Infinity:undefined:undefined:undefined:undefined":11,"s:103:2:113:Infinity":38,"s:104:4:112:Infinity":39,"s:115:18:115:Infinity":40,"b:115:18:115:36:115:36:115:Infinity":12,"s:116:21:116:Infinity":41,"s:117:16:117:Infinity":42,"f:117:16:117:33":6,"s:117:33:117:53":43,"s:118:2:160:Infinity":44,"s:119:21:125:Infinity":45,"b:126:4:136:Infinity:undefined:undefined:undefined:undefined":13,"s:126:4:136:Infinity":46,"s:127:6:135:Infinity":47,"s:137:17:137:Infinity":48,"s:138:20:138:Infinity":49,"s:139:4:147:Infinity":50,"b:144:35:144:45:144:45:144:Infinity":14,"b:146:33:146:108:146:108:146:Infinity":15,"s:149:4:157:Infinity":51,"b:156:38:156:54:156:54:156:Infinity":16,"s:159:4:159:Infinity":52,"f:163:16:163:38":7,"b:163:75:163:108":17,"s:164:2:164:Infinity":53,"s:165:2:165:Infinity":54,"s:166:2:166:Infinity":55,"f:169:9:169:19":8,"s:170:33:170:Infinity":56,"s:171:15:171:Infinity":57,"s:172:16:172:Infinity":58,"s:173:2:188:Infinity":59,"s:173:15:173:18":60,"s:174:18:174:Infinity":61,"b:175:4:179:Infinity:undefined:undefined:undefined:undefined":18,"s:175:4:179:Infinity":62,"s:176:6:176:Infinity":63,"b:176:18:176:33:176:33:176:Infinity":19,"s:177:6:177:Infinity":64,"s:178:6:178:Infinity":65,"b:180:4:184:Infinity:undefined:undefined:undefined:undefined":20,"s:180:4:184:Infinity":66,"s:181:6:181:Infinity":67,"b:181:15:181:30:181:30:181:Infinity":21,"s:182:6:182:Infinity":68,"s:183:6:183:Infinity":69,"b:185:4:187:Infinity:undefined:undefined:undefined:undefined":22,"s:185:4:187:Infinity":70,"s:186:6:186:Infinity":71,"s:189:2:189:Infinity":72,"f:192:15:192:37":9,"s:193:15:193:Infinity":73,"s:194:17:194:Infinity":74,"b:195:2:197:Infinity:undefined:undefined:undefined:undefined":23,"s:195:2:197:Infinity":75,"s:196:4:196:Infinity":76,"s:198:2:198:Infinity":77,"b:201:0:206:Infinity:undefined:undefined:undefined:undefined":24,"s:201:0:206:Infinity":78,"b:201:66:201:85:201:85:201:87":25,"s:202:2:205:Infinity":79,"f:202:9:202:16":10,"s:203:4:203:Infinity":80,"b:203:62:203:78:203:78:203:93":26,"s:204:4:204:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/gateway-resolver.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/config/gateway-resolver.ts","statementMap":{"0":{"start":{"line":24,"column":33},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":35},"end":{"line":25,"column":null}},"2":{"start":{"line":33,"column":37},"end":{"line":33,"column":null}},"3":{"start":{"line":42,"column":18},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":44,"column":19},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"7":{"start":{"line":45,"column":47},"end":{"line":45,"column":null}},"8":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":61,"column":null}},"10":{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},"11":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"12":{"start":{"line":51,"column":22},"end":{"line":51,"column":null}},"13":{"start":{"line":52,"column":19},"end":{"line":52,"column":null}},"14":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"15":{"start":{"line":53,"column":48},"end":{"line":53,"column":null}},"16":{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},"17":{"start":{"line":55,"column":23},"end":{"line":55,"column":null}},"18":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"19":{"start":{"line":56,"column":51},"end":{"line":56,"column":null}},"20":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"21":{"start":{"line":72,"column":20},"end":{"line":72,"column":null}},"22":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"23":{"start":{"line":73,"column":17},"end":{"line":73,"column":null}},"24":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"25":{"start":{"line":75,"column":2},"end":{"line":84,"column":null}},"26":{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},"27":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"28":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"29":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"30":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"31":{"start":{"line":80,"column":59},"end":{"line":80,"column":null}},"32":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"33":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"34":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"35":{"start":{"line":114,"column":29},"end":{"line":114,"column":null}},"36":{"start":{"line":115,"column":21},"end":{"line":115,"column":null}},"37":{"start":{"line":116,"column":2},"end":{"line":127,"column":null}},"38":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"39":{"start":{"line":117,"column":36},"end":{"line":117,"column":null}},"40":{"start":{"line":118,"column":16},"end":{"line":118,"column":null}},"41":{"start":{"line":119,"column":20},"end":{"line":119,"column":null}},"42":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"43":{"start":{"line":120,"column":29},"end":{"line":120,"column":null}},"44":{"start":{"line":121,"column":23},"end":{"line":121,"column":null}},"45":{"start":{"line":122,"column":21},"end":{"line":122,"column":null}},"46":{"start":{"line":123,"column":20},"end":{"line":123,"column":null}},"47":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"48":{"start":{"line":124,"column":36},"end":{"line":124,"column":null}},"49":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"50":{"start":{"line":140,"column":19},"end":{"line":140,"column":null}},"51":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"52":{"start":{"line":141,"column":16},"end":{"line":141,"column":null}},"53":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"54":{"start":{"line":142,"column":28},"end":{"line":142,"column":null}},"55":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}}},"fnMap":{"0":{"name":"getAwfGatewayPort","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":44}},"loc":{"start":{"line":41,"column":44},"end":{"line":63,"column":null}},"line":41},"1":{"name":"getAwfGatewayDomain","decl":{"start":{"line":71,"column":16},"end":{"line":71,"column":46}},"loc":{"start":{"line":71,"column":46},"end":{"line":86,"column":null}},"line":71},"2":{"name":"buildAwfGatewayUrl","decl":{"start":{"line":92,"column":16},"end":{"line":92,"column":35}},"loc":{"start":{"line":92,"column":63},"end":{"line":94,"column":null}},"line":92},"3":{"name":"isAwfGatewayActive","decl":{"start":{"line":113,"column":16},"end":{"line":113,"column":46}},"loc":{"start":{"line":113,"column":46},"end":{"line":129,"column":null}},"line":113},"4":{"name":"getDefaultMcpServerUrl","decl":{"start":{"line":139,"column":16},"end":{"line":139,"column":49}},"loc":{"start":{"line":139,"column":49},"end":{"line":144,"column":null}},"line":139}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"2":{"loc":{"start":{"line":45,"column":8},"end":{"line":45,"column":47}},"type":"binary-expr","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":35}},{"start":{"line":45,"column":35},"end":{"line":45,"column":47}}],"line":45},"3":{"loc":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":21},"end":{"line":47,"column":56}},{"start":{"line":47,"column":56},"end":{"line":47,"column":null}}],"line":47},"4":{"loc":{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":49},"5":{"loc":{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"6":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":48}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":38}},{"start":{"line":53,"column":38},"end":{"line":53,"column":48}}],"line":53},"7":{"loc":{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":6},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":54},"8":{"loc":{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"9":{"loc":{"start":{"line":56,"column":12},"end":{"line":56,"column":51}},"type":"binary-expr","locations":[{"start":{"line":56,"column":12},"end":{"line":56,"column":39}},{"start":{"line":56,"column":39},"end":{"line":56,"column":51}}],"line":56},"10":{"loc":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"11":{"loc":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":21},"end":{"line":74,"column":56}},{"start":{"line":74,"column":56},"end":{"line":74,"column":null}}],"line":74},"12":{"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":76},"13":{"loc":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"14":{"loc":{"start":{"line":80,"column":10},"end":{"line":80,"column":59}},"type":"binary-expr","locations":[{"start":{"line":80,"column":10},"end":{"line":80,"column":40}},{"start":{"line":80,"column":40},"end":{"line":80,"column":59}}],"line":80},"15":{"loc":{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"16":{"loc":{"start":{"line":115,"column":21},"end":{"line":115,"column":null}},"type":"binary-expr","locations":[{"start":{"line":115,"column":21},"end":{"line":115,"column":56}},{"start":{"line":115,"column":56},"end":{"line":115,"column":null}}],"line":115},"17":{"loc":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":117},"18":{"loc":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":120},"19":{"loc":{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":124},"20":{"loc":{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"21":{"loc":{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":142}},"s":{"0":38,"1":38,"2":38,"3":10,"4":10,"5":1,"6":1,"7":1,"8":9,"9":10,"10":10,"11":7,"12":7,"13":7,"14":7,"15":3,"16":4,"17":0,"18":0,"19":0,"20":6,"21":10,"22":10,"23":0,"24":10,"25":10,"26":10,"27":7,"28":7,"29":7,"30":7,"31":3,"32":7,"33":10,"34":37,"35":3,"36":34,"37":37,"38":37,"39":25,"40":9,"41":9,"42":9,"43":5,"44":3,"45":3,"46":37,"47":37,"48":2,"49":2,"50":38,"51":38,"52":1,"53":37,"54":37,"55":27},"f":{"0":10,"1":10,"2":10,"3":37,"4":38},"b":{"0":[1,9],"1":[1,0],"2":[1,1],"3":[9,2],"4":[7,3],"5":[3,4],"6":[7,3],"7":[0,4],"8":[0,0],"9":[0,0],"10":[0,10],"11":[10,3],"12":[7,3],"13":[3,4],"14":[7,3],"15":[3,34],"16":[34,23],"17":[25,12],"18":[5,4],"19":[2,35],"20":[1,37],"21":[10,27]},"meta":{"lastBranch":22,"lastFunction":5,"lastStatement":56,"seen":{"s:24:33:24:Infinity":0,"s:25:35:25:Infinity":1,"s:33:37:33:Infinity":2,"f:41:16:41:44":0,"s:42:18:42:Infinity":3,"b:43:2:46:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:46:Infinity":4,"s:44:19:44:Infinity":5,"b:45:4:45:Infinity:undefined:undefined:undefined:undefined":1,"s:45:4:45:Infinity":6,"b:45:8:45:35:45:35:45:47":2,"s:45:47:45:Infinity":7,"s:47:21:47:Infinity":8,"b:47:21:47:56:47:56:47:Infinity":3,"s:48:2:61:Infinity":9,"b:49:4:58:Infinity:undefined:undefined:undefined:undefined":4,"s:49:4:58:Infinity":10,"s:50:18:50:Infinity":11,"s:51:22:51:Infinity":12,"s:52:19:52:Infinity":13,"b:53:6:53:Infinity:undefined:undefined:undefined:undefined":5,"s:53:6:53:Infinity":14,"b:53:10:53:38:53:38:53:48":6,"s:53:48:53:Infinity":15,"b:54:6:57:Infinity:undefined:undefined:undefined:undefined":7,"s:54:6:57:Infinity":16,"s:55:23:55:Infinity":17,"b:56:8:56:Infinity:undefined:undefined:undefined:undefined":8,"s:56:8:56:Infinity":18,"b:56:12:56:39:56:39:56:51":9,"s:56:51:56:Infinity":19,"s:62:2:62:Infinity":20,"f:71:16:71:46":1,"s:72:20:72:Infinity":21,"b:73:2:73:Infinity:undefined:undefined:undefined:undefined":10,"s:73:2:73:Infinity":22,"s:73:17:73:Infinity":23,"s:74:21:74:Infinity":24,"b:74:21:74:56:74:56:74:Infinity":11,"s:75:2:84:Infinity":25,"b:76:4:81:Infinity:undefined:undefined:undefined:undefined":12,"s:76:4:81:Infinity":26,"s:77:18:77:Infinity":27,"s:78:22:78:Infinity":28,"s:79:21:79:Infinity":29,"b:80:6:80:Infinity:undefined:undefined:undefined:undefined":13,"s:80:6:80:Infinity":30,"b:80:10:80:40:80:40:80:59":14,"s:80:59:80:Infinity":31,"s:85:2:85:Infinity":32,"f:92:16:92:35":2,"s:93:2:93:Infinity":33,"f:113:16:113:46":3,"b:114:2:114:Infinity:undefined:undefined:undefined:undefined":15,"s:114:2:114:Infinity":34,"s:114:29:114:Infinity":35,"s:115:21:115:Infinity":36,"b:115:21:115:56:115:56:115:Infinity":16,"s:116:2:127:Infinity":37,"b:117:4:117:Infinity:undefined:undefined:undefined:undefined":17,"s:117:4:117:Infinity":38,"s:117:36:117:Infinity":39,"s:118:16:118:Infinity":40,"s:119:20:119:Infinity":41,"b:120:4:120:Infinity:undefined:undefined:undefined:undefined":18,"s:120:4:120:Infinity":42,"s:120:29:120:Infinity":43,"s:121:23:121:Infinity":44,"s:122:21:122:Infinity":45,"s:123:20:123:Infinity":46,"b:124:4:124:Infinity:undefined:undefined:undefined:undefined":19,"s:124:4:124:Infinity":47,"s:124:36:124:Infinity":48,"s:128:2:128:Infinity":49,"f:139:16:139:49":4,"s:140:19:140:Infinity":50,"b:141:2:141:Infinity:undefined:undefined:undefined:undefined":20,"s:141:2:141:Infinity":51,"s:141:16:141:Infinity":52,"b:142:2:142:Infinity:undefined:undefined:undefined:undefined":21,"s:142:2:142:Infinity":53,"s:142:28:142:Infinity":54,"s:143:2:143:Infinity":55}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/coverage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/coverage.ts","statementMap":{"0":{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},"1":{"start":{"line":11,"column":33},"end":{"line":11,"column":null}},"2":{"start":{"line":12,"column":18},"end":{"line":12,"column":null}},"3":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"4":{"start":{"line":20,"column":21},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":2},"end":{"line":31,"column":null}},"6":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"7":{"start":{"line":29,"column":6},"end":{"line":29,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"9":{"start":{"line":39,"column":24},"end":{"line":39,"column":null}},"10":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"11":{"start":{"line":40,"column":39},"end":{"line":40,"column":104}},"12":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"13":{"start":{"line":56,"column":38},"end":{"line":56,"column":null}},"14":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"15":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"16":{"start":{"line":66,"column":18},"end":{"line":68,"column":null}},"17":{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},"18":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"19":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"20":{"start":{"line":90,"column":2},"end":{"line":100,"column":null}},"21":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"asCleanString","decl":{"start":{"line":10,"column":9},"end":{"line":10,"column":23}},"loc":{"start":{"line":10,"column":47},"end":{"line":14,"column":null}},"line":10},"1":{"name":"extractDocumentDate","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":36}},"loc":{"start":{"line":19,"column":84},"end":{"line":33,"column":null}},"line":19},"2":{"name":"hasSubstantiveFullText","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":39}},"loc":{"start":{"line":38,"column":81},"end":{"line":41,"column":null}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":40,"column":23},"end":{"line":40,"column":29}},"loc":{"start":{"line":40,"column":39},"end":{"line":40,"column":104}},"line":40},"4":{"name":"inferDocumentCoverageState","decl":{"start":{"line":52,"column":16},"end":{"line":52,"column":null}},"loc":{"start":{"line":55,"column":20},"end":{"line":75,"column":null}},"line":55},"5":{"name":"buildMcpProvenance","decl":{"start":{"line":80,"column":16},"end":{"line":80,"column":35}},"loc":{"start":{"line":89,"column":18},"end":{"line":101,"column":null}},"line":89},"6":{"name":"attachCoverageMetadata","decl":{"start":{"line":106,"column":16},"end":{"line":106,"column":null}},"loc":{"start":{"line":113,"column":2},"end":{"line":122,"column":null}},"line":113}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},"type":"if","locations":[{"start":{"line":11,"column":2},"end":{"line":11,"column":null}},{"start":{},"end":{}}],"line":11},"1":{"loc":{"start":{"line":13,"column":9},"end":{"line":13,"column":null}},"type":"cond-expr","locations":[{"start":{"line":13,"column":40},"end":{"line":13,"column":45}},{"start":{"line":13,"column":45},"end":{"line":13,"column":null}}],"line":13},"2":{"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"3":{"loc":{"start":{"line":28,"column":8},"end":{"line":28,"column":72}},"type":"binary-expr","locations":[{"start":{"line":28,"column":8},"end":{"line":28,"column":41}},{"start":{"line":28,"column":41},"end":{"line":28,"column":72}}],"line":28},"4":{"loc":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"type":"default-arg","locations":[{"start":{"line":54,"column":76},"end":{"line":54,"column":null}}],"line":54},"5":{"loc":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56},"6":{"loc":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":24},"end":{"line":58,"column":63}},{"start":{"line":58,"column":63},"end":{"line":58,"column":null}}],"line":58},"7":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":21}},{"start":{"line":67,"column":21},"end":{"line":67,"column":37}},{"start":{"line":67,"column":37},"end":{"line":67,"column":null}}],"line":67},"8":{"loc":{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":70},"9":{"loc":{"start":{"line":70,"column":6},"end":{"line":70,"column":44}},"type":"binary-expr","locations":[{"start":{"line":70,"column":6},"end":{"line":70,"column":35}},{"start":{"line":70,"column":35},"end":{"line":70,"column":44}}],"line":70},"10":{"loc":{"start":{"line":97,"column":15},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":15},"end":{"line":97,"column":36}},{"start":{"line":97,"column":36},"end":{"line":97,"column":null}}],"line":97},"11":{"loc":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":17},"end":{"line":98,"column":40}},{"start":{"line":98,"column":40},"end":{"line":98,"column":null}}],"line":98},"12":{"loc":{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},"type":"cond-expr","locations":[{"start":{"line":99,"column":56},"end":{"line":99,"column":87}},{"start":{"line":99,"column":87},"end":{"line":99,"column":null}}],"line":99},"13":{"loc":{"start":{"line":99,"column":8},"end":{"line":99,"column":56}},"type":"binary-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":27}},{"start":{"line":99,"column":27},"end":{"line":99,"column":56}}],"line":99},"14":{"loc":{"start":{"line":118,"column":8},"end":{"line":120,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":null}},{"start":{"line":120,"column":8},"end":{"line":120,"column":null}}],"line":118},"15":{"loc":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"type":"binary-expr","locations":[{"start":{"line":118,"column":8},"end":{"line":118,"column":30}},{"start":{"line":118,"column":30},"end":{"line":118,"column":null}}],"line":118}},"s":{"0":247,"1":219,"2":28,"3":28,"4":49,"5":49,"6":81,"7":41,"8":8,"9":68,"10":68,"11":247,"12":68,"13":19,"14":49,"15":68,"16":68,"17":68,"18":1,"19":48,"20":112,"21":34},"f":{"0":247,"1":49,"2":68,"3":247,"4":68,"5":112,"6":34},"b":{"0":[219,28],"1":[2,26],"2":[41,40],"3":[81,41],"4":[68],"5":[19,49],"6":[49,30],"7":[68,19,19],"8":[1,67],"9":[68,19],"10":[112,111],"11":[112,112],"12":[1,111],"13":[112,1],"14":[0,34],"15":[34,0]},"meta":{"lastBranch":16,"lastFunction":7,"lastStatement":22,"seen":{"f:10:9:10:23":0,"b:11:2:11:Infinity:undefined:undefined:undefined:undefined":0,"s:11:2:11:Infinity":0,"s:11:33:11:Infinity":1,"s:12:18:12:Infinity":2,"s:13:2:13:Infinity":3,"b:13:40:13:45:13:45:13:Infinity":1,"f:19:16:19:36":1,"s:20:21:26:Infinity":4,"s:27:2:31:Infinity":5,"b:28:4:30:Infinity:undefined:undefined:undefined:undefined":2,"s:28:4:30:Infinity":6,"b:28:8:28:41:28:41:28:72":3,"s:29:6:29:Infinity":7,"s:32:2:32:Infinity":8,"f:38:16:38:39":2,"s:39:24:39:Infinity":9,"s:40:2:40:Infinity":10,"f:40:23:40:29":3,"s:40:39:40:104":11,"f:52:16:52:Infinity":4,"b:54:76:54:Infinity":4,"b:56:2:56:Infinity:undefined:undefined:undefined:undefined":5,"s:56:2:56:Infinity":12,"s:56:38:56:Infinity":13,"s:58:24:58:Infinity":14,"b:58:24:58:63:58:63:58:Infinity":6,"s:59:23:59:Infinity":15,"s:66:18:68:Infinity":16,"b:67:4:67:21:67:21:67:37:67:37:67:Infinity":7,"b:70:2:72:Infinity:undefined:undefined:undefined:undefined":8,"s:70:2:72:Infinity":17,"b:70:6:70:35:70:35:70:44":9,"s:71:4:71:Infinity":18,"s:74:2:74:Infinity":19,"f:80:16:80:35":5,"s:90:2:100:Infinity":20,"b:97:15:97:36:97:36:97:Infinity":10,"b:98:17:98:40:98:40:98:Infinity":11,"b:99:56:99:87:99:87:99:Infinity":12,"b:99:8:99:27:99:27:99:56":13,"f:106:16:106:Infinity":6,"s:114:2:121:Infinity":21,"b:119:8:119:Infinity:120:8:120:Infinity":14,"b:118:8:118:30:118:30:118:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/document-types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/document-types.ts","statementMap":{"0":{"start":{"line":16,"column":57},"end":{"line":36,"column":null}},"1":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"2":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"3":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":17},"end":{"line":57,"column":null}},"7":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"8":{"start":{"line":58,"column":23},"end":{"line":58,"column":null}},"9":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"10":{"start":{"line":59,"column":33},"end":{"line":59,"column":null}},"11":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}}},"fnMap":{"0":{"name":"normalizeDocumentType","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":38}},"loc":{"start":{"line":43,"column":74},"end":{"line":47,"column":null}},"line":43},"1":{"name":"annotateDocumentTypes","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":38}},"loc":{"start":{"line":55,"column":93},"end":{"line":61,"column":null}},"line":55}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":9},"end":{"line":46,"column":34}},{"start":{"line":46,"column":34},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":56,"column":53},"end":{"line":56,"column":69}},{"start":{"line":56,"column":69},"end":{"line":56,"column":null}}],"line":56},"3":{"loc":{"start":{"line":57,"column":17},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":53},"end":{"line":57,"column":69}},{"start":{"line":57,"column":69},"end":{"line":57,"column":null}}],"line":57},"4":{"loc":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"5":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"6":{"loc":{"start":{"line":59,"column":6},"end":{"line":59,"column":33}},"type":"binary-expr","locations":[{"start":{"line":59,"column":6},"end":{"line":59,"column":25}},{"start":{"line":59,"column":25},"end":{"line":59,"column":33}}],"line":59}},"s":{"0":32,"1":25,"2":4,"3":21,"4":21,"5":8,"6":8,"7":8,"8":7,"9":8,"10":1,"11":8},"f":{"0":25,"1":8},"b":{"0":[4,21],"1":[21,1],"2":[6,2],"3":[1,7],"4":[7,1],"5":[1,7],"6":[8,8]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":12,"seen":{"s:16:57:36:Infinity":0,"f:43:16:43:38":0,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:44:Infinity":1,"s:44:15:44:Infinity":2,"s:45:16:45:Infinity":3,"s:46:2:46:Infinity":4,"b:46:9:46:34:46:34:46:Infinity":1,"f:55:16:55:38":1,"s:56:17:56:Infinity":5,"b:56:53:56:69:56:69:56:Infinity":2,"s:57:17:57:Infinity":6,"b:57:53:57:69:57:69:57:Infinity":3,"b:58:2:58:Infinity:undefined:undefined:undefined:undefined":4,"s:58:2:58:Infinity":7,"s:58:23:58:Infinity":8,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":5,"s:59:2:59:Infinity":9,"b:59:6:59:25:59:25:59:33":6,"s:59:33:59:Infinity":10,"s:60:2:60:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/not-indexed.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/not-indexed.ts","statementMap":{"0":{"start":{"line":27,"column":42},"end":{"line":32,"column":null}},"1":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"2":{"start":{"line":43,"column":16},"end":{"line":43,"column":null}},"3":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"4":{"start":{"line":44,"column":40},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"7":{"start":{"line":46,"column":45},"end":{"line":46,"column":62}},"8":{"start":{"line":46,"column":65},"end":{"line":46,"column":null}},"9":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"10":{"start":{"line":50,"column":83},"end":{"line":50,"column":null}},"11":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}}},"fnMap":{"0":{"name":"classifyDocumentErrorAsNotIndexed","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":50}},"loc":{"start":{"line":42,"column":92},"end":{"line":52,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":46,"column":33},"end":{"line":46,"column":39}},"loc":{"start":{"line":46,"column":45},"end":{"line":46,"column":62}},"line":46}},"branchMap":{"0":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":43},"1":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"2":{"loc":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":46},"3":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"4":{"loc":{"start":{"line":50,"column":6},"end":{"line":50,"column":83}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":15}},{"start":{"line":50,"column":15},"end":{"line":50,"column":54}},{"start":{"line":50,"column":54},"end":{"line":50,"column":83}}],"line":50}},"s":{"0":35,"1":25,"2":1,"3":24,"4":10,"5":14,"6":14,"7":45,"8":6,"9":8,"10":4,"11":4},"f":{"0":25,"1":45},"b":{"0":[1,24],"1":[10,14],"2":[6,8],"3":[4,4],"4":[8,7,4]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":12,"seen":{"s:27:42:32:Infinity":0,"f:42:16:42:50":0,"b:43:2:43:Infinity:undefined:undefined:undefined:undefined":0,"s:43:2:43:Infinity":1,"s:43:16:43:Infinity":2,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":1,"s:44:2:44:Infinity":3,"s:44:40:44:Infinity":4,"s:45:16:45:Infinity":5,"b:46:2:46:Infinity:undefined:undefined:undefined:undefined":2,"s:46:2:46:Infinity":6,"f:46:33:46:39":1,"s:46:45:46:62":7,"s:46:65:46:Infinity":8,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":3,"s:50:2:50:Infinity":9,"b:50:6:50:15:50:15:50:54:50:54:50:83":4,"s:50:83:50:Infinity":10,"s:51:2:51:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/transport.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/error-classification/transport.ts","statementMap":{"0":{"start":{"line":18,"column":34},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":36},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:34:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/calendar.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/calendar.ts","statementMap":{"0":{"start":{"line":30,"column":42},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"2":{"start":{"line":31,"column":11},"end":{"line":31,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":32,"column":11},"end":{"line":32,"column":null}},"5":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},"7":{"start":{"line":37,"column":22},"end":{"line":37,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":40,"column":null}},"9":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"fetchCalendarEvents","decl":{"start":{"line":23,"column":22},"end":{"line":23,"column":null}},"loc":{"start":{"line":29,"column":22},"end":{"line":44,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"default-arg","locations":[{"start":{"line":27,"column":23},"end":{"line":27,"column":null}}],"line":27},"1":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":23},"end":{"line":28,"column":null}}],"line":28},"2":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},{"start":{},"end":{}}],"line":31},"3":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"4":{"loc":{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":36},"5":{"loc":{"start":{"line":39,"column":39},"end":{"line":39,"column":null}},"type":"cond-expr","locations":[{"start":{"line":39,"column":71},"end":{"line":39,"column":83}},{"start":{"line":39,"column":83},"end":{"line":39,"column":null}}],"line":39},"6":{"loc":{"start":{"line":43,"column":10},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":10},"end":{"line":43,"column":34}},{"start":{"line":43,"column":34},"end":{"line":43,"column":56}},{"start":{"line":43,"column":56},"end":{"line":43,"column":null}}],"line":43}},"s":{"0":9,"1":9,"2":1,"3":9,"4":1,"5":9,"6":9,"7":3,"8":3,"9":6},"f":{"0":9},"b":{"0":[9],"1":[9],"2":[1,8],"3":[1,8],"4":[3,6],"5":[2,1],"6":[6,6,2]},"meta":{"lastBranch":7,"lastFunction":1,"lastStatement":10,"seen":{"f:23:22:23:Infinity":0,"b:27:23:27:Infinity":0,"b:28:23:28:Infinity":1,"s:30:42:30:Infinity":0,"b:31:2:31:Infinity:undefined:undefined:undefined:undefined":2,"s:31:2:31:Infinity":1,"s:31:11:31:Infinity":2,"b:32:2:32:Infinity:undefined:undefined:undefined:undefined":3,"s:32:2:32:Infinity":3,"s:32:11:32:Infinity":4,"s:34:19:34:Infinity":5,"b:36:2:41:Infinity:undefined:undefined:undefined:undefined":4,"s:36:2:41:Infinity":6,"s:37:22:37:Infinity":7,"s:38:4:40:Infinity":8,"b:39:71:39:83:39:83:39:Infinity":5,"s:43:2:43:Infinity":9,"b:43:10:43:34:43:34:43:56:43:56:43:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/index.ts","statementMap":{"0":{"start":{"line":31,"column":38},"end":{"line":31,"column":null}},"1":{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"6":{"start":{"line":56,"column":2},"end":{"line":56,"column":null}},"7":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"8":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"9":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"10":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"11":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"12":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"13":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}},"14":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"15":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"16":{"start":{"line":116,"column":2},"end":{"line":116,"column":null}},"17":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}},"18":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}}},"fnMap":{"0":{"name":"getDefaultClient","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":46}},"loc":{"start":{"line":34,"column":46},"end":{"line":39,"column":null}},"line":34},"1":{"name":"fetchCalendarEvents","decl":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"loc":{"start":{"line":43,"column":48},"end":{"line":45,"column":null}},"line":43},"2":{"name":"fetchCommitteeReports","decl":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"loc":{"start":{"line":49,"column":50},"end":{"line":51,"column":null}},"line":49},"3":{"name":"fetchPropositions","decl":{"start":{"line":53,"column":22},"end":{"line":53,"column":null}},"loc":{"start":{"line":55,"column":46},"end":{"line":57,"column":null}},"line":55},"4":{"name":"fetchMotions","decl":{"start":{"line":59,"column":22},"end":{"line":59,"column":null}},"loc":{"start":{"line":61,"column":41},"end":{"line":63,"column":null}},"line":61},"5":{"name":"searchDocuments","decl":{"start":{"line":65,"column":22},"end":{"line":65,"column":null}},"loc":{"start":{"line":67,"column":44},"end":{"line":69,"column":null}},"line":67},"6":{"name":"searchDocumentsWithDiagnostics","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":null}},"loc":{"start":{"line":73,"column":59},"end":{"line":75,"column":null}},"line":73},"7":{"name":"searchSpeeches","decl":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"loc":{"start":{"line":79,"column":43},"end":{"line":81,"column":null}},"line":79},"8":{"name":"fetchMPs","decl":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"loc":{"start":{"line":85,"column":37},"end":{"line":87,"column":null}},"line":85},"9":{"name":"fetchVotingRecords","decl":{"start":{"line":89,"column":22},"end":{"line":89,"column":null}},"loc":{"start":{"line":91,"column":47},"end":{"line":93,"column":null}},"line":91},"10":{"name":"fetchVotingRecordsWithDiagnostics","decl":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"loc":{"start":{"line":97,"column":62},"end":{"line":99,"column":null}},"line":97},"11":{"name":"fetchVotingGroup","decl":{"start":{"line":101,"column":22},"end":{"line":101,"column":null}},"loc":{"start":{"line":103,"column":45},"end":{"line":105,"column":null}},"line":103},"12":{"name":"fetchGovernmentDocuments","decl":{"start":{"line":107,"column":22},"end":{"line":107,"column":null}},"loc":{"start":{"line":109,"column":53},"end":{"line":111,"column":null}},"line":109},"13":{"name":"fetchDocumentDetails","decl":{"start":{"line":113,"column":22},"end":{"line":113,"column":null}},"loc":{"start":{"line":115,"column":49},"end":{"line":117,"column":null}},"line":115},"14":{"name":"fetchDocumentDetailsWithCoverage","decl":{"start":{"line":119,"column":22},"end":{"line":119,"column":null}},"loc":{"start":{"line":121,"column":61},"end":{"line":123,"column":null}},"line":121},"15":{"name":"enrichDocumentsWithContent","decl":{"start":{"line":125,"column":22},"end":{"line":125,"column":null}},"loc":{"start":{"line":127,"column":55},"end":{"line":129,"column":null}},"line":127}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":2},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":35}},"s":{"0":29,"1":28,"2":17,"3":28,"4":1,"5":1,"6":1,"7":1,"8":1,"9":0,"10":1,"11":1,"12":1,"13":0,"14":0,"15":1,"16":0,"17":0,"18":0},"f":{"0":28,"1":1,"2":1,"3":1,"4":1,"5":1,"6":0,"7":1,"8":1,"9":1,"10":0,"11":0,"12":1,"13":0,"14":0,"15":0},"b":{"0":[17,11]},"meta":{"lastBranch":1,"lastFunction":16,"lastStatement":19,"seen":{"s:31:38:31:Infinity":0,"f:34:16:34:46":0,"b:35:2:37:Infinity:undefined:undefined:undefined:undefined":0,"s:35:2:37:Infinity":1,"s:36:4:36:Infinity":2,"s:38:2:38:Infinity":3,"f:41:22:41:Infinity":1,"s:44:2:44:Infinity":4,"f:47:22:47:Infinity":2,"s:50:2:50:Infinity":5,"f:53:22:53:Infinity":3,"s:56:2:56:Infinity":6,"f:59:22:59:Infinity":4,"s:62:2:62:Infinity":7,"f:65:22:65:Infinity":5,"s:68:2:68:Infinity":8,"f:71:22:71:Infinity":6,"s:74:2:74:Infinity":9,"f:77:22:77:Infinity":7,"s:80:2:80:Infinity":10,"f:83:22:83:Infinity":8,"s:86:2:86:Infinity":11,"f:89:22:89:Infinity":9,"s:92:2:92:Infinity":12,"f:95:22:95:Infinity":10,"s:98:2:98:Infinity":13,"f:101:22:101:Infinity":11,"s:104:2:104:Infinity":14,"f:107:22:107:Infinity":12,"s:110:2:110:Infinity":15,"f:113:22:113:Infinity":13,"s:116:2:116:Infinity":16,"f:119:22:119:Infinity":14,"s:122:2:122:Infinity":17,"f:125:22:125:Infinity":15,"s:128:2:128:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/documents.ts","statementMap":{"0":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"1":{"start":{"line":43,"column":19},"end":{"line":46,"column":null}},"2":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"3":{"start":{"line":48,"column":22},"end":{"line":48,"column":null}},"4":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"5":{"start":{"line":50,"column":21},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":16},"end":{"line":65,"column":null}},"7":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"8":{"start":{"line":59,"column":24},"end":{"line":59,"column":null}},"9":{"start":{"line":60,"column":26},"end":{"line":63,"column":null}},"10":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"11":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"12":{"start":{"line":79,"column":19},"end":{"line":82,"column":null}},"13":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"14":{"start":{"line":91,"column":19},"end":{"line":94,"column":null}},"15":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"16":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"17":{"start":{"line":108,"column":2},"end":{"line":154,"column":null}},"18":{"start":{"line":109,"column":21},"end":{"line":109,"column":null}},"19":{"start":{"line":110,"column":26},"end":{"line":113,"column":null}},"20":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"21":{"start":{"line":115,"column":23},"end":{"line":122,"column":null}},"22":{"start":{"line":123,"column":4},"end":{"line":129,"column":null}},"23":{"start":{"line":131,"column":16},"end":{"line":131,"column":null}},"24":{"start":{"line":132,"column":27},"end":{"line":132,"column":null}},"25":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"26":{"start":{"line":133,"column":25},"end":{"line":133,"column":null}},"27":{"start":{"line":135,"column":26},"end":{"line":135,"column":null}},"28":{"start":{"line":136,"column":23},"end":{"line":143,"column":null}},"29":{"start":{"line":144,"column":4},"end":{"line":153,"column":null}},"30":{"start":{"line":162,"column":26},"end":{"line":162,"column":null}},"31":{"start":{"line":163,"column":38},"end":{"line":163,"column":null}},"32":{"start":{"line":165,"column":2},"end":{"line":222,"column":null}},"33":{"start":{"line":165,"column":15},"end":{"line":165,"column":18}},"34":{"start":{"line":166,"column":18},"end":{"line":166,"column":null}},"35":{"start":{"line":168,"column":25},"end":{"line":205,"column":null}},"36":{"start":{"line":170,"column":23},"end":{"line":170,"column":null}},"37":{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},"38":{"start":{"line":172,"column":10},"end":{"line":172,"column":null}},"39":{"start":{"line":173,"column":10},"end":{"line":173,"column":null}},"40":{"start":{"line":176,"column":8},"end":{"line":203,"column":null}},"41":{"start":{"line":177,"column":26},"end":{"line":177,"column":null}},"42":{"start":{"line":178,"column":30},"end":{"line":178,"column":null}},"43":{"start":{"line":179,"column":25},"end":{"line":181,"column":null}},"44":{"start":{"line":182,"column":24},"end":{"line":182,"column":null}},"45":{"start":{"line":184,"column":13},"end":{"line":188,"column":null}},"46":{"start":{"line":190,"column":10},"end":{"line":198,"column":null}},"47":{"start":{"line":200,"column":26},"end":{"line":200,"column":null}},"48":{"start":{"line":201,"column":10},"end":{"line":201,"column":null}},"49":{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},"50":{"start":{"line":207,"column":4},"end":{"line":217,"column":null}},"51":{"start":{"line":207,"column":19},"end":{"line":207,"column":22}},"52":{"start":{"line":208,"column":21},"end":{"line":208,"column":null}},"53":{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},"54":{"start":{"line":210,"column":8},"end":{"line":210,"column":null}},"55":{"start":{"line":212,"column":26},"end":{"line":212,"column":null}},"56":{"start":{"line":213,"column":28},"end":{"line":213,"column":null}},"57":{"start":{"line":214,"column":8},"end":{"line":214,"column":null}},"58":{"start":{"line":215,"column":8},"end":{"line":215,"column":null}},"59":{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},"60":{"start":{"line":220,"column":6},"end":{"line":220,"column":null}},"61":{"start":{"line":220,"column":43},"end":{"line":220,"column":67}},"62":{"start":{"line":224,"column":2},"end":{"line":224,"column":null}},"63":{"start":{"line":240,"column":2},"end":{"line":248,"column":null}},"64":{"start":{"line":241,"column":21},"end":{"line":243,"column":null}},"65":{"start":{"line":244,"column":4},"end":{"line":244,"column":null}},"66":{"start":{"line":246,"column":4},"end":{"line":246,"column":null}},"67":{"start":{"line":247,"column":4},"end":{"line":247,"column":null}},"68":{"start":{"line":261,"column":2},"end":{"line":261,"column":null}}},"fnMap":{"0":{"name":"searchDocuments","decl":{"start":{"line":32,"column":22},"end":{"line":32,"column":null}},"loc":{"start":{"line":35,"column":22},"end":{"line":37,"column":null}},"line":35},"1":{"name":"searchDocumentsWithDiagnostics","decl":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"loc":{"start":{"line":42,"column":53},"end":{"line":73,"column":null}},"line":42},"2":{"name":"(anonymous_2)","decl":{"start":{"line":57,"column":20},"end":{"line":57,"column":25}},"loc":{"start":{"line":57,"column":31},"end":{"line":65,"column":3}},"line":57},"3":{"name":"fetchGovernmentDocuments","decl":{"start":{"line":75,"column":22},"end":{"line":75,"column":null}},"loc":{"start":{"line":78,"column":22},"end":{"line":84,"column":null}},"line":78},"4":{"name":"fetchDocumentDetails","decl":{"start":{"line":86,"column":22},"end":{"line":86,"column":null}},"loc":{"start":{"line":90,"column":36},"end":{"line":96,"column":null}},"line":90},"5":{"name":"fetchDocumentDetailsWithCoverage","decl":{"start":{"line":98,"column":22},"end":{"line":98,"column":null}},"loc":{"start":{"line":106,"column":55},"end":{"line":155,"column":null}},"line":106},"6":{"name":"enrichDocumentsWithContent","decl":{"start":{"line":157,"column":22},"end":{"line":157,"column":null}},"loc":{"start":{"line":161,"column":30},"end":{"line":225,"column":null}},"line":161},"7":{"name":"(anonymous_7)","decl":{"start":{"line":169,"column":16},"end":{"line":169,"column":23}},"loc":{"start":{"line":169,"column":57},"end":{"line":204,"column":7}},"line":169},"8":{"name":"(anonymous_8)","decl":{"start":{"line":220,"column":16},"end":{"line":220,"column":31}},"loc":{"start":{"line":220,"column":43},"end":{"line":220,"column":67}},"line":220},"9":{"name":"fetchGovernmentDocumentContent","decl":{"start":{"line":236,"column":22},"end":{"line":236,"column":null}},"loc":{"start":{"line":239,"column":26},"end":{"line":249,"column":null}},"line":239},"10":{"name":"fetchExternalUrlContent","decl":{"start":{"line":257,"column":22},"end":{"line":257,"column":null}},"loc":{"start":{"line":260,"column":26},"end":{"line":262,"column":null}},"line":260}},"branchMap":{"0":{"loc":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":15},"end":{"line":47,"column":39}},{"start":{"line":47,"column":39},"end":{"line":47,"column":64}},{"start":{"line":47,"column":64},"end":{"line":47,"column":null}}],"line":47},"1":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":44},"end":{"line":49,"column":61}},{"start":{"line":49,"column":61},"end":{"line":49,"column":null}}],"line":49},"2":{"loc":{"start":{"line":83,"column":10},"end":{"line":83,"column":null}},"type":"binary-expr","locations":[{"start":{"line":83,"column":10},"end":{"line":83,"column":35}},{"start":{"line":83,"column":35},"end":{"line":83,"column":null}}],"line":83},"3":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"default-arg","locations":[{"start":{"line":89,"column":22},"end":{"line":89,"column":null}}],"line":89},"4":{"loc":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"type":"default-arg","locations":[{"start":{"line":101,"column":22},"end":{"line":101,"column":null}}],"line":101},"5":{"loc":{"start":{"line":102,"column":2},"end":{"line":105,"column":null}},"type":"default-arg","locations":[{"start":{"line":105,"column":6},"end":{"line":105,"column":null}}],"line":102},"6":{"loc":{"start":{"line":111,"column":21},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":21},"end":{"line":111,"column":46}},{"start":{"line":111,"column":46},"end":{"line":111,"column":null}}],"line":111},"7":{"loc":{"start":{"line":114,"column":24},"end":{"line":114,"column":null}},"type":"cond-expr","locations":[{"start":{"line":114,"column":59},"end":{"line":114,"column":63}},{"start":{"line":114,"column":63},"end":{"line":114,"column":null}}],"line":114},"8":{"loc":{"start":{"line":121,"column":17},"end":{"line":121,"column":null}},"type":"binary-expr","locations":[{"start":{"line":121,"column":17},"end":{"line":121,"column":38}},{"start":{"line":121,"column":38},"end":{"line":121,"column":null}}],"line":121},"9":{"loc":{"start":{"line":132,"column":61},"end":{"line":132,"column":80}},"type":"binary-expr","locations":[{"start":{"line":132,"column":61},"end":{"line":132,"column":76}},{"start":{"line":132,"column":76},"end":{"line":132,"column":80}}],"line":132},"10":{"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},{"start":{},"end":{}}],"line":133},"11":{"loc":{"start":{"line":142,"column":17},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":17},"end":{"line":142,"column":38}},{"start":{"line":142,"column":38},"end":{"line":142,"column":null}}],"line":142},"12":{"loc":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}},"type":"default-arg","locations":[{"start":{"line":160,"column":16},"end":{"line":160,"column":null}}],"line":160},"13":{"loc":{"start":{"line":170,"column":23},"end":{"line":170,"column":null}},"type":"binary-expr","locations":[{"start":{"line":170,"column":23},"end":{"line":170,"column":43}},{"start":{"line":170,"column":43},"end":{"line":170,"column":57}},{"start":{"line":170,"column":57},"end":{"line":170,"column":null}}],"line":170},"14":{"loc":{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},"type":"if","locations":[{"start":{"line":171,"column":8},"end":{"line":174,"column":null}},{"start":{},"end":{}}],"line":171},"15":{"loc":{"start":{"line":178,"column":30},"end":{"line":178,"column":null}},"type":"binary-expr","locations":[{"start":{"line":178,"column":30},"end":{"line":178,"column":55}},{"start":{"line":178,"column":55},"end":{"line":178,"column":null}}],"line":178},"16":{"loc":{"start":{"line":179,"column":25},"end":{"line":181,"column":null}},"type":"cond-expr","locations":[{"start":{"line":180,"column":14},"end":{"line":180,"column":null}},{"start":{"line":181,"column":14},"end":{"line":181,"column":null}}],"line":179},"17":{"loc":{"start":{"line":181,"column":14},"end":{"line":181,"column":null}},"type":"binary-expr","locations":[{"start":{"line":181,"column":14},"end":{"line":181,"column":37}},{"start":{"line":181,"column":37},"end":{"line":181,"column":59}},{"start":{"line":181,"column":59},"end":{"line":181,"column":null}}],"line":181},"18":{"loc":{"start":{"line":182,"column":24},"end":{"line":182,"column":null}},"type":"binary-expr","locations":[{"start":{"line":182,"column":24},"end":{"line":182,"column":47}},{"start":{"line":182,"column":47},"end":{"line":182,"column":60}},{"start":{"line":182,"column":60},"end":{"line":182,"column":null}}],"line":182},"19":{"loc":{"start":{"line":184,"column":13},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":184,"column":13},"end":{"line":184,"column":null}},{"start":{"line":185,"column":12},"end":{"line":185,"column":null}},{"start":{"line":186,"column":13},"end":{"line":186,"column":null}},{"start":{"line":187,"column":12},"end":{"line":187,"column":null}},{"start":{"line":188,"column":12},"end":{"line":188,"column":null}}],"line":184},"20":{"loc":{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},"type":"if","locations":[{"start":{"line":209,"column":6},"end":{"line":216,"column":null}},{"start":{"line":211,"column":13},"end":{"line":216,"column":null}}],"line":209},"21":{"loc":{"start":{"line":213,"column":28},"end":{"line":213,"column":null}},"type":"binary-expr","locations":[{"start":{"line":213,"column":28},"end":{"line":213,"column":54}},{"start":{"line":213,"column":54},"end":{"line":213,"column":74}},{"start":{"line":213,"column":74},"end":{"line":213,"column":90}},{"start":{"line":213,"column":90},"end":{"line":213,"column":null}}],"line":213},"22":{"loc":{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":219,"column":4},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":219},"23":{"loc":{"start":{"line":244,"column":12},"end":{"line":244,"column":null}},"type":"binary-expr","locations":[{"start":{"line":244,"column":12},"end":{"line":244,"column":35}},{"start":{"line":244,"column":35},"end":{"line":244,"column":59}},{"start":{"line":244,"column":59},"end":{"line":244,"column":79}},{"start":{"line":244,"column":79},"end":{"line":244,"column":null}}],"line":244}},"s":{"0":13,"1":14,"2":14,"3":14,"4":14,"5":14,"6":14,"7":8,"8":8,"9":8,"10":8,"11":14,"12":6,"13":6,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0},"f":{"0":13,"1":14,"2":8,"3":6,"4":1,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[14,7,2],"1":[6,8],"2":[6,2],"3":[1],"4":[1],"5":[1],"6":[1,0],"7":[1,0],"8":[1,1],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0],"13":[0,0,0],"14":[0,0],"15":[0,0],"16":[0,0],"17":[0,0,0],"18":[0,0,0],"19":[0,0,0,0,0],"20":[0,0],"21":[0,0,0,0],"22":[0,0],"23":[0,0,0,0]},"meta":{"lastBranch":24,"lastFunction":11,"lastStatement":69,"seen":{"f:32:22:32:Infinity":0,"s:36:2:36:Infinity":0,"f:39:22:39:Infinity":1,"s:43:19:46:Infinity":1,"s:47:15:47:Infinity":2,"b:47:15:47:39:47:39:47:64:47:64:47:Infinity":0,"s:48:22:48:Infinity":3,"s:49:24:49:Infinity":4,"b:49:44:49:61:49:61:49:Infinity":1,"s:50:21:56:Infinity":5,"s:57:16:65:Infinity":6,"f:57:20:57:25":2,"s:58:22:58:Infinity":7,"s:59:24:59:Infinity":8,"s:60:26:63:Infinity":9,"s:64:4:64:Infinity":10,"s:66:2:72:Infinity":11,"f:75:22:75:Infinity":3,"s:79:19:82:Infinity":12,"s:83:2:83:Infinity":13,"b:83:10:83:35:83:35:83:Infinity":2,"f:86:22:86:Infinity":4,"b:89:22:89:Infinity":3,"s:91:19:94:Infinity":14,"s:95:2:95:Infinity":15,"f:98:22:98:Infinity":5,"b:101:22:101:Infinity":4,"b:105:6:105:Infinity":5,"s:107:16:107:Infinity":16,"s:108:2:154:Infinity":17,"s:109:21:109:Infinity":18,"s:110:26:113:Infinity":19,"b:111:21:111:46:111:46:111:Infinity":6,"s:114:24:114:Infinity":20,"b:114:59:114:63:114:63:114:Infinity":7,"s:115:23:122:Infinity":21,"b:121:17:121:38:121:38:121:Infinity":8,"s:123:4:129:Infinity":22,"s:131:16:131:Infinity":23,"s:132:27:132:Infinity":24,"b:132:61:132:76:132:76:132:80":9,"b:133:4:133:Infinity:undefined:undefined:undefined:undefined":10,"s:133:4:133:Infinity":25,"s:133:25:133:Infinity":26,"s:135:26:135:Infinity":27,"s:136:23:143:Infinity":28,"b:142:17:142:38:142:38:142:Infinity":11,"s:144:4:153:Infinity":29,"f:157:22:157:Infinity":6,"b:160:16:160:Infinity":12,"s:162:26:162:Infinity":30,"s:163:38:163:Infinity":31,"s:165:2:222:Infinity":32,"s:165:15:165:18":33,"s:166:18:166:Infinity":34,"s:168:25:205:Infinity":35,"f:169:16:169:23":7,"s:170:23:170:Infinity":36,"b:170:23:170:43:170:43:170:57:170:57:170:Infinity":13,"b:171:8:174:Infinity:undefined:undefined:undefined:undefined":14,"s:171:8:174:Infinity":37,"s:172:10:172:Infinity":38,"s:173:10:173:Infinity":39,"s:176:8:203:Infinity":40,"s:177:26:177:Infinity":41,"s:178:30:178:Infinity":42,"b:178:30:178:55:178:55:178:Infinity":15,"s:179:25:181:Infinity":43,"b:180:14:180:Infinity:181:14:181:Infinity":16,"b:181:14:181:37:181:37:181:59:181:59:181:Infinity":17,"s:182:24:182:Infinity":44,"b:182:24:182:47:182:47:182:60:182:60:182:Infinity":18,"s:184:13:188:Infinity":45,"b:184:13:184:Infinity:185:12:185:Infinity:186:13:186:Infinity:187:12:187:Infinity:188:12:188:Infinity":19,"s:190:10:198:Infinity":46,"s:200:26:200:Infinity":47,"s:201:10:201:Infinity":48,"s:202:10:202:Infinity":49,"s:207:4:217:Infinity":50,"s:207:19:207:22":51,"s:208:21:208:Infinity":52,"b:209:6:216:Infinity:211:13:216:Infinity":20,"s:209:6:216:Infinity":53,"s:210:8:210:Infinity":54,"s:212:26:212:Infinity":55,"s:213:28:213:Infinity":56,"b:213:28:213:54:213:54:213:74:213:74:213:90:213:90:213:Infinity":21,"s:214:8:214:Infinity":57,"s:215:8:215:Infinity":58,"b:219:4:221:Infinity:undefined:undefined:undefined:undefined":22,"s:219:4:221:Infinity":59,"s:220:6:220:Infinity":60,"f:220:16:220:31":8,"s:220:43:220:67":61,"s:224:2:224:Infinity":62,"f:236:22:236:Infinity":9,"s:240:2:248:Infinity":63,"s:241:21:243:Infinity":64,"s:244:4:244:Infinity":65,"b:244:12:244:35:244:35:244:59:244:59:244:79:244:79:244:Infinity":23,"s:246:4:246:Infinity":66,"s:247:4:247:Infinity":67,"f:257:22:257:Infinity":10,"s:261:2:261:Infinity":68}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/members.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/members.ts","statementMap":{"0":{"start":{"line":16,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"fetchMPs","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":15,"column":22},"end":{"line":21,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"type":"default-arg","locations":[{"start":{"line":14,"column":29},"end":{"line":14,"column":null}}],"line":14},"1":{"loc":{"start":{"line":20,"column":10},"end":{"line":20,"column":null}},"type":"binary-expr","locations":[{"start":{"line":20,"column":10},"end":{"line":20,"column":29}},{"start":{"line":20,"column":29},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":9,"1":9},"f":{"0":9},"b":{"0":[9],"1":[9,2]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":2,"seen":{"f:12:22:12:Infinity":0,"b:14:29:14:Infinity":0,"s:16:19:19:Infinity":0,"s:20:2:20:Infinity":1,"b:20:10:20:29:20:29:20:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/reports.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/reports.ts","statementMap":{"0":{"start":{"line":18,"column":42},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"2":{"start":{"line":19,"column":10},"end":{"line":19,"column":null}},"3":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"4":{"start":{"line":20,"column":13},"end":{"line":20,"column":null}},"5":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"6":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"7":{"start":{"line":31,"column":42},"end":{"line":31,"column":null}},"8":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"9":{"start":{"line":32,"column":10},"end":{"line":32,"column":null}},"10":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"11":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"12":{"start":{"line":43,"column":42},"end":{"line":43,"column":null}},"13":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"14":{"start":{"line":44,"column":10},"end":{"line":44,"column":null}},"15":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"16":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"17":{"start":{"line":54,"column":45},"end":{"line":54,"column":null}},"18":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"19":{"start":{"line":55,"column":17},"end":{"line":55,"column":null}},"20":{"start":{"line":56,"column":19},"end":{"line":56,"column":null}},"21":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"22":{"start":{"line":64,"column":45},"end":{"line":64,"column":null}},"23":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"24":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"25":{"start":{"line":66,"column":19},"end":{"line":66,"column":null}},"26":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}}},"fnMap":{"0":{"name":"fetchCommitteeReports","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":17,"column":22},"end":{"line":24,"column":null}},"line":17},"1":{"name":"fetchPropositions","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":null}},"loc":{"start":{"line":30,"column":22},"end":{"line":36,"column":null}},"line":30},"2":{"name":"fetchMotions","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":22},"end":{"line":48,"column":null}},"line":42},"3":{"name":"fetchWrittenQuestions","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":null}},"loc":{"start":{"line":53,"column":22},"end":{"line":58,"column":null}},"line":53},"4":{"name":"fetchInterpellations","decl":{"start":{"line":60,"column":22},"end":{"line":60,"column":null}},"loc":{"start":{"line":63,"column":22},"end":{"line":68,"column":null}},"line":63}},"branchMap":{"0":{"loc":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"type":"default-arg","locations":[{"start":{"line":14,"column":10},"end":{"line":14,"column":null}}],"line":14},"1":{"loc":{"start":{"line":15,"column":2},"end":{"line":15,"column":null}},"type":"default-arg","locations":[{"start":{"line":15,"column":22},"end":{"line":15,"column":null}}],"line":15},"2":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"default-arg","locations":[{"start":{"line":16,"column":25},"end":{"line":16,"column":null}}],"line":16},"3":{"loc":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},{"start":{},"end":{}}],"line":19},"4":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"5":{"loc":{"start":{"line":23,"column":10},"end":{"line":23,"column":null}},"type":"binary-expr","locations":[{"start":{"line":23,"column":10},"end":{"line":23,"column":34}},{"start":{"line":23,"column":34},"end":{"line":23,"column":57}},{"start":{"line":23,"column":57},"end":{"line":23,"column":null}}],"line":23},"6":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":10},"end":{"line":28,"column":null}}],"line":28},"7":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"default-arg","locations":[{"start":{"line":29,"column":22},"end":{"line":29,"column":null}}],"line":29},"8":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"9":{"loc":{"start":{"line":35,"column":10},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":10},"end":{"line":35,"column":34}},{"start":{"line":35,"column":34},"end":{"line":35,"column":62}},{"start":{"line":35,"column":62},"end":{"line":35,"column":null}}],"line":35},"10":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"default-arg","locations":[{"start":{"line":40,"column":10},"end":{"line":40,"column":null}}],"line":40},"11":{"loc":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"type":"default-arg","locations":[{"start":{"line":41,"column":22},"end":{"line":41,"column":null}}],"line":41},"12":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"13":{"loc":{"start":{"line":47,"column":10},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":10},"end":{"line":47,"column":34}},{"start":{"line":47,"column":34},"end":{"line":47,"column":57}},{"start":{"line":47,"column":57},"end":{"line":47,"column":null}}],"line":47},"14":{"loc":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"type":"default-arg","locations":[{"start":{"line":52,"column":44},"end":{"line":52,"column":null}}],"line":52},"15":{"loc":{"start":{"line":54,"column":54},"end":{"line":54,"column":73}},"type":"binary-expr","locations":[{"start":{"line":54,"column":54},"end":{"line":54,"column":70}},{"start":{"line":54,"column":70},"end":{"line":54,"column":73}}],"line":54},"16":{"loc":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"17":{"loc":{"start":{"line":57,"column":10},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":34}},{"start":{"line":57,"column":34},"end":{"line":57,"column":59}},{"start":{"line":57,"column":59},"end":{"line":57,"column":null}}],"line":57},"18":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"default-arg","locations":[{"start":{"line":62,"column":44},"end":{"line":62,"column":null}}],"line":62},"19":{"loc":{"start":{"line":64,"column":54},"end":{"line":64,"column":73}},"type":"binary-expr","locations":[{"start":{"line":64,"column":54},"end":{"line":64,"column":70}},{"start":{"line":64,"column":70},"end":{"line":64,"column":73}}],"line":64},"20":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"21":{"loc":{"start":{"line":67,"column":10},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":10},"end":{"line":67,"column":34}},{"start":{"line":67,"column":34},"end":{"line":67,"column":65}},{"start":{"line":67,"column":65},"end":{"line":67,"column":null}}],"line":67}},"s":{"0":5,"1":5,"2":2,"3":5,"4":1,"5":5,"6":5,"7":7,"8":7,"9":2,"10":7,"11":7,"12":6,"13":6,"14":2,"15":6,"16":6,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1},"f":{"0":5,"1":7,"2":6,"3":1,"4":1},"b":{"0":[5],"1":[5],"2":[5],"3":[2,3],"4":[1,4],"5":[5,5,2],"6":[7],"7":[7],"8":[2,5],"9":[7,7,2],"10":[6],"11":[6],"12":[2,4],"13":[6,6,2],"14":[1],"15":[1,0],"16":[1,0],"17":[1,1,1],"18":[1],"19":[1,0],"20":[1,0],"21":[1,1,1]},"meta":{"lastBranch":22,"lastFunction":5,"lastStatement":27,"seen":{"f:12:22:12:Infinity":0,"b:14:10:14:Infinity":0,"b:15:22:15:Infinity":1,"b:16:25:16:Infinity":2,"s:18:42:18:Infinity":0,"b:19:2:19:Infinity:undefined:undefined:undefined:undefined":3,"s:19:2:19:Infinity":1,"s:19:10:19:Infinity":2,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":4,"s:20:2:20:Infinity":3,"s:20:13:20:Infinity":4,"s:22:19:22:Infinity":5,"s:23:2:23:Infinity":6,"b:23:10:23:34:23:34:23:57:23:57:23:Infinity":5,"f:26:22:26:Infinity":1,"b:28:10:28:Infinity":6,"b:29:22:29:Infinity":7,"s:31:42:31:Infinity":7,"b:32:2:32:Infinity:undefined:undefined:undefined:undefined":8,"s:32:2:32:Infinity":8,"s:32:10:32:Infinity":9,"s:34:19:34:Infinity":10,"s:35:2:35:Infinity":11,"b:35:10:35:34:35:34:35:62:35:62:35:Infinity":9,"f:38:22:38:Infinity":2,"b:40:10:40:Infinity":10,"b:41:22:41:Infinity":11,"s:43:42:43:Infinity":12,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":12,"s:44:2:44:Infinity":13,"s:44:10:44:Infinity":14,"s:46:19:46:Infinity":15,"s:47:2:47:Infinity":16,"b:47:10:47:34:47:34:47:57:47:57:47:Infinity":13,"f:50:22:50:Infinity":3,"b:52:44:52:Infinity":14,"s:54:45:54:Infinity":17,"b:54:54:54:70:54:70:54:73":15,"b:55:2:55:Infinity:undefined:undefined:undefined:undefined":16,"s:55:2:55:Infinity":18,"s:55:17:55:Infinity":19,"s:56:19:56:Infinity":20,"s:57:2:57:Infinity":21,"b:57:10:57:34:57:34:57:59:57:59:57:Infinity":17,"f:60:22:60:Infinity":4,"b:62:44:62:Infinity":18,"s:64:45:64:Infinity":22,"b:64:54:64:70:64:70:64:73":19,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":20,"s:65:2:65:Infinity":23,"s:65:17:65:Infinity":24,"s:66:19:66:Infinity":25,"s:67:2:67:Infinity":26,"b:67:10:67:34:67:34:67:65:67:65:67:Infinity":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/speeches.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/speeches.ts","statementMap":{"0":{"start":{"line":16,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"searchSpeeches","decl":{"start":{"line":12,"column":22},"end":{"line":12,"column":null}},"loc":{"start":{"line":15,"column":22},"end":{"line":21,"column":null}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":10},"end":{"line":20,"column":null}},"type":"binary-expr","locations":[{"start":{"line":20,"column":10},"end":{"line":20,"column":36}},{"start":{"line":20,"column":36},"end":{"line":20,"column":60}},{"start":{"line":20,"column":60},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":8,"1":8},"f":{"0":8},"b":{"0":[8,8,3]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":2,"seen":{"f:12:22:12:Infinity":0,"s:16:19:19:Infinity":0,"s:20:2:20:Infinity":1,"b:20:10:20:36:20:36:20:60:20:60:20:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/votes.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/methods/votes.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":31,"column":19},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":8},"end":{"line":36,"column":null}},"3":{"start":{"line":36,"column":20},"end":{"line":36,"column":32}},"4":{"start":{"line":37,"column":22},"end":{"line":37,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},"6":{"start":{"line":41,"column":25},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},"8":{"start":{"line":43,"column":6},"end":{"line":66,"column":null}},"9":{"start":{"line":44,"column":35},"end":{"line":47,"column":null}},"10":{"start":{"line":48,"column":14},"end":{"line":50,"column":null}},"11":{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},"12":{"start":{"line":52,"column":10},"end":{"line":62,"column":null}},"13":{"start":{"line":70,"column":24},"end":{"line":70,"column":null}},"14":{"start":{"line":71,"column":36},"end":{"line":78,"column":null}},"15":{"start":{"line":80,"column":2},"end":{"line":87,"column":null}},"16":{"start":{"line":81,"column":31},"end":{"line":81,"column":71}},"17":{"start":{"line":94,"column":19},"end":{"line":97,"column":null}},"18":{"start":{"line":98,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"fetchVotingRecords","decl":{"start":{"line":20,"column":22},"end":{"line":20,"column":null}},"loc":{"start":{"line":23,"column":22},"end":{"line":25,"column":null}},"line":23},"1":{"name":"fetchVotingRecordsWithDiagnostics","decl":{"start":{"line":27,"column":22},"end":{"line":27,"column":null}},"loc":{"start":{"line":30,"column":88},"end":{"line":88,"column":null}},"line":30},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":10}},"loc":{"start":{"line":36,"column":20},"end":{"line":36,"column":32}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":81,"column":17},"end":{"line":81,"column":22}},"loc":{"start":{"line":81,"column":31},"end":{"line":81,"column":71}},"line":81},"4":{"name":"fetchVotingGroup","decl":{"start":{"line":90,"column":22},"end":{"line":90,"column":null}},"loc":{"start":{"line":93,"column":22},"end":{"line":99,"column":null}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":67}},"type":"binary-expr","locations":[{"start":{"line":35,"column":18},"end":{"line":35,"column":39}},{"start":{"line":35,"column":39},"end":{"line":35,"column":65}},{"start":{"line":35,"column":65},"end":{"line":35,"column":67}}],"line":35},"1":{"loc":{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":40},"2":{"loc":{"start":{"line":40,"column":6},"end":{"line":40,"column":59}},"type":"binary-expr","locations":[{"start":{"line":40,"column":6},"end":{"line":40,"column":27}},{"start":{"line":40,"column":27},"end":{"line":40,"column":59}}],"line":40},"3":{"loc":{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":42},"4":{"loc":{"start":{"line":49,"column":11},"end":{"line":49,"column":80}},"type":"binary-expr","locations":[{"start":{"line":49,"column":11},"end":{"line":49,"column":42}},{"start":{"line":49,"column":42},"end":{"line":49,"column":78}},{"start":{"line":49,"column":78},"end":{"line":49,"column":80}}],"line":49},"5":{"loc":{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":51},"6":{"loc":{"start":{"line":70,"column":24},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":44},"end":{"line":70,"column":61}},{"start":{"line":70,"column":61},"end":{"line":70,"column":null}}],"line":70},"7":{"loc":{"start":{"line":77,"column":13},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":22},"end":{"line":77,"column":33}},{"start":{"line":77,"column":33},"end":{"line":77,"column":null}}],"line":77},"8":{"loc":{"start":{"line":86,"column":8},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":17},"end":{"line":86,"column":30}},{"start":{"line":86,"column":30},"end":{"line":86,"column":null}}],"line":86},"9":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"default-arg","locations":[{"start":{"line":92,"column":36},"end":{"line":92,"column":null}}],"line":92},"10":{"loc":{"start":{"line":98,"column":10},"end":{"line":98,"column":null}},"type":"binary-expr","locations":[{"start":{"line":98,"column":10},"end":{"line":98,"column":32}},{"start":{"line":98,"column":32},"end":{"line":98,"column":53}},{"start":{"line":98,"column":53},"end":{"line":98,"column":null}}],"line":98}},"s":{"0":6,"1":8,"2":8,"3":3,"4":8,"5":8,"6":5,"7":5,"8":5,"9":5,"10":5,"11":5,"12":1,"13":8,"14":8,"15":8,"16":3,"17":3,"18":3},"f":{"0":6,"1":8,"2":3,"3":3,"4":3},"b":{"0":[8,2,2],"1":[5,3],"2":[8,5],"3":[5,0],"4":[5,2,2],"5":[1,4],"6":[5,3],"7":[1,7],"8":[1,7],"9":[3],"10":[3,1,1]},"meta":{"lastBranch":11,"lastFunction":5,"lastStatement":19,"seen":{"f:20:22:20:Infinity":0,"s:24:2:24:Infinity":0,"f:27:22:27:Infinity":1,"s:31:19:34:Infinity":1,"s:35:8:36:Infinity":2,"b:35:18:35:39:35:39:35:65:35:65:35:67":0,"f:36:5:36:10":2,"s:36:20:36:32":3,"s:37:22:37:Infinity":4,"b:40:2:68:Infinity:undefined:undefined:undefined:undefined":1,"s:40:2:68:Infinity":5,"b:40:6:40:27:40:27:40:59":2,"s:41:25:41:Infinity":6,"b:42:4:67:Infinity:undefined:undefined:undefined:undefined":3,"s:42:4:67:Infinity":7,"s:43:6:66:Infinity":8,"s:44:35:47:Infinity":9,"s:48:14:50:Infinity":10,"b:49:11:49:42:49:42:49:78:49:78:49:80":4,"b:51:8:63:Infinity:undefined:undefined:undefined:undefined":5,"s:51:8:63:Infinity":11,"s:52:10:62:Infinity":12,"s:70:24:70:Infinity":13,"b:70:44:70:61:70:61:70:Infinity":6,"s:71:36:78:Infinity":14,"b:77:22:77:33:77:33:77:Infinity":7,"s:80:2:87:Infinity":15,"f:81:17:81:22":3,"s:81:31:81:71":16,"b:86:17:86:30:86:30:86:Infinity":8,"f:90:22:90:Infinity":4,"b:92:36:92:Infinity":9,"s:94:19:97:Infinity":17,"s:98:2:98:Infinity":18,"b:98:10:98:32:98:32:98:53:98:53:98:Infinity":10}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/riksmote/helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/riksmote/helpers.ts","statementMap":{"0":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"2":{"start":{"line":16,"column":14},"end":{"line":16,"column":null}},"3":{"start":{"line":17,"column":20},"end":{"line":17,"column":null}},"4":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"5":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"6":{"start":{"line":19,"column":64},"end":{"line":19,"column":null}},"7":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}}},"fnMap":{"0":{"name":"previousRiksmote","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":33}},"loc":{"start":{"line":14,"column":60},"end":{"line":21,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"if","locations":[{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},{"start":{},"end":{}}],"line":16},"1":{"loc":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},{"start":{},"end":{}}],"line":19},"2":{"loc":{"start":{"line":19,"column":6},"end":{"line":19,"column":64}},"type":"binary-expr","locations":[{"start":{"line":19,"column":6},"end":{"line":19,"column":37}},{"start":{"line":19,"column":37},"end":{"line":19,"column":64}}],"line":19}},"s":{"0":5,"1":5,"2":0,"3":5,"4":5,"5":5,"6":0,"7":5},"f":{"0":5},"b":{"0":[0,5],"1":[0,5],"2":[5,5]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":8,"seen":{"f:14:16:14:33":0,"s:15:16:15:Infinity":0,"b:16:2:16:Infinity:undefined:undefined:undefined:undefined":0,"s:16:2:16:Infinity":1,"s:16:14:16:Infinity":2,"s:17:20:17:Infinity":3,"s:18:18:18:Infinity":4,"b:19:2:19:Infinity:undefined:undefined:undefined:undefined":1,"s:19:2:19:Infinity":5,"b:19:6:19:37:19:37:19:64":2,"s:19:64:19:Infinity":6,"s:20:2:20:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/jsonrpc.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/jsonrpc.ts","statementMap":{"0":{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},"1":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"2":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"3":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"4":{"start":{"line":60,"column":6},"end":{"line":60,"column":null}},"5":{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},"6":{"start":{"line":63,"column":6},"end":{"line":63,"column":null}},"7":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"9":{"start":{"line":66,"column":6},"end":{"line":66,"column":null}},"10":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"14":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"15":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"16":{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},"17":{"start":{"line":93,"column":6},"end":{"line":93,"column":null}},"18":{"start":{"line":96,"column":23},"end":{"line":96,"column":null}},"19":{"start":{"line":97,"column":22},"end":{"line":97,"column":null}},"20":{"start":{"line":97,"column":39},"end":{"line":97,"column":59}},"21":{"start":{"line":99,"column":4},"end":{"line":161,"column":null}},"22":{"start":{"line":100,"column":29},"end":{"line":100,"column":null}},"23":{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},"24":{"start":{"line":103,"column":8},"end":{"line":107,"column":null}},"25":{"start":{"line":104,"column":10},"end":{"line":104,"column":null}},"26":{"start":{"line":110,"column":22},"end":{"line":110,"column":null}},"27":{"start":{"line":112,"column":23},"end":{"line":117,"column":null}},"28":{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},"29":{"start":{"line":120,"column":24},"end":{"line":120,"column":null}},"30":{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},"31":{"start":{"line":121,"column":14},"end":{"line":121,"column":49}},"32":{"start":{"line":122,"column":8},"end":{"line":124,"column":null}},"33":{"start":{"line":127,"column":47},"end":{"line":127,"column":null}},"34":{"start":{"line":128,"column":27},"end":{"line":128,"column":null}},"35":{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},"36":{"start":{"line":131,"column":8},"end":{"line":131,"column":null}},"37":{"start":{"line":132,"column":14},"end":{"line":132,"column":null}},"38":{"start":{"line":133,"column":8},"end":{"line":133,"column":null}},"39":{"start":{"line":134,"column":8},"end":{"line":134,"column":null}},"40":{"start":{"line":135,"column":8},"end":{"line":135,"column":null}},"41":{"start":{"line":136,"column":8},"end":{"line":136,"column":null}},"42":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"43":{"start":{"line":139,"column":8},"end":{"line":139,"column":null}},"44":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"45":{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},"46":{"start":{"line":145,"column":18},"end":{"line":145,"column":null}},"47":{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},"48":{"start":{"line":148,"column":22},"end":{"line":148,"column":null}},"49":{"start":{"line":149,"column":8},"end":{"line":151,"column":null}},"50":{"start":{"line":152,"column":8},"end":{"line":152,"column":null}},"51":{"start":{"line":153,"column":8},"end":{"line":153,"column":null}},"52":{"start":{"line":154,"column":8},"end":{"line":154,"column":null}},"53":{"start":{"line":157,"column":6},"end":{"line":157,"column":null}},"54":{"start":{"line":158,"column":6},"end":{"line":158,"column":null}},"55":{"start":{"line":160,"column":6},"end":{"line":160,"column":null}},"56":{"start":{"line":169,"column":4},"end":{"line":169,"column":null}},"57":{"start":{"line":169,"column":36},"end":{"line":169,"column":59}},"58":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"59":{"start":{"line":177,"column":4},"end":{"line":177,"column":null}},"60":{"start":{"line":185,"column":4},"end":{"line":192,"column":null}},"61":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"62":{"start":{"line":197,"column":4},"end":{"line":197,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":55,"column":2},"end":{"line":55,"column":14}},"loc":{"start":{"line":55,"column":53},"end":{"line":73,"column":null}},"line":55},"1":{"name":"(anonymous_1)","decl":{"start":{"line":76,"column":2},"end":{"line":76,"column":26}},"loc":{"start":{"line":76,"column":26},"end":{"line":78,"column":null}},"line":76},"2":{"name":"(anonymous_2)","decl":{"start":{"line":84,"column":8},"end":{"line":84,"column":null}},"loc":{"start":{"line":89,"column":38},"end":{"line":162,"column":null}},"line":89},"3":{"name":"(anonymous_3)","decl":{"start":{"line":97,"column":22},"end":{"line":97,"column":39}},"loc":{"start":{"line":97,"column":39},"end":{"line":97,"column":59}},"line":97},"4":{"name":"(anonymous_4)","decl":{"start":{"line":168,"column":8},"end":{"line":168,"column":14}},"loc":{"start":{"line":168,"column":41},"end":{"line":170,"column":null}},"line":168},"5":{"name":"(anonymous_5)","decl":{"start":{"line":169,"column":15},"end":{"line":169,"column":24}},"loc":{"start":{"line":169,"column":36},"end":{"line":169,"column":59}},"line":169},"6":{"name":"(anonymous_6)","decl":{"start":{"line":172,"column":2},"end":{"line":172,"column":19}},"loc":{"start":{"line":172,"column":50},"end":{"line":174,"column":null}},"line":172},"7":{"name":"(anonymous_7)","decl":{"start":{"line":176,"column":8},"end":{"line":176,"column":43}},"loc":{"start":{"line":176,"column":43},"end":{"line":178,"column":null}},"line":176},"8":{"name":"(anonymous_8)","decl":{"start":{"line":184,"column":2},"end":{"line":184,"column":23}},"loc":{"start":{"line":184,"column":23},"end":{"line":193,"column":null}},"line":184},"9":{"name":"(anonymous_9)","decl":{"start":{"line":195,"column":2},"end":{"line":195,"column":21}},"loc":{"start":{"line":195,"column":21},"end":{"line":198,"column":null}},"line":195}},"branchMap":{"0":{"loc":{"start":{"line":55,"column":14},"end":{"line":55,"column":53}},"type":"default-arg","locations":[{"start":{"line":55,"column":49},"end":{"line":55,"column":53}}],"line":55},"1":{"loc":{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":68,"column":null}},{"start":{"line":62,"column":11},"end":{"line":68,"column":null}}],"line":56},"2":{"loc":{"start":{"line":63,"column":21},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":21},"end":{"line":63,"column":39}},{"start":{"line":63,"column":39},"end":{"line":63,"column":59}},{"start":{"line":63,"column":59},"end":{"line":63,"column":null}}],"line":63},"3":{"loc":{"start":{"line":64,"column":21},"end":{"line":64,"column":57}},"type":"binary-expr","locations":[{"start":{"line":64,"column":21},"end":{"line":64,"column":39}},{"start":{"line":64,"column":39},"end":{"line":64,"column":57}}],"line":64},"4":{"loc":{"start":{"line":65,"column":24},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":24},"end":{"line":65,"column":45}},{"start":{"line":65,"column":45},"end":{"line":65,"column":null}}],"line":65},"5":{"loc":{"start":{"line":66,"column":27},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":27},"end":{"line":66,"column":45}},{"start":{"line":66,"column":45},"end":{"line":66,"column":null}}],"line":66},"6":{"loc":{"start":{"line":67,"column":23},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":23},"end":{"line":67,"column":43}},{"start":{"line":67,"column":43},"end":{"line":67,"column":null}}],"line":67},"7":{"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"type":"default-arg","locations":[{"start":{"line":86,"column":38},"end":{"line":86,"column":null}}],"line":86},"8":{"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"type":"default-arg","locations":[{"start":{"line":87,"column":17},"end":{"line":87,"column":null}}],"line":87},"9":{"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"type":"default-arg","locations":[{"start":{"line":88,"column":18},"end":{"line":88,"column":null}}],"line":88},"10":{"loc":{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":92},"11":{"loc":{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":6},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":102},"12":{"loc":{"start":{"line":102,"column":10},"end":{"line":102,"column":45}},"type":"binary-expr","locations":[{"start":{"line":102,"column":10},"end":{"line":102,"column":28}},{"start":{"line":102,"column":28},"end":{"line":102,"column":45}}],"line":102},"13":{"loc":{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":6},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":119},"14":{"loc":{"start":{"line":123,"column":72},"end":{"line":123,"column":null}},"type":"cond-expr","locations":[{"start":{"line":123,"column":84},"end":{"line":123,"column":104}},{"start":{"line":123,"column":104},"end":{"line":123,"column":null}}],"line":123},"15":{"loc":{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":6},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":130},"16":{"loc":{"start":{"line":130,"column":10},"end":{"line":130,"column":66}},"type":"binary-expr","locations":[{"start":{"line":130,"column":10},"end":{"line":130,"column":50}},{"start":{"line":130,"column":50},"end":{"line":130,"column":66}}],"line":130},"17":{"loc":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":138},"18":{"loc":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":22},"end":{"line":142,"column":48}},{"start":{"line":142,"column":48},"end":{"line":142,"column":null}}],"line":142},"19":{"loc":{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},"type":"if","locations":[{"start":{"line":147,"column":6},"end":{"line":155,"column":null}},{"start":{},"end":{}}],"line":147},"20":{"loc":{"start":{"line":147,"column":10},"end":{"line":147,"column":76}},"type":"binary-expr","locations":[{"start":{"line":147,"column":10},"end":{"line":147,"column":46}},{"start":{"line":147,"column":46},"end":{"line":147,"column":76}}],"line":147},"21":{"loc":{"start":{"line":189,"column":8},"end":{"line":191,"column":null}},"type":"cond-expr","locations":[{"start":{"line":190,"column":12},"end":{"line":190,"column":null}},{"start":{"line":191,"column":12},"end":{"line":191,"column":null}}],"line":189}},"s":{"0":133,"1":2,"2":2,"3":2,"4":2,"5":2,"6":131,"7":131,"8":131,"9":131,"10":131,"11":133,"12":133,"13":133,"14":1,"15":133,"16":133,"17":115,"18":125,"19":125,"20":0,"21":125,"22":125,"23":125,"24":1,"25":1,"26":125,"27":125,"28":111,"29":4,"30":4,"31":4,"32":4,"33":107,"34":107,"35":107,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":107,"43":3,"44":104,"45":133,"46":21,"47":21,"48":10,"49":10,"50":10,"51":10,"52":10,"53":11,"54":11,"55":125,"56":1,"57":1,"58":0,"59":1,"60":15,"61":3,"62":3},"f":{"0":133,"1":1,"2":133,"3":0,"4":1,"5":1,"6":0,"7":1,"8":15,"9":3},"b":{"0":[133],"1":[2,131],"2":[131,125,124],"3":[131,130],"4":[131,130],"5":[131,128],"6":[131,130],"7":[133],"8":[133],"9":[133],"10":[115,18],"11":[1,124],"12":[125,1],"13":[4,107],"14":[1,3],"15":[0,107],"16":[107,0],"17":[3,104],"18":[104,12],"19":[10,11],"20":[21,19],"21":[8,7]},"meta":{"lastBranch":22,"lastFunction":10,"lastStatement":63,"seen":{"f:55:2:55:14":0,"b:55:49:55:53":0,"b:56:4:68:Infinity:62:11:68:Infinity":1,"s:56:4:68:Infinity":0,"s:57:6:57:Infinity":1,"s:58:6:58:Infinity":2,"s:59:6:59:Infinity":3,"s:60:6:60:Infinity":4,"s:61:6:61:Infinity":5,"s:63:6:63:Infinity":6,"b:63:21:63:39:63:39:63:59:63:59:63:Infinity":2,"s:64:6:64:Infinity":7,"b:64:21:64:39:64:39:64:57":3,"s:65:6:65:Infinity":8,"b:65:24:65:45:65:45:65:Infinity":4,"s:66:6:66:Infinity":9,"b:66:27:66:45:66:45:66:Infinity":5,"s:67:6:67:Infinity":10,"b:67:23:67:43:67:43:67:Infinity":6,"s:70:4:70:Infinity":11,"s:71:4:71:Infinity":12,"s:72:4:72:Infinity":13,"f:76:2:76:26":1,"s:77:4:77:Infinity":14,"f:84:8:84:Infinity":2,"b:86:38:86:Infinity":7,"b:87:17:87:Infinity":8,"b:88:18:88:Infinity":9,"s:90:4:90:Infinity":15,"b:92:4:94:Infinity:undefined:undefined:undefined:undefined":10,"s:92:4:94:Infinity":16,"s:93:6:93:Infinity":17,"s:96:23:96:Infinity":18,"s:97:22:97:Infinity":19,"f:97:22:97:39":3,"s:97:39:97:59":20,"s:99:4:161:Infinity":21,"s:100:29:100:Infinity":22,"b:102:6:108:Infinity:undefined:undefined:undefined:undefined":11,"s:102:6:108:Infinity":23,"b:102:10:102:28:102:28:102:45":12,"s:103:8:107:Infinity":24,"s:104:10:104:Infinity":25,"s:110:22:110:Infinity":26,"s:112:23:117:Infinity":27,"b:119:6:125:Infinity:undefined:undefined:undefined:undefined":13,"s:119:6:125:Infinity":28,"s:120:24:120:Infinity":29,"s:121:8:121:Infinity":30,"s:121:14:121:49":31,"s:122:8:124:Infinity":32,"b:123:84:123:104:123:104:123:Infinity":14,"s:127:47:127:Infinity":33,"s:128:27:128:Infinity":34,"b:130:6:137:Infinity:undefined:undefined:undefined:undefined":15,"s:130:6:137:Infinity":35,"b:130:10:130:50:130:50:130:66":16,"s:131:8:131:Infinity":36,"s:132:14:132:Infinity":37,"s:133:8:133:Infinity":38,"s:134:8:134:Infinity":39,"s:135:8:135:Infinity":40,"s:136:8:136:Infinity":41,"b:138:6:140:Infinity:undefined:undefined:undefined:undefined":17,"s:138:6:140:Infinity":42,"s:139:8:139:Infinity":43,"s:142:22:142:Infinity":44,"b:142:22:142:48:142:48:142:Infinity":18,"s:143:6:143:Infinity":45,"s:145:18:145:Infinity":46,"b:147:6:155:Infinity:undefined:undefined:undefined:undefined":19,"s:147:6:155:Infinity":47,"b:147:10:147:46:147:46:147:76":20,"s:148:22:148:Infinity":48,"s:149:8:151:Infinity":49,"s:152:8:152:Infinity":50,"s:153:8:153:Infinity":51,"s:154:8:154:Infinity":52,"s:157:6:157:Infinity":53,"s:158:6:158:Infinity":54,"s:160:6:160:Infinity":55,"f:168:8:168:14":4,"s:169:4:169:Infinity":56,"f:169:15:169:24":5,"s:169:36:169:59":57,"f:172:2:172:19":6,"s:173:4:173:Infinity":58,"f:176:8:176:43":7,"s:177:4:177:Infinity":59,"f:184:2:184:23":8,"s:185:4:192:Infinity":60,"b:190:12:190:Infinity:191:12:191:Infinity":21,"f:195:2:195:21":9,"s:196:4:196:Infinity":61,"s:197:4:197:Infinity":62}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/error-envelope.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/error-envelope.ts","statementMap":{"0":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"1":{"start":{"line":40,"column":23},"end":{"line":40,"column":null}},"2":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"6":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"8":{"start":{"line":61,"column":16},"end":{"line":61,"column":null}},"9":{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},"10":{"start":{"line":64,"column":4},"end":{"line":67,"column":null}},"11":{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},"12":{"start":{"line":74,"column":4},"end":{"line":75,"column":null}},"13":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}}},"fnMap":{"0":{"name":"classifyJsonRpcError","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":37}},"loc":{"start":{"line":39,"column":85},"end":{"line":50,"column":null}},"line":39},"1":{"name":"formatRequestFailure","decl":{"start":{"line":59,"column":16},"end":{"line":59,"column":37}},"loc":{"start":{"line":59,"column":74},"end":{"line":81,"column":null}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":40},"1":{"loc":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":19},"end":{"line":42,"column":45}},{"start":{"line":42,"column":45},"end":{"line":42,"column":null}}],"line":42},"2":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"binary-expr","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":51}},{"start":{"line":44,"column":51},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"4":{"loc":{"start":{"line":60,"column":20},"end":{"line":60,"column":37}},"type":"binary-expr","locations":[{"start":{"line":60,"column":20},"end":{"line":60,"column":35}},{"start":{"line":60,"column":35},"end":{"line":60,"column":37}}],"line":60},"5":{"loc":{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":79,"column":null}},{"start":{"line":69,"column":9},"end":{"line":79,"column":null}}],"line":63},"6":{"loc":{"start":{"line":63,"column":6},"end":{"line":63,"column":65}},"type":"binary-expr","locations":[{"start":{"line":63,"column":6},"end":{"line":63,"column":35}},{"start":{"line":63,"column":35},"end":{"line":63,"column":65}}],"line":63},"7":{"loc":{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":9},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":69},"8":{"loc":{"start":{"line":70,"column":4},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},{"start":{"line":72,"column":4},"end":{"line":72,"column":null}}],"line":70}},"s":{"0":107,"1":104,"2":3,"3":107,"4":107,"5":0,"6":3,"7":11,"8":11,"9":11,"10":0,"11":11,"12":2,"13":11},"f":{"0":107,"1":11},"b":{"0":[104,3],"1":[3,0],"2":[107,3],"3":[0,107],"4":[11,0],"5":[0,11],"6":[11,11],"7":[2,9],"8":[11,9,9]},"meta":{"lastBranch":9,"lastFunction":2,"lastStatement":14,"seen":{"f:39:16:39:37":0,"b:40:2:40:Infinity:undefined:undefined:undefined:undefined":0,"s:40:2:40:Infinity":0,"s:40:23:40:Infinity":1,"s:42:19:42:Infinity":2,"b:42:19:42:45:42:45:42:Infinity":1,"s:44:4:44:Infinity":3,"b:44:4:44:51:44:51:44:Infinity":2,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":3,"s:46:2:48:Infinity":4,"s:47:4:47:Infinity":5,"s:49:2:49:Infinity":6,"f:59:16:59:37":1,"s:60:8:60:Infinity":7,"b:60:20:60:35:60:35:60:37":4,"s:61:16:61:Infinity":8,"b:63:2:79:Infinity:69:9:79:Infinity":5,"s:63:2:79:Infinity":9,"b:63:6:63:35:63:35:63:65":6,"s:64:4:67:Infinity":10,"b:69:9:79:Infinity:undefined:undefined:undefined:undefined":7,"s:69:9:79:Infinity":11,"b:70:4:70:Infinity:71:4:71:Infinity:72:4:72:Infinity":8,"s:74:4:75:Infinity":12,"s:80:2:80:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/request-builder.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/request-builder.ts","statementMap":{"0":{"start":{"line":18,"column":16},"end":{"line":18,"column":null}},"1":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":35,"column":null}},"5":{"start":{"line":45,"column":2},"end":{"line":50,"column":null}},"6":{"start":{"line":63,"column":42},"end":{"line":67,"column":null}},"7":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"8":{"start":{"line":68,"column":17},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"10":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"nextJsonRpcId","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":40}},"loc":{"start":{"line":21,"column":40},"end":{"line":23,"column":null}},"line":21},"1":{"name":"_resetJsonRpcIdForTests","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":40}},"loc":{"start":{"line":26,"column":57},"end":{"line":28,"column":null}},"line":26},"2":{"name":"assertValidToolName","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":36}},"loc":{"start":{"line":31,"column":56},"end":{"line":37,"column":null}},"line":31},"3":{"name":"buildJsonRpcRequest","decl":{"start":{"line":40,"column":16},"end":{"line":40,"column":null}},"loc":{"start":{"line":44,"column":18},"end":{"line":51,"column":null}},"line":44},"4":{"name":"buildRequestHeaders","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":null}},"loc":{"start":{"line":62,"column":26},"end":{"line":71,"column":null}},"line":62}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":40},"end":{"line":26,"column":57}},"type":"default-arg","locations":[{"start":{"line":26,"column":48},"end":{"line":26,"column":57}}],"line":26},"1":{"loc":{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":32},"2":{"loc":{"start":{"line":32,"column":6},"end":{"line":32,"column":75}},"type":"binary-expr","locations":[{"start":{"line":32,"column":6},"end":{"line":32,"column":15}},{"start":{"line":32,"column":15},"end":{"line":32,"column":43}},{"start":{"line":32,"column":43},"end":{"line":32,"column":75}}],"line":32},"3":{"loc":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"type":"default-arg","locations":[{"start":{"line":43,"column":15},"end":{"line":43,"column":null}}],"line":43},"4":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"5":{"loc":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":69}},"s":{"0":32,"1":126,"2":0,"3":133,"4":8,"5":125,"6":125,"7":125,"8":1,"9":125,"10":0,"11":125},"f":{"0":126,"1":0,"2":133,"3":125,"4":125},"b":{"0":[0],"1":[8,125],"2":[133,130,129],"3":[125],"4":[1,124],"5":[0,125]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":12,"seen":{"s:18:16:18:Infinity":0,"f:21:16:21:40":0,"s:22:2:22:Infinity":1,"f:26:16:26:40":1,"b:26:48:26:57":0,"s:27:2:27:Infinity":2,"f:31:16:31:36":2,"b:32:2:36:Infinity:undefined:undefined:undefined:undefined":1,"s:32:2:36:Infinity":3,"b:32:6:32:15:32:15:32:43:32:43:32:75":2,"s:33:4:35:Infinity":4,"f:40:16:40:Infinity":3,"b:43:15:43:Infinity":3,"s:45:2:50:Infinity":5,"f:58:16:58:Infinity":4,"s:63:42:67:Infinity":6,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":4,"s:68:2:68:Infinity":7,"s:68:17:68:Infinity":8,"b:69:2:69:Infinity:undefined:undefined:undefined:undefined":5,"s:69:2:69:Infinity":9,"s:69:17:69:Infinity":10,"s:70:2:70:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/response-parser.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/response-parser.ts","statementMap":{"0":{"start":{"line":21,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":35,"column":22},"end":{"line":35,"column":null}},"2":{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},"3":{"start":{"line":37,"column":17},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"7":{"start":{"line":66,"column":59},"end":{"line":66,"column":null}},"8":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},"9":{"start":{"line":67,"column":30},"end":{"line":67,"column":null}},"10":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"11":{"start":{"line":68,"column":48},"end":{"line":68,"column":null}},"12":{"start":{"line":70,"column":34},"end":{"line":74,"column":null}},"13":{"start":{"line":75,"column":19},"end":{"line":75,"column":null}},"14":{"start":{"line":76,"column":23},"end":{"line":76,"column":null}},"15":{"start":{"line":77,"column":24},"end":{"line":80,"column":null}},"16":{"start":{"line":78,"column":24},"end":{"line":78,"column":null}},"17":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"18":{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},"19":{"start":{"line":82,"column":4},"end":{"line":84,"column":null}},"20":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"21":{"start":{"line":88,"column":2},"end":{"line":95,"column":null}},"22":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"23":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"24":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"25":{"start":{"line":109,"column":18},"end":{"line":109,"column":null}},"26":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"27":{"start":{"line":110,"column":52},"end":{"line":110,"column":null}},"28":{"start":{"line":112,"column":2},"end":{"line":130,"column":null}},"29":{"start":{"line":113,"column":19},"end":{"line":113,"column":null}},"30":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"31":{"start":{"line":114,"column":32},"end":{"line":114,"column":null}},"32":{"start":{"line":116,"column":23},"end":{"line":116,"column":null}},"33":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"34":{"start":{"line":117,"column":21},"end":{"line":117,"column":null}},"35":{"start":{"line":119,"column":27},"end":{"line":119,"column":null}},"36":{"start":{"line":120,"column":24},"end":{"line":120,"column":null}},"37":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"38":{"start":{"line":121,"column":22},"end":{"line":121,"column":null}},"39":{"start":{"line":123,"column":4},"end":{"line":127,"column":null}},"40":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"41":{"start":{"line":126,"column":6},"end":{"line":126,"column":null}},"42":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}}},"fnMap":{"0":{"name":"getResponseContentType","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":39}},"loc":{"start":{"line":20,"column":11},"end":{"line":24,"column":null}},"line":20},"1":{"name":"parseJsonRpcEnvelope","decl":{"start":{"line":30,"column":22},"end":{"line":30,"column":43}},"loc":{"start":{"line":34,"column":29},"end":{"line":41,"column":null}},"line":34},"2":{"name":"readGatewayPayload","decl":{"start":{"line":63,"column":22},"end":{"line":63,"column":null}},"loc":{"start":{"line":65,"column":43},"end":{"line":96,"column":null}},"line":65},"3":{"name":"(anonymous_3)","decl":{"start":{"line":77,"column":37},"end":{"line":77,"column":43}},"loc":{"start":{"line":77,"column":52},"end":{"line":80,"column":3}},"line":77},"4":{"name":"resolveResultContent","decl":{"start":{"line":106,"column":22},"end":{"line":106,"column":null}},"loc":{"start":{"line":108,"column":36},"end":{"line":131,"column":null}},"line":108}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":9},"end":{"line":23,"column":null}},"type":"cond-expr","locations":[{"start":{"line":22,"column":7},"end":{"line":22,"column":null}},{"start":{"line":23,"column":6},"end":{"line":23,"column":null}}],"line":21},"1":{"loc":{"start":{"line":21,"column":9},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":9},"end":{"line":21,"column":29}},{"start":{"line":21,"column":29},"end":{"line":21,"column":null}}],"line":21},"2":{"loc":{"start":{"line":22,"column":7},"end":{"line":22,"column":null}},"type":"binary-expr","locations":[{"start":{"line":22,"column":7},"end":{"line":22,"column":47}},{"start":{"line":22,"column":47},"end":{"line":22,"column":null}}],"line":22},"3":{"loc":{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":36},"4":{"loc":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":66},"5":{"loc":{"start":{"line":66,"column":6},"end":{"line":66,"column":59}},"type":"binary-expr","locations":[{"start":{"line":66,"column":6},"end":{"line":66,"column":37}},{"start":{"line":66,"column":37},"end":{"line":66,"column":59}}],"line":66},"6":{"loc":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"7":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"8":{"loc":{"start":{"line":78,"column":24},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":53},"end":{"line":78,"column":60}},{"start":{"line":78,"column":60},"end":{"line":78,"column":null}}],"line":78},"9":{"loc":{"start":{"line":79,"column":11},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":11},"end":{"line":79,"column":32}},{"start":{"line":79,"column":32},"end":{"line":79,"column":null}}],"line":79},"10":{"loc":{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":2},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":81},"11":{"loc":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},{"start":{},"end":{}}],"line":110},"12":{"loc":{"start":{"line":110,"column":6},"end":{"line":110,"column":52}},"type":"binary-expr","locations":[{"start":{"line":110,"column":6},"end":{"line":110,"column":33}},{"start":{"line":110,"column":33},"end":{"line":110,"column":52}}],"line":110},"13":{"loc":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},{"start":{},"end":{}}],"line":114},"14":{"loc":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":117},"15":{"loc":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":121}},"s":{"0":107,"1":107,"2":107,"3":0,"4":0,"5":107,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":104,"26":104,"27":103,"28":1,"29":1,"30":1,"31":1,"32":0,"33":0,"34":0,"35":0,"36":0,"37":104,"38":0,"39":0,"40":0,"41":0,"42":0},"f":{"0":107,"1":107,"2":0,"3":0,"4":104},"b":{"0":[107,0],"1":[107,107],"2":[107,95],"3":[0,107],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[103,1],"12":[104,1],"13":[1,0],"14":[0,0],"15":[0,104]},"meta":{"lastBranch":16,"lastFunction":5,"lastStatement":43,"seen":{"f:18:16:18:39":0,"s:21:2:23:Infinity":0,"b:22:7:22:Infinity:23:6:23:Infinity":0,"b:21:9:21:29:21:29:21:Infinity":1,"b:22:7:22:47:22:47:22:Infinity":2,"f:30:22:30:43":1,"s:35:22:35:Infinity":1,"b:36:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:36:2:39:Infinity":2,"s:37:17:37:Infinity":3,"s:38:4:38:Infinity":4,"s:40:2:40:Infinity":5,"f:63:22:63:Infinity":2,"b:66:2:66:Infinity:undefined:undefined:undefined:undefined":4,"s:66:2:66:Infinity":6,"b:66:6:66:37:66:37:66:59":5,"s:66:59:66:Infinity":7,"b:67:2:67:Infinity:undefined:undefined:undefined:undefined":6,"s:67:2:67:Infinity":8,"s:67:30:67:Infinity":9,"b:68:2:68:Infinity:undefined:undefined:undefined:undefined":7,"s:68:2:68:Infinity":10,"s:68:48:68:Infinity":11,"s:70:34:74:Infinity":12,"s:75:19:75:Infinity":13,"s:76:23:76:Infinity":14,"s:77:24:80:Infinity":15,"f:77:37:77:43":3,"s:78:24:78:Infinity":16,"b:78:53:78:60:78:60:78:Infinity":8,"s:79:4:79:Infinity":17,"b:79:11:79:32:79:32:79:Infinity":9,"b:81:2:86:Infinity:undefined:undefined:undefined:undefined":10,"s:81:2:86:Infinity":18,"s:82:4:84:Infinity":19,"s:85:4:85:Infinity":20,"s:88:2:95:Infinity":21,"s:89:4:89:Infinity":22,"s:91:4:93:Infinity":23,"s:94:4:94:Infinity":24,"f:106:22:106:Infinity":4,"s:109:18:109:Infinity":25,"b:110:2:110:Infinity:undefined:undefined:undefined:undefined":11,"s:110:2:110:Infinity":26,"b:110:6:110:33:110:33:110:52":12,"s:110:52:110:Infinity":27,"s:112:2:130:Infinity":28,"s:113:19:113:Infinity":29,"b:114:4:114:Infinity:undefined:undefined:undefined:undefined":13,"s:114:4:114:Infinity":30,"s:114:32:114:Infinity":31,"s:116:23:116:Infinity":32,"b:117:4:117:Infinity:undefined:undefined:undefined:undefined":14,"s:117:4:117:Infinity":33,"s:117:21:117:Infinity":34,"s:119:27:119:Infinity":35,"s:120:24:120:Infinity":36,"b:121:4:121:Infinity:undefined:undefined:undefined:undefined":15,"s:121:4:121:Infinity":37,"s:121:22:121:Infinity":38,"s:123:4:127:Infinity":39,"s:124:6:124:Infinity":40,"s:126:6:126:Infinity":41,"s:129:4:129:Infinity":42}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/session.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/session.ts","statementMap":{"0":{"start":{"line":21,"column":16},"end":{"line":21,"column":null}},"1":{"start":{"line":22,"column":2},"end":{"line":26,"column":null}},"2":{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},"3":{"start":{"line":24,"column":6},"end":{"line":24,"column":null}},"4":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"5":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"6":{"start":{"line":47,"column":39},"end":{"line":47,"column":null}},"7":{"start":{"line":49,"column":21},"end":{"line":49,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":50,"column":37},"end":{"line":50,"column":57}},"10":{"start":{"line":52,"column":2},"end":{"line":104,"column":null}},"11":{"start":{"line":53,"column":44},"end":{"line":57,"column":null}},"12":{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},"13":{"start":{"line":58,"column":23},"end":{"line":58,"column":null}},"14":{"start":{"line":60,"column":21},"end":{"line":74,"column":null}},"15":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"16":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"17":{"start":{"line":81,"column":6},"end":{"line":83,"column":null}},"18":{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},"19":{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},"20":{"start":{"line":87,"column":6},"end":{"line":87,"column":null}},"21":{"start":{"line":90,"column":4},"end":{"line":101,"column":null}},"22":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}}},"fnMap":{"0":{"name":"parseSSEResponse","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":33}},"loc":{"start":{"line":20,"column":64},"end":{"line":28,"column":null}},"line":20},"1":{"name":"initializeSession","decl":{"start":{"line":46,"column":22},"end":{"line":46,"column":40}},"loc":{"start":{"line":46,"column":80},"end":{"line":105,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":50,"column":20},"end":{"line":50,"column":37}},"loc":{"start":{"line":50,"column":37},"end":{"line":50,"column":57}},"line":50}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":25,"column":null}},{"start":{},"end":{}}],"line":23},"1":{"loc":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":47,"column":6},"end":{"line":47,"column":39}},"type":"binary-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":39}}],"line":47},"3":{"loc":{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":58},"4":{"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76},"5":{"loc":{"start":{"line":81,"column":6},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":82,"column":10},"end":{"line":82,"column":null}},{"start":{"line":83,"column":10},"end":{"line":83,"column":null}}],"line":81},"6":{"loc":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":6},"end":{"line":81,"column":26}},{"start":{"line":81,"column":26},"end":{"line":81,"column":null}}],"line":81},"7":{"loc":{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":85},"8":{"loc":{"start":{"line":94,"column":12},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":28},"end":{"line":94,"column":66}},{"start":{"line":94,"column":66},"end":{"line":94,"column":null}}],"line":94}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":1,"8":1,"9":0,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":0,"17":1,"18":1,"19":0,"20":0,"21":1,"22":1},"f":{"0":0,"1":1,"2":0},"b":{"0":[0,0],"1":[0,1],"2":[1,1],"3":[1,0],"4":[0,1],"5":[1,0],"6":[1,1],"7":[0,1],"8":[0,1]},"meta":{"lastBranch":9,"lastFunction":3,"lastStatement":23,"seen":{"f:20:16:20:33":0,"s:21:16:21:Infinity":0,"s:22:2:26:Infinity":1,"b:23:4:25:Infinity:undefined:undefined:undefined:undefined":0,"s:23:4:25:Infinity":2,"s:24:6:24:Infinity":3,"s:27:2:27:Infinity":4,"f:46:22:46:40":1,"b:47:2:47:Infinity:undefined:undefined:undefined:undefined":1,"s:47:2:47:Infinity":5,"b:47:6:47:23:47:23:47:39":2,"s:47:39:47:Infinity":6,"s:49:21:49:Infinity":7,"s:50:20:50:Infinity":8,"f:50:20:50:37":2,"s:50:37:50:57":9,"s:52:2:104:Infinity":10,"s:53:44:57:Infinity":11,"b:58:4:58:Infinity:undefined:undefined:undefined:undefined":3,"s:58:4:58:Infinity":12,"s:58:23:58:Infinity":13,"s:60:21:74:Infinity":14,"b:76:4:78:Infinity:undefined:undefined:undefined:undefined":4,"s:76:4:78:Infinity":15,"s:77:6:77:Infinity":16,"s:81:6:83:Infinity":17,"b:82:10:82:Infinity:83:10:83:Infinity":5,"b:81:6:81:26:81:26:81:Infinity":6,"b:85:4:88:Infinity:undefined:undefined:undefined:undefined":7,"s:85:4:88:Infinity":18,"s:86:6:86:Infinity":19,"s:87:6:87:Infinity":20,"s:90:4:101:Infinity":21,"b:94:28:94:66:94:66:94:Infinity":8,"s:103:4:103:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/retry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/retry.ts","statementMap":{"0":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"1":{"start":{"line":40,"column":8},"end":{"line":40,"column":null}},"2":{"start":{"line":41,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"calculateRetryDelay","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":36}},"loc":{"start":{"line":25,"column":64},"end":{"line":27,"column":null}},"line":25},"1":{"name":"isRetryableNetworkError","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":40}},"loc":{"start":{"line":39,"column":61},"end":{"line":48,"column":null}},"line":39}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":20},"end":{"line":40,"column":37}},"type":"binary-expr","locations":[{"start":{"line":40,"column":20},"end":{"line":40,"column":35}},{"start":{"line":40,"column":35},"end":{"line":40,"column":37}}],"line":40},"1":{"loc":{"start":{"line":42,"column":4},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},{"start":{"line":46,"column":4},"end":{"line":46,"column":null}}],"line":42}},"s":{"0":16,"1":28,"2":28},"f":{"0":16,"1":28},"b":{"0":[28,0],"1":[28,27,16,14,13]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":3,"seen":{"f:25:16:25:36":0,"s:26:2:26:Infinity":0,"f:39:16:39:40":1,"s:40:8:40:Infinity":1,"b:40:20:40:35:40:35:40:37":0,"s:41:2:46:Infinity":2,"b:42:4:42:Infinity:43:4:43:Infinity:44:4:44:Infinity:45:4:45:Infinity:46:4:46:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/timeout.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/mcp-client/transport/timeout.ts","statementMap":{"0":{"start":{"line":13,"column":45},"end":{"line":13,"column":null}},"1":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"2":{"start":{"line":26,"column":18},"end":{"line":26,"column":null}},"3":{"start":{"line":26,"column":35},"end":{"line":26,"column":55}},"4":{"start":{"line":27,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":28,"column":21},"end":{"line":31,"column":null}},"6":{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":33,"column":6},"end":{"line":33,"column":null}},"8":{"start":{"line":34,"column":6},"end":{"line":34,"column":null}},"9":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"10":{"start":{"line":40,"column":4},"end":{"line":40,"column":null}},"11":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"12":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}}},"fnMap":{"0":{"name":"fetchExternalUrlText","decl":{"start":{"line":21,"column":22},"end":{"line":21,"column":null}},"loc":{"start":{"line":24,"column":26},"end":{"line":45,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":26,"column":18},"end":{"line":26,"column":35}},"loc":{"start":{"line":26,"column":35},"end":{"line":26,"column":55}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"default-arg","locations":[{"start":{"line":23,"column":22},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":32}},"s":{"0":34,"1":7,"2":7,"3":2,"4":7,"5":7,"6":4,"7":1,"8":1,"9":3,"10":4,"11":4,"12":7},"f":{"0":7,"1":2},"b":{"0":[7],"1":[1,3]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":13,"seen":{"s:13:45:13:Infinity":0,"f:21:22:21:Infinity":0,"b:23:22:23:Infinity":0,"s:25:21:25:Infinity":1,"s:26:18:26:Infinity":2,"f:26:18:26:35":1,"s:26:35:26:55":3,"s:27:2:44:Infinity":4,"s:28:21:31:Infinity":5,"b:32:4:35:Infinity:undefined:undefined:undefined:undefined":1,"s:32:4:35:Infinity":6,"s:33:6:33:Infinity":7,"s:34:6:34:Infinity":8,"s:38:4:38:Infinity":9,"s:40:4:40:Infinity":10,"s:41:4:41:Infinity":11,"s:43:4:43:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/full-text-threshold.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/full-text-threshold.ts","statementMap":{"0":{"start":{"line":7,"column":36},"end":{"line":7,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":34},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:7:36:7:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/optimize-images.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/optimize-images.ts","statementMap":{"0":{"start":{"line":1,"column":9},"end":{"line":1,"column":null}},"1":{"start":{"line":1,"column":22},"end":{"line":1,"column":null}},"2":{"start":{"line":7,"column":17},"end":{"line":7,"column":null}},"3":{"start":{"line":8,"column":17},"end":{"line":8,"column":null}},"4":{"start":{"line":30,"column":61},"end":{"line":73,"column":null}},"5":{"start":{"line":76,"column":19},"end":{"line":76,"column":null}},"6":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"7":{"start":{"line":81,"column":2},"end":{"line":88,"column":null}},"8":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"9":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"10":{"start":{"line":87,"column":6},"end":{"line":87,"column":null}},"11":{"start":{"line":92,"column":16},"end":{"line":92,"column":null}},"12":{"start":{"line":93,"column":17},"end":{"line":93,"column":null}},"13":{"start":{"line":94,"column":19},"end":{"line":96,"column":null}},"14":{"start":{"line":97,"column":2},"end":{"line":97,"column":null}},"15":{"start":{"line":101,"column":16},"end":{"line":101,"column":null}},"16":{"start":{"line":102,"column":17},"end":{"line":102,"column":null}},"17":{"start":{"line":103,"column":19},"end":{"line":111,"column":null}},"18":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"19":{"start":{"line":116,"column":2},"end":{"line":116,"column":null}},"20":{"start":{"line":117,"column":2},"end":{"line":131,"column":null}},"21":{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},"22":{"start":{"line":119,"column":6},"end":{"line":123,"column":null}},"23":{"start":{"line":120,"column":8},"end":{"line":122,"column":null}},"24":{"start":{"line":121,"column":10},"end":{"line":121,"column":null}},"25":{"start":{"line":125,"column":6},"end":{"line":129,"column":null}},"26":{"start":{"line":126,"column":8},"end":{"line":128,"column":null}},"27":{"start":{"line":127,"column":10},"end":{"line":127,"column":null}},"28":{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},"29":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"30":{"start":{"line":136,"column":2},"end":{"line":136,"column":null}}},"fnMap":{"0":{"name":"variantName","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":28}},"loc":{"start":{"line":75,"column":89},"end":{"line":78,"column":null}},"line":75},"1":{"name":"encode","decl":{"start":{"line":80,"column":15},"end":{"line":80,"column":22}},"loc":{"start":{"line":80,"column":75},"end":{"line":89,"column":null}},"line":80},"2":{"name":"writeWidthVariant","decl":{"start":{"line":91,"column":15},"end":{"line":91,"column":33}},"loc":{"start":{"line":91,"column":108},"end":{"line":98,"column":null}},"line":91},"3":{"name":"writeSquareVariant","decl":{"start":{"line":100,"column":15},"end":{"line":100,"column":34}},"loc":{"start":{"line":100,"column":109},"end":{"line":113,"column":null}},"line":100},"4":{"name":"optimizeImages","decl":{"start":{"line":115,"column":22},"end":{"line":115,"column":54}},"loc":{"start":{"line":115,"column":54},"end":{"line":132,"column":null}},"line":115}},"branchMap":{"0":{"loc":{"start":{"line":81,"column":2},"end":{"line":88,"column":null}},"type":"switch","locations":[{"start":{"line":82,"column":4},"end":{"line":83,"column":null}},{"start":{"line":84,"column":4},"end":{"line":85,"column":null}},{"start":{"line":86,"column":4},"end":{"line":87,"column":null}}],"line":81},"1":{"loc":{"start":{"line":95,"column":26},"end":{"line":95,"column":47}},"type":"binary-expr","locations":[{"start":{"line":95,"column":26},"end":{"line":95,"column":37}},{"start":{"line":95,"column":37},"end":{"line":95,"column":47}}],"line":95},"2":{"loc":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"type":"binary-expr","locations":[{"start":{"line":108,"column":18},"end":{"line":108,"column":36}},{"start":{"line":108,"column":36},"end":{"line":108,"column":null}}],"line":108},"3":{"loc":{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":4},"end":{"line":130,"column":null}},{"start":{"line":124,"column":11},"end":{"line":130,"column":null}}],"line":118},"4":{"loc":{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":0},"end":{"line":137,"column":null}},{"start":{},"end":{}}],"line":134},"5":{"loc":{"start":{"line":134,"column":4},"end":{"line":134,"column":80}},"type":"binary-expr","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":23}},{"start":{"line":134,"column":23},"end":{"line":134,"column":80}}],"line":134}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":44,"6":44,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":1,"29":0,"30":0},"f":{"0":44,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0,0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,1],"5":[1,1]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":31,"seen":{"s:1:9:1:Infinity":0,"s:1:22:1:Infinity":1,"s:7:17:7:Infinity":2,"s:8:17:8:Infinity":3,"s:30:61:73:Infinity":4,"f:75:16:75:28":0,"s:76:19:76:Infinity":5,"s:77:2:77:Infinity":6,"f:80:15:80:22":1,"b:82:4:83:Infinity:84:4:85:Infinity:86:4:87:Infinity":0,"s:81:2:88:Infinity":7,"s:83:6:83:Infinity":8,"s:85:6:85:Infinity":9,"s:87:6:87:Infinity":10,"f:91:15:91:33":2,"s:92:16:92:Infinity":11,"s:93:17:93:Infinity":12,"s:94:19:96:Infinity":13,"b:95:26:95:37:95:37:95:47":1,"s:97:2:97:Infinity":14,"f:100:15:100:34":3,"s:101:16:101:Infinity":15,"s:102:17:102:Infinity":16,"s:103:19:111:Infinity":17,"b:108:18:108:36:108:36:108:Infinity":2,"s:112:2:112:Infinity":18,"f:115:22:115:54":4,"s:116:2:116:Infinity":19,"s:117:2:131:Infinity":20,"b:118:4:130:Infinity:124:11:130:Infinity":3,"s:118:4:130:Infinity":21,"s:119:6:123:Infinity":22,"s:120:8:122:Infinity":23,"s:121:10:121:Infinity":24,"s:125:6:129:Infinity":25,"s:126:8:128:Infinity":26,"s:127:10:127:Infinity":27,"b:134:0:137:Infinity:undefined:undefined:undefined:undefined":4,"s:134:0:137:Infinity":28,"b:134:4:134:23:134:23:134:80":5,"s:135:2:135:Infinity":29,"s:136:2:136:Infinity":30}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/index.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/index.ts","statementMap":{"0":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"1":{"start":{"line":60,"column":14},"end":{"line":60,"column":null}},"2":{"start":{"line":61,"column":16},"end":{"line":61,"column":null}},"3":{"start":{"line":62,"column":42},"end":{"line":62,"column":null}},"4":{"start":{"line":63,"column":69},"end":{"line":63,"column":null}},"5":{"start":{"line":64,"column":56},"end":{"line":64,"column":null}},"6":{"start":{"line":65,"column":53},"end":{"line":65,"column":null}},"7":{"start":{"line":66,"column":29},"end":{"line":66,"column":null}},"8":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"10":{"start":{"line":70,"column":17},"end":{"line":70,"column":null}},"11":{"start":{"line":71,"column":16},"end":{"line":71,"column":null}},"12":{"start":{"line":73,"column":2},"end":{"line":105,"column":null}},"13":{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},"14":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"15":{"start":{"line":76,"column":6},"end":{"line":76,"column":null}},"16":{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},"17":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"18":{"start":{"line":80,"column":6},"end":{"line":80,"column":null}},"19":{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},"20":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"21":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"22":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"23":{"start":{"line":90,"column":6},"end":{"line":92,"column":null}},"24":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"25":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"26":{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},"27":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"28":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"29":{"start":{"line":98,"column":28},"end":{"line":98,"column":null}},"30":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"31":{"start":{"line":99,"column":30},"end":{"line":99,"column":null}},"32":{"start":{"line":100,"column":6},"end":{"line":100,"column":null}},"33":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"34":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"35":{"start":{"line":107,"column":42},"end":{"line":111,"column":null}},"36":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"37":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"38":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"39":{"start":{"line":122,"column":2},"end":{"line":131,"column":null}}},"fnMap":{"0":{"name":"drainMcpRetryQueue","decl":{"start":{"line":50,"column":22},"end":{"line":50,"column":null}},"loc":{"start":{"line":58,"column":32},"end":{"line":132,"column":null}},"line":58}},"branchMap":{"0":{"loc":{"start":{"line":52,"column":2},"end":{"line":57,"column":null}},"type":"default-arg","locations":[{"start":{"line":57,"column":6},"end":{"line":57,"column":null}}],"line":52},"1":{"loc":{"start":{"line":59,"column":20},"end":{"line":59,"column":null}},"type":"binary-expr","locations":[{"start":{"line":59,"column":20},"end":{"line":59,"column":41}},{"start":{"line":59,"column":41},"end":{"line":59,"column":null}}],"line":59},"2":{"loc":{"start":{"line":60,"column":14},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":14},"end":{"line":60,"column":29}},{"start":{"line":60,"column":29},"end":{"line":60,"column":null}}],"line":60},"3":{"loc":{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":74},"4":{"loc":{"start":{"line":74,"column":8},"end":{"line":74,"column":79}},"type":"binary-expr","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":27}},{"start":{"line":74,"column":27},"end":{"line":74,"column":44}},{"start":{"line":74,"column":44},"end":{"line":74,"column":79}}],"line":74},"5":{"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":78},"6":{"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":82},"7":{"loc":{"start":{"line":82,"column":8},"end":{"line":82,"column":63}},"type":"binary-expr","locations":[{"start":{"line":82,"column":8},"end":{"line":82,"column":30}},{"start":{"line":82,"column":30},"end":{"line":82,"column":63}}],"line":82},"8":{"loc":{"start":{"line":90,"column":6},"end":{"line":92,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":10},"end":{"line":91,"column":null}},{"start":{"line":92,"column":10},"end":{"line":92,"column":null}}],"line":90},"9":{"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":94},"10":{"loc":{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},"type":"if","locations":[{"start":{"line":96,"column":4},"end":{"line":101,"column":null}},{"start":{},"end":{}}],"line":96},"11":{"loc":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":98},"12":{"loc":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":99},"13":{"loc":{"start":{"line":117,"column":18},"end":{"line":117,"column":null}},"type":"binary-expr","locations":[{"start":{"line":117,"column":18},"end":{"line":117,"column":44}},{"start":{"line":117,"column":44},"end":{"line":117,"column":61}},{"start":{"line":117,"column":61},"end":{"line":117,"column":76}},{"start":{"line":117,"column":76},"end":{"line":117,"column":null}}],"line":117},"14":{"loc":{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":2},"end":{"line":120,"column":null}},{"start":{},"end":{}}],"line":118}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":3,"13":3,"14":0,"15":0,"16":3,"17":0,"18":0,"19":3,"20":0,"21":0,"22":3,"23":3,"24":0,"25":0,"26":3,"27":2,"28":2,"29":2,"30":2,"31":0,"32":2,"33":1,"34":1,"35":3,"36":3,"37":3,"38":2,"39":3},"f":{"0":3},"b":{"0":[3],"1":[3,0],"2":[3,3],"3":[0,3],"4":[3,0,0],"5":[0,3],"6":[0,3],"7":[3,0],"8":[3,0],"9":[3,-3],"10":[2,1],"11":[2,0],"12":[0,2],"13":[3,1,1,1],"14":[2,1]},"meta":{"lastBranch":15,"lastFunction":1,"lastStatement":40,"seen":{"f:50:22:50:Infinity":0,"b:57:6:57:Infinity":0,"s:59:20:59:Infinity":0,"b:59:20:59:41:59:41:59:Infinity":1,"s:60:14:60:Infinity":1,"b:60:14:60:29:60:29:60:Infinity":2,"s:61:16:61:Infinity":2,"s:62:42:62:Infinity":3,"s:63:69:63:Infinity":4,"s:64:56:64:Infinity":5,"s:65:53:65:Infinity":6,"s:66:29:66:Infinity":7,"s:68:18:68:Infinity":8,"s:69:17:69:Infinity":9,"s:70:17:70:Infinity":10,"s:71:16:71:Infinity":11,"s:73:2:105:Infinity":12,"b:74:4:77:Infinity:undefined:undefined:undefined:undefined":3,"s:74:4:77:Infinity":13,"b:74:8:74:27:74:27:74:44:74:44:74:79":4,"s:75:6:75:Infinity":14,"s:76:6:76:Infinity":15,"b:78:4:81:Infinity:undefined:undefined:undefined:undefined":5,"s:78:4:81:Infinity":16,"s:79:6:79:Infinity":17,"s:80:6:80:Infinity":18,"b:82:4:85:Infinity:undefined:undefined:undefined:undefined":6,"s:82:4:85:Infinity":19,"b:82:8:82:30:82:30:82:63":7,"s:83:6:83:Infinity":20,"s:84:6:84:Infinity":21,"s:87:4:87:Infinity":22,"s:90:6:92:Infinity":23,"b:91:10:91:Infinity:92:10:92:Infinity":8,"b:94:4:94:Infinity:undefined:undefined:undefined:undefined":9,"s:94:4:94:Infinity":24,"s:94:28:94:Infinity":25,"b:96:4:101:Infinity:undefined:undefined:undefined:undefined":10,"s:96:4:101:Infinity":26,"s:97:6:97:Infinity":27,"b:98:6:98:Infinity:undefined:undefined:undefined:undefined":11,"s:98:6:98:Infinity":28,"s:98:28:98:Infinity":29,"b:99:6:99:Infinity:undefined:undefined:undefined:undefined":12,"s:99:6:99:Infinity":30,"s:99:30:99:Infinity":31,"s:100:6:100:Infinity":32,"s:103:4:103:Infinity":33,"s:104:4:104:Infinity":34,"s:107:42:111:Infinity":35,"s:117:18:117:Infinity":36,"b:117:18:117:44:117:44:117:61:117:61:117:76:117:76:117:Infinity":13,"b:118:2:120:Infinity:undefined:undefined:undefined:undefined":14,"s:118:2:120:Infinity":37,"s:119:4:119:Infinity":38,"s:122:2:131:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/classifier.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/classifier.ts","statementMap":{"0":{"start":{"line":43,"column":24},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":2},"end":{"line":111,"column":null}},"2":{"start":{"line":45,"column":19},"end":{"line":52,"column":null}},"3":{"start":{"line":54,"column":52},"end":{"line":61,"column":null}},"4":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"5":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"6":{"start":{"line":67,"column":4},"end":{"line":77,"column":null}},"7":{"start":{"line":79,"column":23},"end":{"line":79,"column":null}},"8":{"start":{"line":80,"column":4},"end":{"line":83,"column":null}},"9":{"start":{"line":84,"column":4},"end":{"line":110,"column":null}},"10":{"start":{"line":119,"column":24},"end":{"line":119,"column":null}},"11":{"start":{"line":120,"column":23},"end":{"line":120,"column":null}},"12":{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},"13":{"start":{"line":122,"column":4},"end":{"line":131,"column":null}},"14":{"start":{"line":134,"column":2},"end":{"line":203,"column":null}},"15":{"start":{"line":135,"column":25},"end":{"line":137,"column":null}},"16":{"start":{"line":139,"column":52},"end":{"line":147,"column":null}},"17":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"18":{"start":{"line":150,"column":6},"end":{"line":156,"column":null}},"19":{"start":{"line":159,"column":4},"end":{"line":169,"column":null}},"20":{"start":{"line":171,"column":23},"end":{"line":171,"column":null}},"21":{"start":{"line":172,"column":4},"end":{"line":175,"column":null}},"22":{"start":{"line":176,"column":4},"end":{"line":202,"column":null}}},"fnMap":{"0":{"name":"drainDocumentFulltextEntry","decl":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"loc":{"start":{"line":42,"column":25},"end":{"line":112,"column":null}},"line":42},"1":{"name":"drainVoteringarSearchEntry","decl":{"start":{"line":114,"column":22},"end":{"line":114,"column":null}},"loc":{"start":{"line":118,"column":25},"end":{"line":204,"column":null}},"line":118}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":24},"end":{"line":49,"column":80}},{"start":{"line":49,"column":80},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":16},"end":{"line":74,"column":32}},{"start":{"line":74,"column":32},"end":{"line":74,"column":null}}],"line":74},"3":{"loc":{"start":{"line":79,"column":23},"end":{"line":79,"column":null}},"type":"cond-expr","locations":[{"start":{"line":79,"column":51},"end":{"line":79,"column":70}},{"start":{"line":79,"column":70},"end":{"line":79,"column":null}}],"line":79},"4":{"loc":{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":121,"column":2},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":121},"5":{"loc":{"start":{"line":121,"column":6},"end":{"line":121,"column":65}},"type":"binary-expr","locations":[{"start":{"line":121,"column":6},"end":{"line":121,"column":42}},{"start":{"line":121,"column":42},"end":{"line":121,"column":65}}],"line":121},"6":{"loc":{"start":{"line":146,"column":10},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":32},"end":{"line":146,"column":66}},{"start":{"line":146,"column":66},"end":{"line":146,"column":null}}],"line":146},"7":{"loc":{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":4},"end":{"line":157,"column":null}},{"start":{},"end":{}}],"line":149},"8":{"loc":{"start":{"line":153,"column":20},"end":{"line":155,"column":null}},"type":"cond-expr","locations":[{"start":{"line":154,"column":13},"end":{"line":154,"column":null}},{"start":{"line":155,"column":12},"end":{"line":155,"column":null}}],"line":153},"9":{"loc":{"start":{"line":166,"column":16},"end":{"line":166,"column":null}},"type":"binary-expr","locations":[{"start":{"line":166,"column":16},"end":{"line":166,"column":48}},{"start":{"line":166,"column":48},"end":{"line":166,"column":null}}],"line":166},"10":{"loc":{"start":{"line":171,"column":23},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":171,"column":51},"end":{"line":171,"column":70}},{"start":{"line":171,"column":70},"end":{"line":171,"column":null}}],"line":171}},"s":{"0":3,"1":3,"2":3,"3":2,"4":2,"5":2,"6":0,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0},"f":{"0":3,"1":0},"b":{"0":[3,0],"1":[2,0],"2":[0,0],"3":[1,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0]},"meta":{"lastBranch":11,"lastFunction":2,"lastStatement":23,"seen":{"f:38:22:38:Infinity":0,"s:43:24:43:Infinity":0,"s:44:2:111:Infinity":1,"s:45:19:52:Infinity":2,"b:49:24:49:80:49:80:49:Infinity":0,"s:54:52:61:Infinity":3,"b:63:4:65:Infinity:undefined:undefined:undefined:undefined":1,"s:63:4:65:Infinity":4,"s:64:6:64:Infinity":5,"s:67:4:77:Infinity":6,"b:74:16:74:32:74:32:74:Infinity":2,"s:79:23:79:Infinity":7,"b:79:51:79:70:79:70:79:Infinity":3,"s:80:4:83:Infinity":8,"s:84:4:110:Infinity":9,"f:114:22:114:Infinity":1,"s:119:24:119:Infinity":10,"s:120:23:120:Infinity":11,"b:121:2:132:Infinity:undefined:undefined:undefined:undefined":4,"s:121:2:132:Infinity":12,"b:121:6:121:42:121:42:121:65":5,"s:122:4:131:Infinity":13,"s:134:2:203:Infinity":14,"s:135:25:137:Infinity":15,"s:139:52:147:Infinity":16,"b:146:32:146:66:146:66:146:Infinity":6,"b:149:4:157:Infinity:undefined:undefined:undefined:undefined":7,"s:149:4:157:Infinity":17,"s:150:6:156:Infinity":18,"b:154:13:154:Infinity:155:12:155:Infinity":8,"s:159:4:169:Infinity":19,"b:166:16:166:48:166:48:166:Infinity":9,"s:171:23:171:Infinity":20,"b:171:51:171:70:171:70:171:Infinity":10,"s:172:4:175:Infinity":21,"s:176:4:202:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/persistence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/persistence.ts","statementMap":{"0":{"start":{"line":17,"column":18},"end":{"line":17,"column":null}},"1":{"start":{"line":18,"column":18},"end":{"line":18,"column":null}},"2":{"start":{"line":20,"column":38},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":44},"end":{"line":25,"column":null}},"4":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"5":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"6":{"start":{"line":77,"column":33},"end":{"line":77,"column":null}},"7":{"start":{"line":78,"column":2},"end":{"line":87,"column":null}},"8":{"start":{"line":79,"column":19},"end":{"line":79,"column":null}},"9":{"start":{"line":80,"column":4},"end":{"line":84,"column":null}},"10":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"11":{"start":{"line":94,"column":2},"end":{"line":94,"column":null}},"12":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}}},"fnMap":{"0":{"name":"emptyQueue","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"loc":{"start":{"line":66,"column":21},"end":{"line":72,"column":null}},"line":66},"1":{"name":"loadMcpRetryQueue","decl":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"loc":{"start":{"line":76,"column":21},"end":{"line":88,"column":null}},"line":76},"2":{"name":"saveMcpRetryQueue","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":null}},"loc":{"start":{"line":93,"column":8},"end":{"line":96,"column":null}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"default-arg","locations":[{"start":{"line":65,"column":21},"end":{"line":65,"column":null}}],"line":65},"1":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"default-arg","locations":[{"start":{"line":75,"column":22},"end":{"line":75,"column":null}}],"line":75},"2":{"loc":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":77},"3":{"loc":{"start":{"line":81,"column":14},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":14},"end":{"line":81,"column":31}},{"start":{"line":81,"column":31},"end":{"line":81,"column":null}}],"line":81},"4":{"loc":{"start":{"line":82,"column":17},"end":{"line":82,"column":null}},"type":"binary-expr","locations":[{"start":{"line":82,"column":17},"end":{"line":82,"column":37}},{"start":{"line":82,"column":37},"end":{"line":82,"column":null}}],"line":82},"5":{"loc":{"start":{"line":83,"column":15},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":47},"end":{"line":83,"column":88}},{"start":{"line":83,"column":88},"end":{"line":83,"column":null}}],"line":83},"6":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"default-arg","locations":[{"start":{"line":92,"column":22},"end":{"line":92,"column":null}}],"line":92}},"s":{"0":3,"1":3,"2":3,"3":3,"4":4,"5":7,"6":4,"7":3,"8":3,"9":3,"10":0,"11":5,"12":5},"f":{"0":4,"1":7,"2":5},"b":{"0":[4],"1":[7],"2":[4,3],"3":[3,0],"4":[7,0],"5":[3,0],"6":[5]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":13,"seen":{"s:17:18:17:Infinity":0,"s:18:18:18:Infinity":1,"s:20:38:20:Infinity":2,"s:21:44:25:Infinity":3,"f:64:16:64:Infinity":0,"b:65:21:65:Infinity":0,"s:67:2:71:Infinity":4,"f:74:16:74:Infinity":1,"b:75:22:75:Infinity":1,"b:77:2:77:Infinity:undefined:undefined:undefined:undefined":2,"s:77:2:77:Infinity":5,"s:77:33:77:Infinity":6,"s:78:2:87:Infinity":7,"s:79:19:79:Infinity":8,"s:80:4:84:Infinity":9,"b:81:14:81:31:81:31:81:Infinity":3,"b:82:17:82:37:82:37:82:Infinity":4,"b:83:47:83:88:83:88:83:Infinity":5,"s:86:4:86:Infinity":10,"f:90:16:90:Infinity":2,"b:92:22:92:Infinity":6,"s:94:2:94:Infinity":11,"s:95:2:95:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/retry-policy.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/mcp-retry-queue/retry-policy.ts","statementMap":{"0":{"start":{"line":25,"column":28},"end":{"line":25,"column":null}},"1":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"2":{"start":{"line":39,"column":20},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":60,"column":16},"end":{"line":60,"column":null}},"5":{"start":{"line":61,"column":18},"end":{"line":61,"column":null}},"6":{"start":{"line":63,"column":2},"end":{"line":65,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"8":{"start":{"line":67,"column":2},"end":{"line":79,"column":null}},"9":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"10":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":78,"column":null}},"12":{"start":{"line":81,"column":37},"end":{"line":85,"column":null}},"13":{"start":{"line":84,"column":50},"end":{"line":84,"column":90}},"14":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"15":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}}},"fnMap":{"0":{"name":"createRetryQueueEntry","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":38}},"loc":{"start":{"line":37,"column":23},"end":{"line":54,"column":null}},"line":37},"1":{"name":"enqueueRetryEntries","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":59,"column":21},"end":{"line":88,"column":null}},"line":59},"2":{"name":"(anonymous_2)","decl":{"start":{"line":84,"column":35},"end":{"line":84,"column":41}},"loc":{"start":{"line":84,"column":50},"end":{"line":84,"column":90}},"line":84}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":22},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":22},"end":{"line":38,"column":45}},{"start":{"line":38,"column":45},"end":{"line":38,"column":null}}],"line":38},"1":{"loc":{"start":{"line":40,"column":40},"end":{"line":40,"column":88}},"type":"binary-expr","locations":[{"start":{"line":40,"column":40},"end":{"line":40,"column":65}},{"start":{"line":40,"column":65},"end":{"line":40,"column":88}}],"line":40},"2":{"loc":{"start":{"line":46,"column":13},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":32}},{"start":{"line":46,"column":32},"end":{"line":46,"column":null}}],"line":46},"3":{"loc":{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":25},"end":{"line":52,"column":54}},{"start":{"line":52,"column":54},"end":{"line":52,"column":null}}],"line":52},"4":{"loc":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}},"type":"default-arg","locations":[{"start":{"line":58,"column":22},"end":{"line":58,"column":null}}],"line":58},"5":{"loc":{"start":{"line":70,"column":21},"end":{"line":78,"column":13}},"type":"cond-expr","locations":[{"start":{"line":71,"column":8},"end":{"line":77,"column":null}},{"start":{"line":78,"column":8},"end":{"line":78,"column":13}}],"line":70}},"s":{"0":3,"1":5,"2":5,"3":5,"4":3,"5":3,"6":3,"7":0,"8":3,"9":5,"10":5,"11":5,"12":3,"13":1,"14":3,"15":3},"f":{"0":5,"1":3,"2":1},"b":{"0":[5,5],"1":[5,5],"2":[5,5],"3":[0,5],"4":[3],"5":[1,4]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":16,"seen":{"s:25:28:25:Infinity":0,"f:27:16:27:38":0,"s:38:22:38:Infinity":1,"b:38:22:38:45:38:45:38:Infinity":0,"s:39:20:41:Infinity":2,"b:40:40:40:65:40:65:40:88":1,"s:42:2:53:Infinity":3,"b:46:13:46:32:46:32:46:Infinity":2,"b:52:25:52:54:52:54:52:Infinity":3,"f:56:16:56:Infinity":1,"b:58:22:58:Infinity":4,"s:60:16:60:Infinity":4,"s:61:18:61:Infinity":5,"s:63:2:65:Infinity":6,"s:64:4:64:Infinity":7,"s:67:2:79:Infinity":8,"s:68:16:68:Infinity":9,"s:69:21:69:Infinity":10,"s:70:4:78:Infinity":11,"b:71:8:77:Infinity:78:8:78:13":5,"s:81:37:85:Infinity":12,"f:84:35:84:41":2,"s:84:50:84:90":13,"s:86:2:86:Infinity":14,"s:87:2:87:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/imf.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/imf.ts","statementMap":{"0":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"1":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"2":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"3":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"4":{"start":{"line":50,"column":2},"end":{"line":54,"column":null}},"5":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"6":{"start":{"line":57,"column":2},"end":{"line":68,"column":null}},"7":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"persistIMFData","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"loc":{"start":{"line":44,"column":10},"end":{"line":71,"column":null}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":43,"column":null}},"type":"default-arg","locations":[{"start":{"line":43,"column":6},"end":{"line":43,"column":null}}],"line":39},"1":{"loc":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":19},"end":{"line":45,"column":39}},{"start":{"line":45,"column":39},"end":{"line":45,"column":null}}],"line":45},"2":{"loc":{"start":{"line":64,"column":10},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":64,"column":29},"end":{"line":64,"column":62}},{"start":{"line":64,"column":62},"end":{"line":64,"column":null}}],"line":64},"3":{"loc":{"start":{"line":65,"column":10},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":38},"end":{"line":65,"column":89}},{"start":{"line":65,"column":89},"end":{"line":65,"column":null}}],"line":65}},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5},"f":{"0":5},"b":{"0":[5],"1":[5,0],"2":[2,3],"3":[2,3]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":8,"seen":{"f:35:16:35:Infinity":0,"b:43:6:43:Infinity":0,"s:45:19:45:Infinity":0,"b:45:19:45:39:45:39:45:Infinity":1,"s:46:14:46:Infinity":1,"s:47:2:47:Infinity":2,"s:49:19:49:Infinity":3,"s:50:2:54:Infinity":4,"s:56:23:56:Infinity":5,"s:57:2:68:Infinity":6,"b:64:29:64:62:64:62:64:Infinity":2,"b:65:38:65:89:65:89:65:Infinity":3,"s:70:2:70:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/documents.ts","statementMap":{"0":{"start":{"line":51,"column":58},"end":{"line":59,"column":null}},"1":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"2":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"3":{"start":{"line":63,"column":16},"end":{"line":63,"column":null}},"4":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"5":{"start":{"line":66,"column":38},"end":{"line":74,"column":null}},"6":{"start":{"line":76,"column":2},"end":{"line":123,"column":null}},"7":{"start":{"line":77,"column":17},"end":{"line":77,"column":null}},"8":{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},"9":{"start":{"line":79,"column":6},"end":{"line":79,"column":null}},"10":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"11":{"start":{"line":83,"column":42},"end":{"line":88,"column":null}},"12":{"start":{"line":90,"column":20},"end":{"line":90,"column":null}},"13":{"start":{"line":91,"column":4},"end":{"line":122,"column":null}},"14":{"start":{"line":91,"column":17},"end":{"line":91,"column":20}},"15":{"start":{"line":92,"column":18},"end":{"line":92,"column":null}},"16":{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},"17":{"start":{"line":94,"column":8},"end":{"line":94,"column":null}},"18":{"start":{"line":95,"column":8},"end":{"line":95,"column":null}},"19":{"start":{"line":98,"column":18},"end":{"line":98,"column":null}},"20":{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},"21":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"22":{"start":{"line":101,"column":8},"end":{"line":101,"column":null}},"23":{"start":{"line":101,"column":50},"end":{"line":101,"column":null}},"24":{"start":{"line":102,"column":8},"end":{"line":102,"column":null}},"25":{"start":{"line":104,"column":6},"end":{"line":104,"column":null}},"26":{"start":{"line":105,"column":23},"end":{"line":105,"column":null}},"27":{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},"28":{"start":{"line":108,"column":25},"end":{"line":110,"column":null}},"29":{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},"30":{"start":{"line":112,"column":30},"end":{"line":112,"column":null}},"31":{"start":{"line":113,"column":10},"end":{"line":116,"column":null}},"32":{"start":{"line":120,"column":6},"end":{"line":120,"column":null}},"33":{"start":{"line":121,"column":6},"end":{"line":121,"column":null}},"34":{"start":{"line":125,"column":2},"end":{"line":125,"column":null}},"35":{"start":{"line":137,"column":20},"end":{"line":137,"column":null}},"36":{"start":{"line":138,"column":16},"end":{"line":138,"column":null}},"37":{"start":{"line":139,"column":16},"end":{"line":139,"column":null}},"38":{"start":{"line":141,"column":2},"end":{"line":163,"column":null}},"39":{"start":{"line":141,"column":15},"end":{"line":141,"column":18}},"40":{"start":{"line":142,"column":18},"end":{"line":142,"column":null}},"41":{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},"42":{"start":{"line":143,"column":18},"end":{"line":143,"column":29}},"43":{"start":{"line":143,"column":29},"end":{"line":143,"column":39}},"44":{"start":{"line":145,"column":19},"end":{"line":145,"column":null}},"45":{"start":{"line":146,"column":20},"end":{"line":150,"column":null}},"46":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"47":{"start":{"line":153,"column":21},"end":{"line":153,"column":null}},"48":{"start":{"line":155,"column":20},"end":{"line":155,"column":null}},"49":{"start":{"line":156,"column":4},"end":{"line":161,"column":null}},"50":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"51":{"start":{"line":165,"column":2},"end":{"line":165,"column":null}},"52":{"start":{"line":177,"column":20},"end":{"line":177,"column":null}},"53":{"start":{"line":178,"column":16},"end":{"line":178,"column":null}},"54":{"start":{"line":179,"column":16},"end":{"line":179,"column":null}},"55":{"start":{"line":181,"column":2},"end":{"line":197,"column":null}},"56":{"start":{"line":181,"column":15},"end":{"line":181,"column":18}},"57":{"start":{"line":182,"column":15},"end":{"line":182,"column":null}},"58":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"59":{"start":{"line":183,"column":15},"end":{"line":183,"column":26}},"60":{"start":{"line":183,"column":26},"end":{"line":183,"column":36}},"61":{"start":{"line":185,"column":19},"end":{"line":185,"column":null}},"62":{"start":{"line":186,"column":16},"end":{"line":187,"column":null}},"63":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"64":{"start":{"line":190,"column":4},"end":{"line":195,"column":null}},"65":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"66":{"start":{"line":199,"column":2},"end":{"line":199,"column":null}}},"fnMap":{"0":{"name":"persistDownloadedData","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"loc":{"start":{"line":50,"column":21},"end":{"line":126,"column":null}},"line":50},"1":{"name":"persistEvents","decl":{"start":{"line":132,"column":16},"end":{"line":132,"column":null}},"loc":{"start":{"line":136,"column":21},"end":{"line":166,"column":null}},"line":136},"2":{"name":"persistMPs","decl":{"start":{"line":172,"column":16},"end":{"line":172,"column":null}},"loc":{"start":{"line":176,"column":21},"end":{"line":200,"column":null}},"line":176}},"branchMap":{"0":{"loc":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"type":"default-arg","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":null}}],"line":49},"1":{"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":4},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"2":{"loc":{"start":{"line":78,"column":8},"end":{"line":78,"column":36}},"type":"binary-expr","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":17}},{"start":{"line":78,"column":17},"end":{"line":78,"column":36}}],"line":78},"3":{"loc":{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":6},"end":{"line":96,"column":null}},{"start":{},"end":{}}],"line":93},"4":{"loc":{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":6},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":99},"5":{"loc":{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":6},"end":{"line":118,"column":null}},{"start":{},"end":{}}],"line":107},"6":{"loc":{"start":{"line":107,"column":10},"end":{"line":107,"column":44}},"type":"binary-expr","locations":[{"start":{"line":107,"column":10},"end":{"line":107,"column":33}},{"start":{"line":107,"column":33},"end":{"line":107,"column":44}}],"line":107},"7":{"loc":{"start":{"line":108,"column":25},"end":{"line":110,"column":null}},"type":"cond-expr","locations":[{"start":{"line":109,"column":12},"end":{"line":109,"column":null}},{"start":{"line":110,"column":12},"end":{"line":110,"column":null}}],"line":108},"8":{"loc":{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":8},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":111},"9":{"loc":{"start":{"line":135,"column":2},"end":{"line":135,"column":null}},"type":"default-arg","locations":[{"start":{"line":135,"column":21},"end":{"line":135,"column":null}}],"line":135},"10":{"loc":{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":4},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":143},"11":{"loc":{"start":{"line":146,"column":20},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":9},"end":{"line":147,"column":null}},{"start":{"line":148,"column":8},"end":{"line":150,"column":null}}],"line":146},"12":{"loc":{"start":{"line":148,"column":8},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":149,"column":11},"end":{"line":149,"column":null}},{"start":{"line":150,"column":10},"end":{"line":150,"column":null}}],"line":148},"13":{"loc":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":50},"end":{"line":152,"column":60}},{"start":{"line":152,"column":60},"end":{"line":152,"column":null}}],"line":152},"14":{"loc":{"start":{"line":175,"column":2},"end":{"line":175,"column":null}},"type":"default-arg","locations":[{"start":{"line":175,"column":21},"end":{"line":175,"column":null}}],"line":175},"15":{"loc":{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":183,"column":null}},{"start":{},"end":{}}],"line":183},"16":{"loc":{"start":{"line":186,"column":16},"end":{"line":187,"column":null}},"type":"binary-expr","locations":[{"start":{"line":186,"column":16},"end":{"line":186,"column":63}},{"start":{"line":186,"column":63},"end":{"line":186,"column":null}},{"start":{"line":187,"column":9},"end":{"line":187,"column":null}}],"line":186},"17":{"loc":{"start":{"line":188,"column":22},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":22},"end":{"line":188,"column":43}},{"start":{"line":188,"column":43},"end":{"line":188,"column":null}}],"line":188}},"s":{"0":19,"1":19,"2":19,"3":19,"4":19,"5":19,"6":19,"7":133,"8":133,"9":104,"10":29,"11":29,"12":29,"13":29,"14":29,"15":32,"16":32,"17":1,"18":1,"19":31,"20":31,"21":2,"22":2,"23":1,"24":2,"25":31,"26":31,"27":31,"28":4,"29":4,"30":4,"31":4,"32":31,"33":31,"34":19,"35":10,"36":10,"37":10,"38":10,"39":10,"40":11,"41":11,"42":1,"43":1,"44":10,"45":10,"46":11,"47":11,"48":11,"49":11,"50":11,"51":10,"52":9,"53":9,"54":9,"55":9,"56":9,"57":59,"58":59,"59":1,"60":1,"61":58,"62":58,"63":59,"64":59,"65":59,"66":9},"f":{"0":19,"1":10,"2":9},"b":{"0":[19],"1":[104,29],"2":[133,133],"3":[1,31],"4":[2,29],"5":[4,27],"6":[31,4],"7":[4,0],"8":[4,0],"9":[10],"10":[1,10],"11":[7,3],"12":[2,1],"13":[9,1],"14":[9],"15":[1,58],"16":[58,57,1],"17":[59,0]},"meta":{"lastBranch":18,"lastFunction":3,"lastStatement":67,"seen":{"f:45:16:45:Infinity":0,"b:49:21:49:Infinity":0,"s:51:58:59:Infinity":0,"s:60:18:60:Infinity":1,"s:61:20:61:Infinity":2,"s:63:16:63:Infinity":3,"s:64:16:64:Infinity":4,"s:66:38:74:Infinity":5,"s:76:2:123:Infinity":6,"s:77:17:77:Infinity":7,"b:78:4:80:Infinity:undefined:undefined:undefined:undefined":1,"s:78:4:80:Infinity":8,"b:78:8:78:17:78:17:78:36":2,"s:79:6:79:Infinity":9,"s:82:20:82:Infinity":10,"s:83:42:88:Infinity":11,"s:90:20:90:Infinity":12,"s:91:4:122:Infinity":13,"s:91:17:91:20":14,"s:92:18:92:Infinity":15,"b:93:6:96:Infinity:undefined:undefined:undefined:undefined":3,"s:93:6:96:Infinity":16,"s:94:8:94:Infinity":17,"s:95:8:95:Infinity":18,"s:98:18:98:Infinity":19,"b:99:6:103:Infinity:undefined:undefined:undefined:undefined":4,"s:99:6:103:Infinity":20,"s:100:21:100:Infinity":21,"s:101:8:101:Infinity":22,"s:101:50:101:Infinity":23,"s:102:8:102:Infinity":24,"s:104:6:104:Infinity":25,"s:105:23:105:Infinity":26,"b:107:6:118:Infinity:undefined:undefined:undefined:undefined":5,"s:107:6:118:Infinity":27,"b:107:10:107:33:107:33:107:44":6,"s:108:25:110:Infinity":28,"b:109:12:109:Infinity:110:12:110:Infinity":7,"b:111:8:117:Infinity:undefined:undefined:undefined:undefined":8,"s:111:8:117:Infinity":29,"s:112:30:112:Infinity":30,"s:113:10:116:Infinity":31,"s:120:6:120:Infinity":32,"s:121:6:121:Infinity":33,"s:125:2:125:Infinity":34,"f:132:16:132:Infinity":1,"b:135:21:135:Infinity":9,"s:137:20:137:Infinity":35,"s:138:16:138:Infinity":36,"s:139:16:139:Infinity":37,"s:141:2:163:Infinity":38,"s:141:15:141:18":39,"s:142:18:142:Infinity":40,"b:143:4:143:Infinity:undefined:undefined:undefined:undefined":10,"s:143:4:143:Infinity":41,"s:143:18:143:29":42,"s:143:29:143:39":43,"s:145:19:145:Infinity":44,"s:146:20:150:Infinity":45,"b:147:9:147:Infinity:148:8:150:Infinity":11,"b:149:11:149:Infinity:150:10:150:Infinity":12,"s:152:22:152:Infinity":46,"b:152:50:152:60:152:60:152:Infinity":13,"s:153:21:153:Infinity":47,"s:155:20:155:Infinity":48,"s:156:4:161:Infinity":49,"s:162:4:162:Infinity":50,"s:165:2:165:Infinity":51,"f:172:16:172:Infinity":2,"b:175:21:175:Infinity":14,"s:177:20:177:Infinity":52,"s:178:16:178:Infinity":53,"s:179:16:179:Infinity":54,"s:181:2:197:Infinity":55,"s:181:15:181:18":56,"s:182:15:182:Infinity":57,"b:183:4:183:Infinity:undefined:undefined:undefined:undefined":15,"s:183:4:183:Infinity":58,"s:183:15:183:26":59,"s:183:26:183:36":60,"s:185:19:185:Infinity":61,"s:186:16:187:Infinity":62,"b:186:16:186:63:186:63:186:Infinity:187:9:187:Infinity":16,"s:188:22:188:Infinity":63,"b:188:22:188:43:188:43:188:Infinity":17,"s:190:4:195:Infinity":64,"s:196:4:196:Infinity":65,"s:199:2:199:Infinity":66}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/mcp-response.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/mcp-response.ts","statementMap":{"0":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"1":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"2":{"start":{"line":45,"column":19},"end":{"line":45,"column":null}},"3":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"4":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"5":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":2},"end":{"line":54,"column":null}},"7":{"start":{"line":56,"column":27},"end":{"line":57,"column":null}},"8":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"9":{"start":{"line":60,"column":78},"end":{"line":66,"column":null}},"10":{"start":{"line":67,"column":2},"end":{"line":71,"column":null}},"11":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}}},"fnMap":{"0":{"name":"persistMCPResponse","decl":{"start":{"line":36,"column":16},"end":{"line":36,"column":null}},"loc":{"start":{"line":42,"column":10},"end":{"line":74,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"type":"default-arg","locations":[{"start":{"line":40,"column":21},"end":{"line":40,"column":null}}],"line":40},"1":{"loc":{"start":{"line":43,"column":20},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":20},"end":{"line":43,"column":41}},{"start":{"line":43,"column":41},"end":{"line":43,"column":null}}],"line":43},"2":{"loc":{"start":{"line":56,"column":27},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":27},"end":{"line":56,"column":null}},{"start":{"line":57,"column":8},"end":{"line":57,"column":null}}],"line":56},"3":{"loc":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":45},"end":{"line":57,"column":62}},{"start":{"line":57,"column":62},"end":{"line":57,"column":null}}],"line":57}},"s":{"0":17,"1":17,"2":17,"3":17,"4":17,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":17},"f":{"0":17},"b":{"0":[17],"1":[17,1],"2":[17,16],"3":[2,14]},"meta":{"lastBranch":4,"lastFunction":1,"lastStatement":12,"seen":{"f:36:16:36:Infinity":0,"b:40:21:40:Infinity":0,"s:43:20:43:Infinity":0,"b:43:20:43:41:43:41:43:Infinity":1,"s:44:21:44:Infinity":1,"s:45:19:45:Infinity":2,"s:46:14:46:Infinity":3,"s:47:2:47:Infinity":4,"s:49:19:49:Infinity":5,"s:50:2:54:Infinity":6,"s:56:27:57:Infinity":7,"b:56:27:56:Infinity:57:8:57:Infinity":2,"b:57:45:57:62:57:62:57:Infinity":3,"s:59:23:59:Infinity":8,"s:60:78:66:Infinity":9,"s:67:2:71:Infinity":10,"s:73:2:73:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/scb.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/scb.ts","statementMap":{"0":{"start":{"line":30,"column":14},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"2":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"5":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"6":{"start":{"line":42,"column":2},"end":{"line":51,"column":null}},"7":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"persistSCBData","decl":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"loc":{"start":{"line":29,"column":10},"end":{"line":54,"column":null}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":28,"column":null}},"type":"default-arg","locations":[{"start":{"line":28,"column":21},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":48,"column":10},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":18},"end":{"line":48,"column":30}},{"start":{"line":48,"column":30},"end":{"line":48,"column":null}}],"line":48}},"s":{"0":7,"1":7,"2":7,"3":7,"4":7,"5":7,"6":7,"7":7},"f":{"0":7},"b":{"0":[7],"1":[3,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":8,"seen":{"f:24:16:24:Infinity":0,"b:28:21:28:Infinity":0,"s:30:14:30:Infinity":0,"s:31:2:31:Infinity":1,"s:33:20:33:Infinity":2,"s:34:19:34:Infinity":3,"s:35:2:39:Infinity":4,"s:41:23:41:Infinity":5,"s:42:2:51:Infinity":6,"b:48:18:48:30:48:30:48:Infinity":1,"s:53:2:53:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/meta-sidecar.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/meta-sidecar.ts","statementMap":{"0":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"1":{"start":{"line":29,"column":25},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":25},"end":{"line":31,"column":null}},"3":{"start":{"line":34,"column":27},"end":{"line":34,"column":null}},"4":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"5":{"start":{"line":100,"column":17},"end":{"line":100,"column":null}},"6":{"start":{"line":101,"column":21},"end":{"line":108,"column":null}},"7":{"start":{"line":109,"column":13},"end":{"line":111,"column":null}},"8":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"9":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"10":{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},"11":{"start":{"line":136,"column":4},"end":{"line":138,"column":null}},"12":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"13":{"start":{"line":141,"column":22},"end":{"line":141,"column":null}},"14":{"start":{"line":142,"column":2},"end":{"line":146,"column":null}},"15":{"start":{"line":147,"column":23},"end":{"line":147,"column":null}},"16":{"start":{"line":148,"column":2},"end":{"line":152,"column":null}},"17":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}}},"fnMap":{"0":{"name":"ensureDir","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":26}},"loc":{"start":{"line":91,"column":45},"end":{"line":93,"column":null}},"line":91},"1":{"name":"resolveDocId","decl":{"start":{"line":99,"column":16},"end":{"line":99,"column":29}},"loc":{"start":{"line":99,"column":70},"end":{"line":113,"column":null}},"line":99},"2":{"name":"(anonymous_2)","decl":{"start":{"line":109,"column":24},"end":{"line":109,"column":null}},"loc":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"line":110},"3":{"name":"writeDocumentAndMeta","decl":{"start":{"line":129,"column":16},"end":{"line":129,"column":null}},"loc":{"start":{"line":134,"column":8},"end":{"line":153,"column":null}},"line":134},"4":{"name":"getDataRoot","decl":{"start":{"line":159,"column":16},"end":{"line":159,"column":38}},"loc":{"start":{"line":159,"column":38},"end":{"line":161,"column":null}},"line":159}},"branchMap":{"0":{"loc":{"start":{"line":109,"column":13},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":109,"column":13},"end":{"line":111,"column":15}},{"start":{"line":111,"column":15},"end":{"line":111,"column":null}}],"line":109},"1":{"loc":{"start":{"line":110,"column":24},"end":{"line":110,"column":null}},"type":"binary-expr","locations":[{"start":{"line":110,"column":24},"end":{"line":110,"column":49}},{"start":{"line":110,"column":49},"end":{"line":110,"column":null}}],"line":110},"2":{"loc":{"start":{"line":112,"column":9},"end":{"line":112,"column":null}},"type":"binary-expr","locations":[{"start":{"line":112,"column":9},"end":{"line":112,"column":30}},{"start":{"line":112,"column":30},"end":{"line":112,"column":null}}],"line":112},"3":{"loc":{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":135}},"s":{"0":25,"1":25,"2":25,"3":25,"4":154,"5":49,"6":49,"7":49,"8":85,"9":49,"10":110,"11":1,"12":109,"13":109,"14":109,"15":109,"16":109,"17":3},"f":{"0":154,"1":49,"2":85,"3":110,"4":3},"b":{"0":[49,1],"1":[85,49],"2":[49,0],"3":[1,109]},"meta":{"lastBranch":4,"lastFunction":5,"lastStatement":18,"seen":{"s:27:18:27:Infinity":0,"s:29:25:29:Infinity":1,"s:31:25:31:Infinity":2,"s:34:27:34:Infinity":3,"f:91:16:91:26":0,"s:92:2:92:Infinity":4,"f:99:16:99:29":1,"s:100:17:100:Infinity":5,"s:101:21:108:Infinity":6,"s:109:13:111:Infinity":7,"b:109:13:111:15:111:15:111:Infinity":0,"f:109:24:109:Infinity":2,"s:110:24:110:Infinity":8,"b:110:24:110:49:110:49:110:Infinity":1,"s:112:2:112:Infinity":9,"b:112:9:112:30:112:30:112:Infinity":2,"f:129:16:129:Infinity":3,"b:135:2:139:Infinity:undefined:undefined:undefined:undefined":3,"s:135:2:139:Infinity":10,"s:136:4:138:Infinity":11,"s:140:2:140:Infinity":12,"s:141:22:141:Infinity":13,"s:142:2:146:Infinity":14,"s:147:23:147:Infinity":15,"s:148:2:152:Infinity":16,"f:159:16:159:38":4,"s:160:2:160:Infinity":17}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/riksbank.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/riksbank.ts","statementMap":{"0":{"start":{"line":32,"column":14},"end":{"line":32,"column":null}},"1":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"2":{"start":{"line":35,"column":20},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":2},"end":{"line":41,"column":null}},"5":{"start":{"line":43,"column":23},"end":{"line":45,"column":null}},"6":{"start":{"line":46,"column":20},"end":{"line":48,"column":null}},"7":{"start":{"line":49,"column":23},"end":{"line":49,"column":null}},"8":{"start":{"line":50,"column":2},"end":{"line":59,"column":null}},"9":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}}},"fnMap":{"0":{"name":"persistRiksbankData","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"loc":{"start":{"line":31,"column":10},"end":{"line":62,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"default-arg","locations":[{"start":{"line":30,"column":21},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":43,"column":23},"end":{"line":45,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":7},"end":{"line":44,"column":null}},{"start":{"line":45,"column":6},"end":{"line":45,"column":null}}],"line":43},"2":{"loc":{"start":{"line":43,"column":23},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":23},"end":{"line":43,"column":55}},{"start":{"line":43,"column":55},"end":{"line":43,"column":76}},{"start":{"line":43,"column":76},"end":{"line":43,"column":null}}],"line":43},"3":{"loc":{"start":{"line":46,"column":20},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":null}},{"start":{"line":48,"column":6},"end":{"line":48,"column":null}}],"line":46},"4":{"loc":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":20},"end":{"line":46,"column":56}},{"start":{"line":46,"column":56},"end":{"line":46,"column":null}}],"line":46},"5":{"loc":{"start":{"line":56,"column":10},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":56,"column":22},"end":{"line":56,"column":43}},{"start":{"line":56,"column":43},"end":{"line":56,"column":null}}],"line":56}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3},"f":{"0":3},"b":{"0":[3],"1":[2,1],"2":[3,3,3],"3":[2,1],"4":[3,2],"5":[2,1]},"meta":{"lastBranch":6,"lastFunction":1,"lastStatement":10,"seen":{"f:27:16:27:Infinity":0,"b:30:21:30:Infinity":0,"s:32:14:32:Infinity":0,"s:33:2:33:Infinity":1,"s:35:20:35:Infinity":2,"s:36:19:36:Infinity":3,"s:37:2:41:Infinity":4,"s:43:23:45:Infinity":5,"b:44:7:44:Infinity:45:6:45:Infinity":1,"b:43:23:43:55:43:55:43:76:43:76:43:Infinity":2,"s:46:20:48:Infinity":6,"b:47:6:47:Infinity:48:6:48:Infinity":3,"b:46:20:46:56:46:56:46:Infinity":4,"s:49:23:49:Infinity":7,"s:50:2:59:Infinity":8,"b:56:22:56:43:56:43:56:Infinity":5,"s:61:2:61:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/sanitize.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/sanitize.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":32,"column":13},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"3":{"start":{"line":33,"column":26},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}}},"fnMap":{"0":{"name":"sanitizeDokId","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":53},"end":{"line":24,"column":null}},"line":17},"1":{"name":"sanitizePathSegment","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":36}},"loc":{"start":{"line":31,"column":61},"end":{"line":39,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"1":{"loc":{"start":{"line":38,"column":9},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":9},"end":{"line":38,"column":17}},{"start":{"line":38,"column":17},"end":{"line":38,"column":null}}],"line":38}},"s":{"0":188,"1":34,"2":34,"3":1,"4":34,"5":34},"f":{"0":188,"1":34},"b":{"0":[1,33],"1":[34,0]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":6,"seen":{"f:17:16:17:30":0,"s:18:2:23:Infinity":0,"f:31:16:31:36":1,"s:32:13:32:Infinity":1,"b:33:2:33:Infinity:undefined:undefined:undefined:undefined":0,"s:33:2:33:Infinity":2,"s:33:26:33:Infinity":3,"s:34:2:37:Infinity":4,"s:38:2:38:Infinity":5,"b:38:9:38:17:38:17:38:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/strip-metadata.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/shared/strip-metadata.ts","statementMap":{"0":{"start":{"line":19,"column":40},"end":{"line":23,"column":null}},"1":{"start":{"line":33,"column":17},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":47},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},"5":{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},"6":{"start":{"line":37,"column":19},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"8":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}}},"fnMap":{"0":{"name":"stripInMemoryCoverageMetadata","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":46}},"loc":{"start":{"line":32,"column":77},"end":{"line":42,"column":null}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":36},"1":{"loc":{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"2":{"loc":{"start":{"line":41,"column":10},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":41,"column":10},"end":{"line":41,"column":20}},{"start":{"line":41,"column":20},"end":{"line":41,"column":null}}],"line":41}},"s":{"0":25,"1":109,"2":109,"3":109,"4":327,"5":21,"6":7,"7":21,"8":109},"f":{"0":109},"b":{"0":[21,306],"1":[7,14],"2":[109,102]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":9,"seen":{"s:19:40:23:Infinity":0,"f:32:16:32:46":0,"s:33:17:33:Infinity":1,"s:34:47:34:Infinity":2,"s:35:2:40:Infinity":3,"b:36:4:39:Infinity:undefined:undefined:undefined:undefined":0,"s:36:4:39:Infinity":4,"b:37:6:37:Infinity:undefined:undefined:undefined:undefined":1,"s:37:6:37:Infinity":5,"s:37:19:37:Infinity":6,"s:38:6:38:Infinity":7,"s:41:2:41:Infinity":8,"b:41:10:41:20:41:20:41:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/statskontoret.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/statskontoret.ts","statementMap":{"0":{"start":{"line":36,"column":14},"end":{"line":36,"column":null}},"1":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":39,"column":28},"end":{"line":39,"column":null}},"3":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"4":{"start":{"line":41,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":47,"column":23},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":57,"column":null}},"7":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}}},"fnMap":{"0":{"name":"persistStatskontoretData","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"loc":{"start":{"line":35,"column":10},"end":{"line":60,"column":null}},"line":35}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"default-arg","locations":[{"start":{"line":34,"column":21},"end":{"line":34,"column":null}}],"line":34}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4},"f":{"0":4},"b":{"0":[4]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":8,"seen":{"f:30:16:30:Infinity":0,"b:34:21:34:Infinity":0,"s:36:14:36:Infinity":0,"s:37:2:37:Infinity":1,"s:39:28:39:Infinity":2,"s:40:19:40:Infinity":3,"s:41:2:45:Infinity":4,"s:47:23:47:Infinity":5,"s:48:2:57:Infinity":6,"s:59:2:59:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/world-bank.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/parliamentary-data/persistence/world-bank.ts","statementMap":{"0":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"2":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"4":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"5":{"start":{"line":42,"column":2},"end":{"line":51,"column":null}},"6":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"persistWorldBankData","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":null}},"loc":{"start":{"line":30,"column":10},"end":{"line":54,"column":null}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"default-arg","locations":[{"start":{"line":29,"column":21},"end":{"line":29,"column":null}}],"line":29}},"s":{"0":9,"1":9,"2":9,"3":9,"4":9,"5":9,"6":9},"f":{"0":9},"b":{"0":[9]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:25:16:25:Infinity":0,"b:29:21:29:Infinity":0,"s:31:14:31:Infinity":0,"s:32:2:32:Infinity":1,"s:34:19:34:Infinity":2,"s:35:2:39:Infinity":3,"s:41:23:41:Infinity":4,"s:42:2:51:Infinity":5,"s:53:2:53:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/catalog.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/catalog.ts","statementMap":{"0":{"start":{"line":23,"column":20},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":20},"end":{"line":24,"column":null}},"2":{"start":{"line":46,"column":15},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"5":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"6":{"start":{"line":62,"column":27},"end":{"line":62,"column":null}},"7":{"start":{"line":63,"column":34},"end":{"line":63,"column":null}},"8":{"start":{"line":64,"column":2},"end":{"line":78,"column":null}},"9":{"start":{"line":64,"column":56},"end":{"line":64,"column":74}},"10":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"11":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"12":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"13":{"start":{"line":67,"column":24},"end":{"line":67,"column":null}},"14":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"15":{"start":{"line":68,"column":37},"end":{"line":68,"column":null}},"16":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"17":{"start":{"line":70,"column":4},"end":{"line":77,"column":null}},"18":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"buildGithubUrl","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":31}},"loc":{"start":{"line":45,"column":80},"end":{"line":49,"column":null}},"line":45},"1":{"name":"collectCatalog","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":61,"column":18},"end":{"line":80,"column":null}},"line":61},"2":{"name":"(anonymous_2)","decl":{"start":{"line":64,"column":41},"end":{"line":64,"column":47}},"loc":{"start":{"line":64,"column":56},"end":{"line":64,"column":74}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":15},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":33},"end":{"line":46,"column":47}},{"start":{"line":46,"column":47},"end":{"line":46,"column":null}}],"line":46},"1":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":62},"2":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"3":{"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},{"start":{},"end":{}}],"line":68},"4":{"loc":{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":12},"end":{"line":73,"column":27}},{"start":{"line":73,"column":27},"end":{"line":73,"column":null}}],"line":73},"5":{"loc":{"start":{"line":73,"column":27},"end":{"line":73,"column":null}},"type":"cond-expr","locations":[{"start":{"line":73,"column":52},"end":{"line":73,"column":59}},{"start":{"line":73,"column":59},"end":{"line":73,"column":null}}],"line":73},"6":{"loc":{"start":{"line":74,"column":19},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":19},"end":{"line":74,"column":40}},{"start":{"line":74,"column":40},"end":{"line":74,"column":null}}],"line":74}},"s":{"0":2,"1":2,"2":438252,"3":438252,"4":438252,"5":62,"6":0,"7":62,"8":62,"9":7130,"10":1953,"11":1953,"12":1953,"13":31,"14":1922,"15":0,"16":1922,"17":1922,"18":62},"f":{"0":438252,"1":62,"2":7130},"b":{"0":[424798,13454],"1":[0,62],"2":[31,1922],"3":[0,1922],"4":[1922,248],"5":[31,217],"6":[1953,248]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":19,"seen":{"s:23:20:23:Infinity":0,"s:24:20:24:Infinity":1,"f:45:16:45:31":0,"s:46:15:46:Infinity":2,"b:46:33:46:47:46:47:46:Infinity":0,"s:47:18:47:Infinity":3,"s:48:2:48:Infinity":4,"f:56:16:56:Infinity":1,"b:62:2:62:Infinity:undefined:undefined:undefined:undefined":1,"s:62:2:62:Infinity":5,"s:62:27:62:Infinity":6,"s:63:34:63:Infinity":7,"s:64:2:78:Infinity":8,"f:64:41:64:47":2,"s:64:56:64:74":9,"s:65:17:65:Infinity":10,"s:66:17:66:Infinity":11,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":2,"s:67:4:67:Infinity":12,"s:67:24:67:Infinity":13,"b:68:4:68:Infinity:undefined:undefined:undefined:undefined":3,"s:68:4:68:Infinity":14,"s:68:37:68:Infinity":15,"s:69:17:69:Infinity":16,"s:70:4:77:Infinity":17,"b:73:12:73:27:73:27:73:Infinity":4,"b:73:52:73:59:73:59:73:Infinity":5,"b:74:19:74:40:74:40:74:Infinity":6,"s:79:2:79:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/daily-streams.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/daily-streams.ts","statementMap":{"0":{"start":{"line":23,"column":19},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":18},"end":{"line":24,"column":null}},"2":{"start":{"line":26,"column":17},"end":{"line":26,"column":null}},"3":{"start":{"line":27,"column":18},"end":{"line":27,"column":null}},"4":{"start":{"line":51,"column":10},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":2},"end":{"line":59,"column":null}},"6":{"start":{"line":53,"column":17},"end":{"line":53,"column":null}},"7":{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},"8":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"9":{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},"10":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"11":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"12":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"13":{"start":{"line":65,"column":33},"end":{"line":65,"column":null}},"14":{"start":{"line":66,"column":31},"end":{"line":66,"column":null}},"15":{"start":{"line":67,"column":8},"end":{"line":81,"column":null}},"16":{"start":{"line":68,"column":4},"end":{"line":80,"column":null}},"17":{"start":{"line":68,"column":80},"end":{"line":68,"column":108}},"18":{"start":{"line":69,"column":19},"end":{"line":69,"column":null}},"19":{"start":{"line":70,"column":18},"end":{"line":70,"column":null}},"20":{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},"21":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"22":{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},"23":{"start":{"line":74,"column":8},"end":{"line":78,"column":null}},"24":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"25":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"26":{"start":{"line":83,"column":28},"end":{"line":83,"column":56}},"27":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"28":{"start":{"line":87,"column":33},"end":{"line":87,"column":null}},"29":{"start":{"line":88,"column":27},"end":{"line":88,"column":null}},"30":{"start":{"line":89,"column":22},"end":{"line":92,"column":null}},"31":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"32":{"start":{"line":91,"column":16},"end":{"line":91,"column":22}},"33":{"start":{"line":92,"column":20},"end":{"line":92,"column":38}},"34":{"start":{"line":94,"column":2},"end":{"line":120,"column":null}},"35":{"start":{"line":95,"column":20},"end":{"line":95,"column":null}},"36":{"start":{"line":96,"column":24},"end":{"line":99,"column":null}},"37":{"start":{"line":97,"column":21},"end":{"line":97,"column":36}},"38":{"start":{"line":98,"column":18},"end":{"line":98,"column":24}},"39":{"start":{"line":99,"column":22},"end":{"line":99,"column":40}},"40":{"start":{"line":101,"column":35},"end":{"line":110,"column":null}},"41":{"start":{"line":102,"column":24},"end":{"line":102,"column":null}},"42":{"start":{"line":103,"column":24},"end":{"line":103,"column":null}},"43":{"start":{"line":104,"column":6},"end":{"line":109,"column":null}},"44":{"start":{"line":112,"column":27},"end":{"line":112,"column":null}},"45":{"start":{"line":112,"column":52},"end":{"line":112,"column":73}},"46":{"start":{"line":114,"column":4},"end":{"line":119,"column":null}},"47":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"countArtifactsRecursive","decl":{"start":{"line":50,"column":16},"end":{"line":50,"column":40}},"loc":{"start":{"line":50,"column":61},"end":{"line":61,"column":null}},"line":50},"1":{"name":"collectStreamArtifacts","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":39}},"loc":{"start":{"line":64,"column":103},"end":{"line":84,"column":null}},"line":64},"2":{"name":"(anonymous_2)","decl":{"start":{"line":67,"column":8},"end":{"line":67,"column":16}},"loc":{"start":{"line":67,"column":55},"end":{"line":81,"column":null}},"line":67},"3":{"name":"(anonymous_3)","decl":{"start":{"line":68,"column":65},"end":{"line":68,"column":71}},"loc":{"start":{"line":68,"column":80},"end":{"line":68,"column":108}},"line":68},"4":{"name":"(anonymous_4)","decl":{"start":{"line":83,"column":13},"end":{"line":83,"column":19}},"loc":{"start":{"line":83,"column":28},"end":{"line":83,"column":56}},"line":83},"5":{"name":"collectDailyDays","decl":{"start":{"line":86,"column":16},"end":{"line":86,"column":47}},"loc":{"start":{"line":86,"column":47},"end":{"line":123,"column":null}},"line":86},"6":{"name":"(anonymous_6)","decl":{"start":{"line":90,"column":5},"end":{"line":90,"column":13}},"loc":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"line":90},"7":{"name":"(anonymous_7)","decl":{"start":{"line":91,"column":5},"end":{"line":91,"column":10}},"loc":{"start":{"line":91,"column":16},"end":{"line":91,"column":22}},"line":91},"8":{"name":"(anonymous_8)","decl":{"start":{"line":92,"column":5},"end":{"line":92,"column":11}},"loc":{"start":{"line":92,"column":20},"end":{"line":92,"column":38}},"line":92},"9":{"name":"(anonymous_9)","decl":{"start":{"line":97,"column":7},"end":{"line":97,"column":15}},"loc":{"start":{"line":97,"column":21},"end":{"line":97,"column":36}},"line":97},"10":{"name":"(anonymous_10)","decl":{"start":{"line":98,"column":7},"end":{"line":98,"column":12}},"loc":{"start":{"line":98,"column":18},"end":{"line":98,"column":24}},"line":98},"11":{"name":"(anonymous_11)","decl":{"start":{"line":99,"column":7},"end":{"line":99,"column":13}},"loc":{"start":{"line":99,"column":22},"end":{"line":99,"column":40}},"line":99},"12":{"name":"(anonymous_12)","decl":{"start":{"line":101,"column":47},"end":{"line":101,"column":52}},"loc":{"start":{"line":101,"column":61},"end":{"line":110,"column":5}},"line":101},"13":{"name":"(anonymous_13)","decl":{"start":{"line":112,"column":35},"end":{"line":112,"column":43}},"loc":{"start":{"line":112,"column":52},"end":{"line":112,"column":73}},"line":112}},"branchMap":{"0":{"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":58,"column":null}},{"start":{"line":56,"column":11},"end":{"line":58,"column":null}}],"line":54},"1":{"loc":{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":11},"end":{"line":58,"column":null}},{"start":{},"end":{}}],"line":56},"2":{"loc":{"start":{"line":56,"column":15},"end":{"line":56,"column":59}},"type":"binary-expr","locations":[{"start":{"line":56,"column":15},"end":{"line":56,"column":29}},{"start":{"line":56,"column":29},"end":{"line":56,"column":59}}],"line":56},"3":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65},"4":{"loc":{"start":{"line":70,"column":18},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":28},"end":{"line":70,"column":53}},{"start":{"line":70,"column":53},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":6},"end":{"line":79,"column":null}},{"start":{"line":73,"column":13},"end":{"line":79,"column":null}}],"line":71},"6":{"loc":{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":13},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":73},"7":{"loc":{"start":{"line":73,"column":17},"end":{"line":73,"column":61}},"type":"binary-expr","locations":[{"start":{"line":73,"column":17},"end":{"line":73,"column":31}},{"start":{"line":73,"column":31},"end":{"line":73,"column":61}}],"line":73},"8":{"loc":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":87},"9":{"loc":{"start":{"line":90,"column":19},"end":{"line":90,"column":72}},"type":"binary-expr","locations":[{"start":{"line":90,"column":19},"end":{"line":90,"column":38}},{"start":{"line":90,"column":38},"end":{"line":90,"column":72}}],"line":90},"10":{"loc":{"start":{"line":107,"column":23},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":107,"column":23},"end":{"line":107,"column":43}},{"start":{"line":107,"column":43},"end":{"line":107,"column":null}}],"line":107}},"s":{"0":2,"1":2,"2":2,"3":2,"4":4,"5":4,"6":7,"7":7,"8":1,"9":6,"10":5,"11":4,"12":11474,"13":1,"14":11473,"15":11473,"16":21549,"17":1270880,"18":432985,"19":432985,"20":432985,"21":10076,"22":422909,"23":422876,"24":11473,"25":11473,"26":411682,"27":32,"28":1,"29":31,"30":31,"31":2046,"32":1984,"33":1953,"34":31,"35":1984,"36":1984,"37":13950,"38":11470,"39":12183,"40":1984,"41":11470,"42":11470,"43":11470,"44":1984,"45":11470,"46":1984,"47":31},"f":{"0":4,"1":11474,"2":21549,"3":1270880,"4":411682,"5":32,"6":2046,"7":1984,"8":1953,"9":13950,"10":11470,"11":12183,"12":11470,"13":11470},"b":{"0":[1,6],"1":[5,1],"2":[6,6],"3":[1,11473],"4":[128341,304644],"5":[10076,422909],"6":[422876,33],"7":[422909,422909],"8":[1,31],"9":[2046,1984],"10":[11470,0]},"meta":{"lastBranch":11,"lastFunction":14,"lastStatement":48,"seen":{"s:23:19:23:Infinity":0,"s:24:18:24:Infinity":1,"s:26:17:26:Infinity":2,"s:27:18:27:Infinity":3,"f:50:16:50:40":0,"s:51:10:51:Infinity":4,"s:52:2:59:Infinity":5,"s:53:17:53:Infinity":6,"b:54:4:58:Infinity:56:11:58:Infinity":0,"s:54:4:58:Infinity":7,"s:55:6:55:Infinity":8,"b:56:11:58:Infinity:undefined:undefined:undefined:undefined":1,"s:56:11:58:Infinity":9,"b:56:15:56:29:56:29:56:59":2,"s:57:6:57:Infinity":10,"s:60:2:60:Infinity":11,"f:64:16:64:39":1,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:2:65:Infinity":12,"s:65:33:65:Infinity":13,"s:66:31:66:Infinity":14,"s:67:8:81:Infinity":15,"f:67:8:67:16":2,"s:68:4:80:Infinity":16,"f:68:65:68:71":3,"s:68:80:68:108":17,"s:69:19:69:Infinity":18,"s:70:18:70:Infinity":19,"b:70:28:70:53:70:53:70:Infinity":4,"b:71:6:79:Infinity:73:13:79:Infinity":5,"s:71:6:79:Infinity":20,"s:72:8:72:Infinity":21,"b:73:13:79:Infinity:undefined:undefined:undefined:undefined":6,"s:73:13:79:Infinity":22,"b:73:17:73:31:73:31:73:61":7,"s:74:8:78:Infinity":23,"s:82:2:82:Infinity":24,"s:83:2:83:Infinity":25,"f:83:13:83:19":4,"s:83:28:83:56":26,"f:86:16:86:47":5,"b:87:2:87:Infinity:undefined:undefined:undefined:undefined":8,"s:87:2:87:Infinity":27,"s:87:33:87:Infinity":28,"s:88:27:88:Infinity":29,"s:89:22:92:Infinity":30,"f:90:5:90:13":6,"s:90:19:90:72":31,"b:90:19:90:38:90:38:90:72":9,"f:91:5:91:10":7,"s:91:16:91:22":32,"f:92:5:92:11":8,"s:92:20:92:38":33,"s:94:2:120:Infinity":34,"s:95:20:95:Infinity":35,"s:96:24:99:Infinity":36,"f:97:7:97:15":9,"s:97:21:97:36":37,"f:98:7:98:12":10,"s:98:18:98:24":38,"f:99:7:99:13":11,"s:99:22:99:40":39,"s:101:35:110:Infinity":40,"f:101:47:101:52":12,"s:102:24:102:Infinity":41,"s:103:24:103:Infinity":42,"s:104:6:109:Infinity":43,"b:107:23:107:43:107:43:107:Infinity":10,"s:112:27:112:Infinity":44,"f:112:35:112:43":13,"s:112:52:112:73":45,"s:114:4:119:Infinity":46,"s:122:2:122:Infinity":47}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/artifact-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/artifact-i18n.ts","statementMap":{"0":{"start":{"line":26,"column":60},"end":{"line":182,"column":null}},"1":{"start":{"line":188,"column":53},"end":{"line":220,"column":null}},"2":{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},"3":{"start":{"line":231,"column":19},"end":{"line":231,"column":null}},"4":{"start":{"line":232,"column":18},"end":{"line":232,"column":null}},"5":{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},"6":{"start":{"line":233,"column":16},"end":{"line":233,"column":null}},"7":{"start":{"line":234,"column":2},"end":{"line":236,"column":null}},"8":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"9":{"start":{"line":235,"column":22},"end":{"line":235,"column":null}},"10":{"start":{"line":237,"column":2},"end":{"line":237,"column":null}},"11":{"start":{"line":242,"column":19},"end":{"line":242,"column":null}},"12":{"start":{"line":243,"column":18},"end":{"line":243,"column":null}},"13":{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},"14":{"start":{"line":244,"column":30},"end":{"line":244,"column":null}},"15":{"start":{"line":245,"column":18},"end":{"line":245,"column":null}},"16":{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},"17":{"start":{"line":246,"column":30},"end":{"line":246,"column":null}},"18":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"19":{"start":{"line":247,"column":30},"end":{"line":247,"column":null}},"20":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"21":{"start":{"line":248,"column":70},"end":{"line":248,"column":null}},"22":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"23":{"start":{"line":249,"column":37},"end":{"line":249,"column":null}},"24":{"start":{"line":250,"column":2},"end":{"line":250,"column":null}},"25":{"start":{"line":254,"column":81},"end":{"line":265,"column":null}},"26":{"start":{"line":272,"column":2},"end":{"line":276,"column":null}},"27":{"start":{"line":276,"column":29},"end":{"line":276,"column":44}},"28":{"start":{"line":281,"column":14},"end":{"line":281,"column":null}},"29":{"start":{"line":282,"column":2},"end":{"line":284,"column":null}},"30":{"start":{"line":299,"column":14},"end":{"line":299,"column":null}},"31":{"start":{"line":300,"column":14},"end":{"line":300,"column":null}},"32":{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},"33":{"start":{"line":301,"column":11},"end":{"line":301,"column":null}},"34":{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},"35":{"start":{"line":303,"column":20},"end":{"line":303,"column":null}},"36":{"start":{"line":304,"column":18},"end":{"line":304,"column":null}},"37":{"start":{"line":305,"column":20},"end":{"line":305,"column":null}},"38":{"start":{"line":306,"column":4},"end":{"line":306,"column":null}},"39":{"start":{"line":308,"column":2},"end":{"line":308,"column":null}}},"fnMap":{"0":{"name":"aliasLookupKey","decl":{"start":{"line":230,"column":9},"end":{"line":230,"column":27}},"loc":{"start":{"line":230,"column":73},"end":{"line":238,"column":null}},"line":230},"1":{"name":"artifactIcon","decl":{"start":{"line":241,"column":16},"end":{"line":241,"column":29}},"loc":{"start":{"line":241,"column":51},"end":{"line":251,"column":null}},"line":241},"2":{"name":"prettifyMarkdownTitle","decl":{"start":{"line":271,"column":16},"end":{"line":271,"column":38}},"loc":{"start":{"line":271,"column":60},"end":{"line":277,"column":null}},"line":271},"3":{"name":"(anonymous_3)","decl":{"start":{"line":276,"column":13},"end":{"line":276,"column":23}},"loc":{"start":{"line":276,"column":29},"end":{"line":276,"column":44}},"line":276},"4":{"name":"artifactTitle","decl":{"start":{"line":280,"column":16},"end":{"line":280,"column":30}},"loc":{"start":{"line":280,"column":68},"end":{"line":285,"column":null}},"line":280},"5":{"name":"localisedCatalogDescription","decl":{"start":{"line":293,"column":16},"end":{"line":293,"column":null}},"loc":{"start":{"line":298,"column":10},"end":{"line":309,"column":null}},"line":298}},"branchMap":{"0":{"loc":{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},"type":"if","locations":[{"start":{"line":231,"column":2},"end":{"line":231,"column":null}},{"start":{},"end":{}}],"line":231},"1":{"loc":{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},"type":"if","locations":[{"start":{"line":233,"column":2},"end":{"line":233,"column":null}},{"start":{},"end":{}}],"line":233},"2":{"loc":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"type":"if","locations":[{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},{"start":{},"end":{}}],"line":235},"3":{"loc":{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":244,"column":2},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":244},"4":{"loc":{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},"type":"if","locations":[{"start":{"line":246,"column":2},"end":{"line":246,"column":null}},{"start":{},"end":{}}],"line":246},"5":{"loc":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"type":"if","locations":[{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},{"start":{},"end":{}}],"line":247},"6":{"loc":{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":2},"end":{"line":248,"column":null}},{"start":{},"end":{}}],"line":248},"7":{"loc":{"start":{"line":248,"column":6},"end":{"line":248,"column":70}},"type":"binary-expr","locations":[{"start":{"line":248,"column":6},"end":{"line":248,"column":39}},{"start":{"line":248,"column":39},"end":{"line":248,"column":70}}],"line":248},"8":{"loc":{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},"type":"if","locations":[{"start":{"line":249,"column":2},"end":{"line":249,"column":null}},{"start":{},"end":{}}],"line":249},"9":{"loc":{"start":{"line":282,"column":9},"end":{"line":284,"column":null}},"type":"binary-expr","locations":[{"start":{"line":282,"column":9},"end":{"line":282,"column":null}},{"start":{"line":283,"column":9},"end":{"line":283,"column":null}},{"start":{"line":284,"column":9},"end":{"line":284,"column":null}}],"line":282},"10":{"loc":{"start":{"line":299,"column":14},"end":{"line":299,"column":null}},"type":"cond-expr","locations":[{"start":{"line":299,"column":44},"end":{"line":299,"column":68}},{"start":{"line":299,"column":68},"end":{"line":299,"column":null}}],"line":299},"11":{"loc":{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},"type":"if","locations":[{"start":{"line":301,"column":2},"end":{"line":301,"column":null}},{"start":{},"end":{}}],"line":301},"12":{"loc":{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},"type":"if","locations":[{"start":{"line":302,"column":2},"end":{"line":307,"column":null}},{"start":{},"end":{}}],"line":302},"13":{"loc":{"start":{"line":303,"column":20},"end":{"line":303,"column":null}},"type":"binary-expr","locations":[{"start":{"line":303,"column":20},"end":{"line":303,"column":56}},{"start":{"line":303,"column":56},"end":{"line":303,"column":null}}],"line":303},"14":{"loc":{"start":{"line":305,"column":20},"end":{"line":305,"column":null}},"type":"binary-expr","locations":[{"start":{"line":305,"column":20},"end":{"line":305,"column":57}},{"start":{"line":305,"column":57},"end":{"line":305,"column":null}}],"line":305}},"s":{"0":14,"1":14,"2":412473,"3":193713,"4":218760,"5":218760,"6":218275,"7":485,"8":485,"9":485,"10":0,"11":205,"12":205,"13":205,"14":200,"15":5,"16":5,"17":0,"18":5,"19":0,"20":5,"21":0,"22":5,"23":0,"24":5,"25":14,"26":220438,"27":482412,"28":412263,"29":412263,"30":1860,"31":1860,"32":1860,"33":720,"34":1140,"35":1050,"36":1050,"37":1050,"38":1050,"39":90},"f":{"0":412473,"1":205,"2":220438,"3":482412,"4":412263,"5":1860},"b":{"0":[193713,218760],"1":[218275,485],"2":[485,0],"3":[200,5],"4":[0,5],"5":[0,5],"6":[0,5],"7":[5,0],"8":[0,5],"9":[412263,218265,218265],"10":[660,1200],"11":[720,1140],"12":[1050,90],"13":[1050,0],"14":[1050,0]},"meta":{"lastBranch":15,"lastFunction":6,"lastStatement":40,"seen":{"s:26:60:182:Infinity":0,"s:188:53:220:Infinity":1,"f:230:9:230:27":0,"b:231:2:231:Infinity:undefined:undefined:undefined:undefined":0,"s:231:2:231:Infinity":2,"s:231:19:231:Infinity":3,"s:232:18:232:Infinity":4,"b:233:2:233:Infinity:undefined:undefined:undefined:undefined":1,"s:233:2:233:Infinity":5,"s:233:16:233:Infinity":6,"s:234:2:236:Infinity":7,"b:235:4:235:Infinity:undefined:undefined:undefined:undefined":2,"s:235:4:235:Infinity":8,"s:235:22:235:Infinity":9,"s:237:2:237:Infinity":10,"f:241:16:241:29":1,"s:242:19:242:Infinity":11,"s:243:18:243:Infinity":12,"b:244:2:244:Infinity:undefined:undefined:undefined:undefined":3,"s:244:2:244:Infinity":13,"s:244:30:244:Infinity":14,"s:245:18:245:Infinity":15,"b:246:2:246:Infinity:undefined:undefined:undefined:undefined":4,"s:246:2:246:Infinity":16,"s:246:30:246:Infinity":17,"b:247:2:247:Infinity:undefined:undefined:undefined:undefined":5,"s:247:2:247:Infinity":18,"s:247:30:247:Infinity":19,"b:248:2:248:Infinity:undefined:undefined:undefined:undefined":6,"s:248:2:248:Infinity":20,"b:248:6:248:39:248:39:248:70":7,"s:248:70:248:Infinity":21,"b:249:2:249:Infinity:undefined:undefined:undefined:undefined":8,"s:249:2:249:Infinity":22,"s:249:37:249:Infinity":23,"s:250:2:250:Infinity":24,"s:254:81:265:Infinity":25,"f:271:16:271:38":2,"s:272:2:276:Infinity":26,"f:276:13:276:23":3,"s:276:29:276:44":27,"f:280:16:280:30":4,"s:281:14:281:Infinity":28,"s:282:2:284:Infinity":29,"b:282:9:282:Infinity:283:9:283:Infinity:284:9:284:Infinity":9,"f:293:16:293:Infinity":5,"s:299:14:299:Infinity":30,"b:299:44:299:68:299:68:299:Infinity":10,"s:300:14:300:Infinity":31,"b:301:2:301:Infinity:undefined:undefined:undefined:undefined":11,"s:301:2:301:Infinity":32,"s:301:11:301:Infinity":33,"b:302:2:307:Infinity:undefined:undefined:undefined:undefined":12,"s:302:2:307:Infinity":34,"s:303:20:303:Infinity":35,"b:303:20:303:56:303:56:303:Infinity":13,"s:304:18:304:Infinity":36,"s:305:20:305:Infinity":37,"b:305:20:305:57:305:57:305:Infinity":14,"s:306:4:306:Infinity":38,"s:308:2:308:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/methodology-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/methodology-i18n.ts","statementMap":{"0":{"start":{"line":20,"column":87},"end":{"line":40,"column":null}},"1":{"start":{"line":43,"column":62},"end":{"line":348,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":14,"1":14},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:20:87:40:Infinity":0,"s:43:62:348:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/page-translations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/page-translations.ts","statementMap":{"0":{"start":{"line":63,"column":65},"end":{"line":540,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":2},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:63:65:540:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/stream-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/stream-i18n.ts","statementMap":{"0":{"start":{"line":20,"column":82},"end":{"line":33,"column":null}},"1":{"start":{"line":43,"column":74},"end":{"line":109,"column":null}},"2":{"start":{"line":112,"column":74},"end":{"line":321,"column":null}},"3":{"start":{"line":324,"column":60},"end":{"line":339,"column":null}},"4":{"start":{"line":343,"column":66},"end":{"line":358,"column":null}},"5":{"start":{"line":371,"column":2},"end":{"line":373,"column":null}},"6":{"start":{"line":373,"column":29},"end":{"line":373,"column":44}},"7":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"8":{"start":{"line":382,"column":25},"end":{"line":382,"column":null}},"9":{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},"10":{"start":{"line":383,"column":28},"end":{"line":383,"column":null}},"11":{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},"12":{"start":{"line":384,"column":36},"end":{"line":384,"column":null}},"13":{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},"14":{"start":{"line":385,"column":35},"end":{"line":385,"column":null}},"15":{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},"16":{"start":{"line":386,"column":34},"end":{"line":386,"column":null}},"17":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"18":{"start":{"line":387,"column":35},"end":{"line":387,"column":null}},"19":{"start":{"line":388,"column":2},"end":{"line":388,"column":null}},"20":{"start":{"line":393,"column":14},"end":{"line":393,"column":null}},"21":{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},"22":{"start":{"line":394,"column":11},"end":{"line":394,"column":null}},"23":{"start":{"line":395,"column":16},"end":{"line":395,"column":null}},"24":{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},"25":{"start":{"line":397,"column":17},"end":{"line":397,"column":null}},"26":{"start":{"line":398,"column":4},"end":{"line":398,"column":null}},"27":{"start":{"line":400,"column":2},"end":{"line":400,"column":null}},"28":{"start":{"line":405,"column":14},"end":{"line":405,"column":null}},"29":{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},"30":{"start":{"line":406,"column":11},"end":{"line":406,"column":null}},"31":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"32":{"start":{"line":407,"column":36},"end":{"line":407,"column":null}},"33":{"start":{"line":408,"column":18},"end":{"line":408,"column":null}},"34":{"start":{"line":409,"column":2},"end":{"line":409,"column":null}}},"fnMap":{"0":{"name":"prettifyStream","decl":{"start":{"line":370,"column":16},"end":{"line":370,"column":31}},"loc":{"start":{"line":370,"column":53},"end":{"line":374,"column":null}},"line":370},"1":{"name":"(anonymous_1)","decl":{"start":{"line":373,"column":13},"end":{"line":373,"column":23}},"loc":{"start":{"line":373,"column":29},"end":{"line":373,"column":44}},"line":373},"2":{"name":"streamIcon","decl":{"start":{"line":381,"column":16},"end":{"line":381,"column":27}},"loc":{"start":{"line":381,"column":49},"end":{"line":389,"column":null}},"line":381},"3":{"name":"streamDisplayName","decl":{"start":{"line":392,"column":16},"end":{"line":392,"column":34}},"loc":{"start":{"line":392,"column":72},"end":{"line":401,"column":null}},"line":392},"4":{"name":"streamDescription","decl":{"start":{"line":404,"column":16},"end":{"line":404,"column":34}},"loc":{"start":{"line":404,"column":72},"end":{"line":410,"column":null}},"line":404}},"branchMap":{"0":{"loc":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"type":"if","locations":[{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},{"start":{},"end":{}}],"line":382},"1":{"loc":{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},"type":"if","locations":[{"start":{"line":383,"column":2},"end":{"line":383,"column":null}},{"start":{},"end":{}}],"line":383},"2":{"loc":{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},"type":"if","locations":[{"start":{"line":384,"column":2},"end":{"line":384,"column":null}},{"start":{},"end":{}}],"line":384},"3":{"loc":{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},"type":"if","locations":[{"start":{"line":385,"column":2},"end":{"line":385,"column":null}},{"start":{},"end":{}}],"line":385},"4":{"loc":{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},"type":"if","locations":[{"start":{"line":386,"column":2},"end":{"line":386,"column":null}},{"start":{},"end":{}}],"line":386},"5":{"loc":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"type":"if","locations":[{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},{"start":{},"end":{}}],"line":387},"6":{"loc":{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},"type":"if","locations":[{"start":{"line":394,"column":2},"end":{"line":394,"column":null}},{"start":{},"end":{}}],"line":394},"7":{"loc":{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},"type":"if","locations":[{"start":{"line":396,"column":2},"end":{"line":399,"column":null}},{"start":{},"end":{}}],"line":396},"8":{"loc":{"start":{"line":397,"column":17},"end":{"line":397,"column":null}},"type":"binary-expr","locations":[{"start":{"line":397,"column":17},"end":{"line":397,"column":62}},{"start":{"line":397,"column":62},"end":{"line":397,"column":null}}],"line":397},"9":{"loc":{"start":{"line":398,"column":14},"end":{"line":398,"column":92}},"type":"cond-expr","locations":[{"start":{"line":398,"column":30},"end":{"line":398,"column":43}},{"start":{"line":398,"column":43},"end":{"line":398,"column":92}}],"line":398},"10":{"loc":{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},"type":"if","locations":[{"start":{"line":406,"column":2},"end":{"line":406,"column":null}},{"start":{},"end":{}}],"line":406},"11":{"loc":{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},"type":"if","locations":[{"start":{"line":407,"column":2},"end":{"line":407,"column":null}},{"start":{},"end":{}}],"line":407},"12":{"loc":{"start":{"line":408,"column":18},"end":{"line":408,"column":null}},"type":"binary-expr","locations":[{"start":{"line":408,"column":18},"end":{"line":408,"column":52}},{"start":{"line":408,"column":52},"end":{"line":408,"column":null}}],"line":408}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":2673,"6":5528,"7":11102,"8":7801,"9":3301,"10":660,"11":2641,"12":1710,"13":931,"14":0,"15":931,"16":0,"17":931,"18":90,"19":841,"20":12031,"21":12031,"22":8460,"23":3571,"24":3571,"25":900,"26":900,"27":2671,"28":11268,"29":11268,"30":8628,"31":2640,"32":1710,"33":930,"34":11268},"f":{"0":2673,"1":5528,"2":11102,"3":12031,"4":11268},"b":{"0":[7801,3301],"1":[660,2641],"2":[1710,931],"3":[0,931],"4":[0,931],"5":[90,841],"6":[8460,3571],"7":[900,2671],"8":[900,0],"9":[90,810],"10":[8628,2640],"11":[1710,930],"12":[930,0]},"meta":{"lastBranch":13,"lastFunction":5,"lastStatement":35,"seen":{"s:20:82:33:Infinity":0,"s:43:74:109:Infinity":1,"s:112:74:321:Infinity":2,"s:324:60:339:Infinity":3,"s:343:66:358:Infinity":4,"f:370:16:370:31":0,"s:371:2:373:Infinity":5,"f:373:13:373:23":1,"s:373:29:373:44":6,"f:381:16:381:27":2,"b:382:2:382:Infinity:undefined:undefined:undefined:undefined":0,"s:382:2:382:Infinity":7,"s:382:25:382:Infinity":8,"b:383:2:383:Infinity:undefined:undefined:undefined:undefined":1,"s:383:2:383:Infinity":9,"s:383:28:383:Infinity":10,"b:384:2:384:Infinity:undefined:undefined:undefined:undefined":2,"s:384:2:384:Infinity":11,"s:384:36:384:Infinity":12,"b:385:2:385:Infinity:undefined:undefined:undefined:undefined":3,"s:385:2:385:Infinity":13,"s:385:35:385:Infinity":14,"b:386:2:386:Infinity:undefined:undefined:undefined:undefined":4,"s:386:2:386:Infinity":15,"s:386:34:386:Infinity":16,"b:387:2:387:Infinity:undefined:undefined:undefined:undefined":5,"s:387:2:387:Infinity":17,"s:387:35:387:Infinity":18,"s:388:2:388:Infinity":19,"f:392:16:392:34":3,"s:393:14:393:Infinity":20,"b:394:2:394:Infinity:undefined:undefined:undefined:undefined":6,"s:394:2:394:Infinity":21,"s:394:11:394:Infinity":22,"s:395:16:395:Infinity":23,"b:396:2:399:Infinity:undefined:undefined:undefined:undefined":7,"s:396:2:399:Infinity":24,"s:397:17:397:Infinity":25,"b:397:17:397:62:397:62:397:Infinity":8,"s:398:4:398:Infinity":26,"b:398:30:398:43:398:43:398:92":9,"s:400:2:400:Infinity":27,"f:404:16:404:34":4,"s:405:14:405:Infinity":28,"b:406:2:406:Infinity:undefined:undefined:undefined:undefined":10,"s:406:2:406:Infinity":29,"s:406:11:406:Infinity":30,"b:407:2:407:Infinity:undefined:undefined:undefined:undefined":11,"s:407:2:407:Infinity":31,"s:407:36:407:Infinity":32,"s:408:18:408:Infinity":33,"b:408:18:408:52:408:52:408:Infinity":12,"s:409:2:409:Infinity":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/daily-day.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/daily-day.ts","statementMap":{"0":{"start":{"line":37,"column":14},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"2":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"3":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"4":{"start":{"line":48,"column":33},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"6":{"start":{"line":49,"column":36},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"8":{"start":{"line":50,"column":29},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"10":{"start":{"line":51,"column":28},"end":{"line":51,"column":null}},"11":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"12":{"start":{"line":61,"column":22},"end":{"line":86,"column":null}},"13":{"start":{"line":62,"column":24},"end":{"line":62,"column":null}},"14":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"15":{"start":{"line":64,"column":26},"end":{"line":76,"column":null}},"16":{"start":{"line":73,"column":25},"end":{"line":73,"column":385}},"17":{"start":{"line":77,"column":4},"end":{"line":84,"column":null}},"18":{"start":{"line":88,"column":2},"end":{"line":98,"column":null}}},"fnMap":{"0":{"name":"artifactBaseName","decl":{"start":{"line":36,"column":16},"end":{"line":36,"column":33}},"loc":{"start":{"line":36,"column":55},"end":{"line":39,"column":null}},"line":36},"1":{"name":"artifactIcon","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":29}},"loc":{"start":{"line":46,"column":51},"end":{"line":53,"column":null}},"line":46},"2":{"name":"renderDailyDay","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":31}},"loc":{"start":{"line":60,"column":89},"end":{"line":101,"column":null}},"line":60},"3":{"name":"(anonymous_3)","decl":{"start":{"line":61,"column":34},"end":{"line":61,"column":39}},"loc":{"start":{"line":61,"column":45},"end":{"line":86,"column":3}},"line":61},"4":{"name":"(anonymous_4)","decl":{"start":{"line":73,"column":14},"end":{"line":73,"column":19}},"loc":{"start":{"line":73,"column":25},"end":{"line":73,"column":385}},"line":73}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":9},"end":{"line":38,"column":null}},"type":"cond-expr","locations":[{"start":{"line":38,"column":20},"end":{"line":38,"column":42}},{"start":{"line":38,"column":42},"end":{"line":38,"column":null}}],"line":38},"1":{"loc":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":48},"2":{"loc":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"3":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":50},"4":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"5":{"loc":{"start":{"line":64,"column":26},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":8},"end":{"line":76,"column":null}},{"start":{"line":76,"column":8},"end":{"line":76,"column":null}}],"line":64}},"s":{"0":818470,"1":818470,"2":409237,"3":409237,"4":173012,"5":236225,"6":0,"7":236225,"8":48391,"9":187834,"10":0,"11":187834,"12":1920,"13":11100,"14":11100,"15":11100,"16":409230,"17":11100,"18":1920},"f":{"0":818470,"1":409237,"2":1920,"3":11100,"4":409230},"b":{"0":[247682,570788],"1":[173012,236225],"2":[0,236225],"3":[48391,187834],"4":[0,187834],"5":[11100,0]},"meta":{"lastBranch":6,"lastFunction":5,"lastStatement":19,"seen":{"f:36:16:36:33":0,"s:37:14:37:Infinity":0,"s:38:2:38:Infinity":1,"b:38:20:38:42:38:42:38:Infinity":0,"f:46:16:46:29":1,"s:47:15:47:Infinity":2,"b:48:2:48:Infinity:undefined:undefined:undefined:undefined":1,"s:48:2:48:Infinity":3,"s:48:33:48:Infinity":4,"b:49:2:49:Infinity:undefined:undefined:undefined:undefined":2,"s:49:2:49:Infinity":5,"s:49:36:49:Infinity":6,"b:50:2:50:Infinity:undefined:undefined:undefined:undefined":3,"s:50:2:50:Infinity":7,"s:50:29:50:Infinity":8,"b:51:2:51:Infinity:undefined:undefined:undefined:undefined":4,"s:51:2:51:Infinity":9,"s:51:28:51:Infinity":10,"s:52:2:52:Infinity":11,"f:60:16:60:31":2,"s:61:22:86:Infinity":12,"f:61:34:61:39":3,"s:62:24:62:Infinity":13,"s:63:17:63:Infinity":14,"s:64:26:76:Infinity":15,"b:65:8:76:Infinity:76:8:76:Infinity":5,"f:73:14:73:19":4,"s:73:25:73:385":16,"s:77:4:84:Infinity":17,"s:88:2:98:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/template-i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/i18n/template-i18n.ts","statementMap":{"0":{"start":{"line":22,"column":84},"end":{"line":58,"column":null}},"1":{"start":{"line":62,"column":59},"end":{"line":255,"column":null}},"2":{"start":{"line":259,"column":68},"end":{"line":274,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":14,"1":14,"2":14},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":3,"seen":{"s:22:84:58:Infinity":0,"s:62:59:255:Infinity":1,"s:259:68:274:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/style.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/style.ts","statementMap":{"0":{"start":{"line":18,"column":38},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:38:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/page.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/page.ts","statementMap":{"0":{"start":{"line":37,"column":17},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":20},"end":{"line":38,"column":null}},"2":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"3":{"start":{"line":41,"column":18},"end":{"line":41,"column":null}},"4":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":21},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":26},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":22},"end":{"line":46,"column":null}},"8":{"start":{"line":48,"column":39},"end":{"line":50,"column":null}},"9":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"10":{"start":{"line":63,"column":12},"end":{"line":63,"column":null}},"11":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"12":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"13":{"start":{"line":66,"column":20},"end":{"line":66,"column":null}},"14":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"15":{"start":{"line":69,"column":24},"end":{"line":69,"column":null}},"16":{"start":{"line":70,"column":20},"end":{"line":70,"column":null}},"17":{"start":{"line":71,"column":15},"end":{"line":71,"column":32}},"18":{"start":{"line":72,"column":25},"end":{"line":72,"column":null}},"19":{"start":{"line":72,"column":47},"end":{"line":72,"column":69}},"20":{"start":{"line":74,"column":17},"end":{"line":74,"column":null}},"21":{"start":{"line":75,"column":21},"end":{"line":75,"column":null}},"22":{"start":{"line":76,"column":20},"end":{"line":76,"column":null}},"23":{"start":{"line":78,"column":31},"end":{"line":78,"column":null}},"24":{"start":{"line":79,"column":28},"end":{"line":79,"column":null}},"25":{"start":{"line":80,"column":25},"end":{"line":80,"column":null}},"26":{"start":{"line":80,"column":47},"end":{"line":80,"column":73}},"27":{"start":{"line":81,"column":24},"end":{"line":81,"column":null}},"28":{"start":{"line":81,"column":45},"end":{"line":81,"column":71}},"29":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"30":{"start":{"line":84,"column":19},"end":{"line":84,"column":null}},"31":{"start":{"line":86,"column":27},"end":{"line":113,"column":null}},"32":{"start":{"line":115,"column":29},"end":{"line":124,"column":null}},"33":{"start":{"line":121,"column":47},"end":{"line":123,"column":6}},"34":{"start":{"line":126,"column":32},"end":{"line":135,"column":null}},"35":{"start":{"line":132,"column":50},"end":{"line":134,"column":6}},"36":{"start":{"line":136,"column":28},"end":{"line":145,"column":null}},"37":{"start":{"line":142,"column":48},"end":{"line":144,"column":6}},"38":{"start":{"line":147,"column":23},"end":{"line":154,"column":null}},"39":{"start":{"line":156,"column":25},"end":{"line":162,"column":null}},"40":{"start":{"line":163,"column":20},"end":{"line":172,"column":null}},"41":{"start":{"line":174,"column":28},"end":{"line":179,"column":null}},"42":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"43":{"start":{"line":180,"column":26},"end":{"line":180,"column":null}},"44":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"45":{"start":{"line":181,"column":29},"end":{"line":181,"column":null}},"46":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"47":{"start":{"line":182,"column":25},"end":{"line":182,"column":null}},"48":{"start":{"line":191,"column":21},"end":{"line":193,"column":null}},"49":{"start":{"line":192,"column":41},"end":{"line":192,"column":49}},"50":{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},"51":{"start":{"line":195,"column":4},"end":{"line":195,"column":null}},"52":{"start":{"line":195,"column":35},"end":{"line":195,"column":null}},"53":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"54":{"start":{"line":196,"column":33},"end":{"line":196,"column":null}},"55":{"start":{"line":198,"column":29},"end":{"line":198,"column":null}},"56":{"start":{"line":200,"column":19},"end":{"line":200,"column":null}},"57":{"start":{"line":202,"column":64},"end":{"line":202,"column":null}},"58":{"start":{"line":203,"column":2},"end":{"line":205,"column":null}},"59":{"start":{"line":204,"column":4},"end":{"line":204,"column":null}},"60":{"start":{"line":207,"column":17},"end":{"line":228,"column":null}},"61":{"start":{"line":230,"column":15},"end":{"line":305,"column":null}},"62":{"start":{"line":302,"column":22},"end":{"line":305,"column":24}},"63":{"start":{"line":309,"column":2},"end":{"line":312,"column":null}}},"fnMap":{"0":{"name":"hreflangCodeOf","decl":{"start":{"line":53,"column":9},"end":{"line":53,"column":24}},"loc":{"start":{"line":53,"column":48},"end":{"line":55,"column":null}},"line":53},"1":{"name":"generatePoliticalIntelligenceHtml","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":50}},"loc":{"start":{"line":62,"column":74},"end":{"line":313,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":72,"column":30},"end":{"line":72,"column":38}},"loc":{"start":{"line":72,"column":47},"end":{"line":72,"column":69}},"line":72},"3":{"name":"(anonymous_3)","decl":{"start":{"line":80,"column":36},"end":{"line":80,"column":41}},"loc":{"start":{"line":80,"column":47},"end":{"line":80,"column":73}},"line":80},"4":{"name":"(anonymous_4)","decl":{"start":{"line":81,"column":34},"end":{"line":81,"column":39}},"loc":{"start":{"line":81,"column":45},"end":{"line":81,"column":71}},"line":81},"5":{"name":"(anonymous_5)","decl":{"start":{"line":121,"column":32},"end":{"line":121,"column":37}},"loc":{"start":{"line":121,"column":47},"end":{"line":123,"column":6}},"line":121},"6":{"name":"(anonymous_6)","decl":{"start":{"line":132,"column":35},"end":{"line":132,"column":40}},"loc":{"start":{"line":132,"column":50},"end":{"line":134,"column":6}},"line":132},"7":{"name":"(anonymous_7)","decl":{"start":{"line":142,"column":31},"end":{"line":142,"column":36}},"loc":{"start":{"line":142,"column":48},"end":{"line":144,"column":6}},"line":142},"8":{"name":"(anonymous_8)","decl":{"start":{"line":192,"column":30},"end":{"line":192,"column":35}},"loc":{"start":{"line":192,"column":41},"end":{"line":192,"column":49}},"line":192},"9":{"name":"(anonymous_9)","decl":{"start":{"line":302,"column":11},"end":{"line":302,"column":16}},"loc":{"start":{"line":302,"column":22},"end":{"line":305,"column":24}},"line":302}},"branchMap":{"0":{"loc":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":31},"end":{"line":65,"column":63}},{"start":{"line":65,"column":63},"end":{"line":65,"column":null}}],"line":65},"1":{"loc":{"start":{"line":66,"column":20},"end":{"line":66,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":47}},{"start":{"line":66,"column":47},"end":{"line":66,"column":null}}],"line":66},"2":{"loc":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":67,"column":34},"end":{"line":67,"column":51}},{"start":{"line":67,"column":51},"end":{"line":67,"column":null}}],"line":67},"3":{"loc":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"type":"binary-expr","locations":[{"start":{"line":83,"column":21},"end":{"line":83,"column":38}},{"start":{"line":83,"column":38},"end":{"line":83,"column":null}}],"line":83},"4":{"loc":{"start":{"line":115,"column":29},"end":{"line":124,"column":null}},"type":"cond-expr","locations":[{"start":{"line":115,"column":53},"end":{"line":124,"column":6}},{"start":{"line":124,"column":6},"end":{"line":124,"column":null}}],"line":115},"5":{"loc":{"start":{"line":126,"column":32},"end":{"line":135,"column":null}},"type":"cond-expr","locations":[{"start":{"line":126,"column":59},"end":{"line":135,"column":6}},{"start":{"line":135,"column":6},"end":{"line":135,"column":null}}],"line":126},"6":{"loc":{"start":{"line":136,"column":28},"end":{"line":145,"column":null}},"type":"cond-expr","locations":[{"start":{"line":136,"column":51},"end":{"line":145,"column":6}},{"start":{"line":145,"column":6},"end":{"line":145,"column":null}}],"line":136},"7":{"loc":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"type":"if","locations":[{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},{"start":{},"end":{}}],"line":180},"8":{"loc":{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":181,"column":2},"end":{"line":181,"column":null}},{"start":{},"end":{}}],"line":181},"9":{"loc":{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":2},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"10":{"loc":{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":194,"column":2},"end":{"line":197,"column":null}},{"start":{},"end":{}}],"line":194},"11":{"loc":{"start":{"line":204,"column":28},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":204,"column":41},"end":{"line":204,"column":73}},{"start":{"line":204,"column":73},"end":{"line":204,"column":null}}],"line":204},"12":{"loc":{"start":{"line":284,"column":2},"end":{"line":292,"column":null}},"type":"cond-expr","locations":[{"start":{"line":284,"column":25},"end":{"line":292,"column":null}},{"start":{"line":292,"column":26},"end":{"line":292,"column":null}}],"line":284}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":30,"10":30,"11":30,"12":30,"13":30,"14":30,"15":30,"16":30,"17":30,"18":30,"19":1920,"20":30,"21":30,"22":30,"23":30,"24":30,"25":30,"26":420,"27":30,"28":1500,"29":30,"30":30,"31":30,"32":30,"33":420,"34":30,"35":660,"36":30,"37":1200,"38":30,"39":30,"40":30,"41":30,"42":30,"43":30,"44":30,"45":30,"46":30,"47":30,"48":30,"49":232,"50":30,"51":3,"52":66,"53":3,"54":120,"55":30,"56":30,"57":30,"58":30,"59":420,"60":30,"61":30,"62":150,"63":30},"f":{"0":30,"1":30,"2":1920,"3":420,"4":1500,"5":420,"6":660,"7":1200,"8":232,"9":150},"b":{"0":[3,27],"1":[3,27],"2":[3,27],"3":[30,0],"4":[30,0],"5":[30,0],"6":[30,0],"7":[30,0],"8":[30,0],"9":[30,0],"10":[3,27],"11":[30,390],"12":[30,0]},"meta":{"lastBranch":13,"lastFunction":10,"lastStatement":64,"seen":{"s:37:17:37:Infinity":0,"s:38:20:38:Infinity":1,"s:40:19:40:Infinity":2,"s:41:18:41:Infinity":3,"s:43:17:43:Infinity":4,"s:44:21:44:Infinity":5,"s:45:26:45:Infinity":6,"s:46:22:46:Infinity":7,"s:48:39:50:Infinity":8,"f:53:9:53:24":0,"s:54:2:54:Infinity":9,"f:62:16:62:50":1,"s:63:12:63:Infinity":10,"s:64:20:64:Infinity":11,"s:65:19:65:Infinity":12,"b:65:31:65:63:65:63:65:Infinity":0,"s:66:20:66:Infinity":13,"b:66:32:66:47:66:47:66:Infinity":1,"s:67:22:67:Infinity":14,"b:67:34:67:51:67:51:67:Infinity":2,"s:69:24:69:Infinity":15,"s:70:20:70:Infinity":16,"s:71:15:71:32":17,"s:72:25:72:Infinity":18,"f:72:30:72:38":2,"s:72:47:72:69":19,"s:74:17:74:Infinity":20,"s:75:21:75:Infinity":21,"s:76:20:76:Infinity":22,"s:78:31:78:Infinity":23,"s:79:28:79:Infinity":24,"s:80:25:80:Infinity":25,"f:80:36:80:41":3,"s:80:47:80:73":26,"s:81:24:81:Infinity":27,"f:81:34:81:39":4,"s:81:45:81:71":28,"s:83:21:83:Infinity":29,"b:83:21:83:38:83:38:83:Infinity":3,"s:84:19:84:Infinity":30,"s:86:27:113:Infinity":31,"s:115:29:124:Infinity":32,"b:115:53:124:6:124:6:124:Infinity":4,"f:121:32:121:37":5,"s:121:47:123:6":33,"s:126:32:135:Infinity":34,"b:126:59:135:6:135:6:135:Infinity":5,"f:132:35:132:40":6,"s:132:50:134:6":35,"s:136:28:145:Infinity":36,"b:136:51:145:6:145:6:145:Infinity":6,"f:142:31:142:36":7,"s:142:48:144:6":37,"s:147:23:154:Infinity":38,"s:156:25:162:Infinity":39,"s:163:20:172:Infinity":40,"s:174:28:179:Infinity":41,"b:180:2:180:Infinity:undefined:undefined:undefined:undefined":7,"s:180:2:180:Infinity":42,"s:180:26:180:Infinity":43,"b:181:2:181:Infinity:undefined:undefined:undefined:undefined":8,"s:181:2:181:Infinity":44,"s:181:29:181:Infinity":45,"b:182:2:182:Infinity:undefined:undefined:undefined:undefined":9,"s:182:2:182:Infinity":46,"s:182:25:182:Infinity":47,"s:191:21:193:Infinity":48,"f:192:30:192:35":8,"s:192:41:192:49":49,"b:194:2:197:Infinity:undefined:undefined:undefined:undefined":10,"s:194:2:197:Infinity":50,"s:195:4:195:Infinity":51,"s:195:35:195:Infinity":52,"s:196:4:196:Infinity":53,"s:196:33:196:Infinity":54,"s:198:29:198:Infinity":55,"s:200:19:200:Infinity":56,"s:202:64:202:Infinity":57,"s:203:2:205:Infinity":58,"s:204:4:204:Infinity":59,"b:204:41:204:73:204:73:204:Infinity":11,"s:207:17:228:Infinity":60,"s:230:15:305:Infinity":61,"b:284:25:292:Infinity:292:26:292:Infinity":12,"f:302:11:302:16":9,"s:302:22:305:24":62,"s:309:2:312:Infinity":63}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/polling-fetch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/polling-fetch.ts","statementMap":{"0":{"start":{"line":19,"column":27},"end":{"line":19,"column":null}},"1":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"2":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"3":{"start":{"line":65,"column":38},"end":{"line":65,"column":null}},"4":{"start":{"line":70,"column":42},"end":{"line":70,"column":null}},"5":{"start":{"line":71,"column":79},"end":{"line":81,"column":null}},"6":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"7":{"start":{"line":84,"column":16},"end":{"line":84,"column":null}},"8":{"start":{"line":85,"column":17},"end":{"line":85,"column":null}},"9":{"start":{"line":86,"column":15},"end":{"line":86,"column":null}},"10":{"start":{"line":87,"column":22},"end":{"line":87,"column":null}},"11":{"start":{"line":88,"column":16},"end":{"line":88,"column":null}},"12":{"start":{"line":89,"column":17},"end":{"line":89,"column":null}},"13":{"start":{"line":90,"column":23},"end":{"line":90,"column":null}},"14":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"15":{"start":{"line":97,"column":19},"end":{"line":100,"column":null}},"16":{"start":{"line":101,"column":2},"end":{"line":108,"column":null}},"17":{"start":{"line":102,"column":18},"end":{"line":102,"column":null}},"18":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"19":{"start":{"line":103,"column":21},"end":{"line":103,"column":null}},"20":{"start":{"line":104,"column":18},"end":{"line":104,"column":null}},"21":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"22":{"start":{"line":106,"column":6},"end":{"line":106,"column":null}},"23":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"24":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"25":{"start":{"line":125,"column":2},"end":{"line":135,"column":null}},"26":{"start":{"line":126,"column":17},"end":{"line":126,"column":null}},"27":{"start":{"line":127,"column":18},"end":{"line":127,"column":null}},"28":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"29":{"start":{"line":128,"column":15},"end":{"line":128,"column":null}},"30":{"start":{"line":129,"column":21},"end":{"line":129,"column":null}},"31":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"32":{"start":{"line":130,"column":59},"end":{"line":130,"column":null}},"33":{"start":{"line":131,"column":21},"end":{"line":131,"column":null}},"34":{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},"35":{"start":{"line":132,"column":32},"end":{"line":132,"column":null}},"36":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"37":{"start":{"line":133,"column":36},"end":{"line":133,"column":null}},"38":{"start":{"line":134,"column":4},"end":{"line":134,"column":null}},"39":{"start":{"line":136,"column":20},"end":{"line":136,"column":null}},"40":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"41":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"42":{"start":{"line":140,"column":2},"end":{"line":140,"column":null}},"43":{"start":{"line":149,"column":21},"end":{"line":149,"column":null}},"44":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"45":{"start":{"line":151,"column":15},"end":{"line":151,"column":null}},"46":{"start":{"line":152,"column":22},"end":{"line":152,"column":null}},"47":{"start":{"line":153,"column":21},"end":{"line":153,"column":null}},"48":{"start":{"line":154,"column":25},"end":{"line":154,"column":null}},"49":{"start":{"line":155,"column":26},"end":{"line":155,"column":null}},"50":{"start":{"line":156,"column":21},"end":{"line":156,"column":null}},"51":{"start":{"line":158,"column":54},"end":{"line":158,"column":null}},"52":{"start":{"line":159,"column":2},"end":{"line":164,"column":null}},"53":{"start":{"line":160,"column":18},"end":{"line":160,"column":null}},"54":{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},"55":{"start":{"line":162,"column":6},"end":{"line":162,"column":null}},"56":{"start":{"line":166,"column":27},"end":{"line":166,"column":null}},"57":{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},"58":{"start":{"line":168,"column":4},"end":{"line":178,"column":null}},"59":{"start":{"line":181,"column":2},"end":{"line":192,"column":null}},"60":{"start":{"line":196,"column":20},"end":{"line":196,"column":null}},"61":{"start":{"line":196,"column":43},"end":{"line":196,"column":63}},"62":{"start":{"line":197,"column":71},"end":{"line":197,"column":null}},"63":{"start":{"line":198,"column":2},"end":{"line":208,"column":null}},"64":{"start":{"line":199,"column":19},"end":{"line":201,"column":null}},"65":{"start":{"line":200,"column":21},"end":{"line":200,"column":44}},"66":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"67":{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},"68":{"start":{"line":202,"column":29},"end":{"line":202,"column":null}},"69":{"start":{"line":203,"column":16},"end":{"line":203,"column":null}},"70":{"start":{"line":203,"column":46},"end":{"line":203,"column":59}},"71":{"start":{"line":204,"column":4},"end":{"line":207,"column":null}},"72":{"start":{"line":209,"column":2},"end":{"line":212,"column":null}},"73":{"start":{"line":220,"column":21},"end":{"line":220,"column":null}},"74":{"start":{"line":221,"column":16},"end":{"line":221,"column":null}},"75":{"start":{"line":221,"column":33},"end":{"line":221,"column":53}},"76":{"start":{"line":222,"column":2},"end":{"line":236,"column":null}},"77":{"start":{"line":223,"column":21},"end":{"line":229,"column":null}},"78":{"start":{"line":232,"column":17},"end":{"line":232,"column":null}},"79":{"start":{"line":233,"column":4},"end":{"line":233,"column":null}},"80":{"start":{"line":235,"column":4},"end":{"line":235,"column":null}},"81":{"start":{"line":240,"column":20},"end":{"line":240,"column":null}},"82":{"start":{"line":241,"column":18},"end":{"line":241,"column":null}},"83":{"start":{"line":242,"column":20},"end":{"line":242,"column":null}},"84":{"start":{"line":244,"column":16},"end":{"line":297,"column":null}},"85":{"start":{"line":246,"column":6},"end":{"line":295,"column":null}},"86":{"start":{"line":247,"column":41},"end":{"line":247,"column":null}},"87":{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},"88":{"start":{"line":249,"column":10},"end":{"line":256,"column":null}},"89":{"start":{"line":261,"column":28},"end":{"line":261,"column":null}},"90":{"start":{"line":262,"column":29},"end":{"line":262,"column":null}},"91":{"start":{"line":263,"column":32},"end":{"line":263,"column":null}},"92":{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},"93":{"start":{"line":265,"column":39},"end":{"line":265,"column":null}},"94":{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},"95":{"start":{"line":267,"column":12},"end":{"line":267,"column":null}},"96":{"start":{"line":268,"column":71},"end":{"line":268,"column":null}},"97":{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},"98":{"start":{"line":270,"column":14},"end":{"line":270,"column":null}},"99":{"start":{"line":271,"column":14},"end":{"line":271,"column":null}},"100":{"start":{"line":275,"column":19},"end":{"line":275,"column":null}},"101":{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},"102":{"start":{"line":277,"column":30},"end":{"line":277,"column":null}},"103":{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},"104":{"start":{"line":279,"column":71},"end":{"line":279,"column":null}},"105":{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},"106":{"start":{"line":281,"column":14},"end":{"line":281,"column":null}},"107":{"start":{"line":285,"column":8},"end":{"line":285,"column":null}},"108":{"start":{"line":287,"column":8},"end":{"line":294,"column":null}},"109":{"start":{"line":299,"column":2},"end":{"line":305,"column":null}},"110":{"start":{"line":309,"column":2},"end":{"line":309,"column":null}},"111":{"start":{"line":310,"column":2},"end":{"line":310,"column":null}},"112":{"start":{"line":311,"column":2},"end":{"line":311,"column":null}},"113":{"start":{"line":315,"column":15},"end":{"line":315,"column":null}},"114":{"start":{"line":316,"column":16},"end":{"line":316,"column":null}},"115":{"start":{"line":317,"column":2},"end":{"line":327,"column":null}},"116":{"start":{"line":317,"column":15},"end":{"line":317,"column":18}},"117":{"start":{"line":318,"column":18},"end":{"line":318,"column":null}},"118":{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},"119":{"start":{"line":320,"column":6},"end":{"line":320,"column":null}},"120":{"start":{"line":321,"column":6},"end":{"line":321,"column":null}},"121":{"start":{"line":322,"column":6},"end":{"line":322,"column":null}},"122":{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},"123":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"124":{"start":{"line":328,"column":2},"end":{"line":328,"column":null}},"125":{"start":{"line":332,"column":15},"end":{"line":332,"column":null}},"126":{"start":{"line":333,"column":18},"end":{"line":333,"column":null}},"127":{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},"128":{"start":{"line":335,"column":4},"end":{"line":335,"column":null}},"129":{"start":{"line":337,"column":2},"end":{"line":337,"column":null}},"130":{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},"131":{"start":{"line":341,"column":2},"end":{"line":344,"column":null}},"132":{"start":{"line":342,"column":4},"end":{"line":342,"column":null}},"133":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}}},"fnMap":{"0":{"name":"stripHtml","decl":{"start":{"line":92,"column":9},"end":{"line":92,"column":19}},"loc":{"start":{"line":92,"column":41},"end":{"line":94,"column":null}},"line":92},"1":{"name":"extractNumericPartyShare","decl":{"start":{"line":96,"column":9},"end":{"line":96,"column":34}},"loc":{"start":{"line":96,"column":90},"end":{"line":110,"column":null}},"line":96},"2":{"name":"isArchiveRootUrl","decl":{"start":{"line":112,"column":9},"end":{"line":112,"column":26}},"loc":{"start":{"line":112,"column":48},"end":{"line":119,"column":null}},"line":112},"3":{"name":"findFollowUpPollingUrl","decl":{"start":{"line":121,"column":9},"end":{"line":121,"column":32}},"loc":{"start":{"line":121,"column":80},"end":{"line":141,"column":null}},"line":121},"4":{"name":"extractPollingWaveFromHtml","decl":{"start":{"line":143,"column":16},"end":{"line":143,"column":null}},"loc":{"start":{"line":148,"column":15},"end":{"line":193,"column":null}},"line":148},"5":{"name":"buildPollingAggregate","decl":{"start":{"line":195,"column":16},"end":{"line":195,"column":38}},"loc":{"start":{"line":195,"column":98},"end":{"line":213,"column":null}},"line":195},"6":{"name":"(anonymous_6)","decl":{"start":{"line":196,"column":26},"end":{"line":196,"column":34}},"loc":{"start":{"line":196,"column":43},"end":{"line":196,"column":63}},"line":196},"7":{"name":"(anonymous_7)","decl":{"start":{"line":200,"column":7},"end":{"line":200,"column":12}},"loc":{"start":{"line":200,"column":21},"end":{"line":200,"column":44}},"line":200},"8":{"name":"(anonymous_8)","decl":{"start":{"line":201,"column":7},"end":{"line":201,"column":15}},"loc":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"line":201},"9":{"name":"(anonymous_9)","decl":{"start":{"line":203,"column":23},"end":{"line":203,"column":31}},"loc":{"start":{"line":203,"column":46},"end":{"line":203,"column":59}},"line":203},"10":{"name":"fetchWithTimeout","decl":{"start":{"line":215,"column":15},"end":{"line":215,"column":null}},"loc":{"start":{"line":219,"column":49},"end":{"line":237,"column":null}},"line":219},"11":{"name":"(anonymous_11)","decl":{"start":{"line":221,"column":16},"end":{"line":221,"column":33}},"loc":{"start":{"line":221,"column":33},"end":{"line":221,"column":53}},"line":221},"12":{"name":"fetchPollingContext","decl":{"start":{"line":239,"column":22},"end":{"line":239,"column":42}},"loc":{"start":{"line":239,"column":100},"end":{"line":306,"column":null}},"line":239},"13":{"name":"(anonymous_13)","decl":{"start":{"line":245,"column":18},"end":{"line":245,"column":25}},"loc":{"start":{"line":245,"column":60},"end":{"line":296,"column":5}},"line":245},"14":{"name":"persistPollingContext","decl":{"start":{"line":308,"column":16},"end":{"line":308,"column":38}},"loc":{"start":{"line":308,"column":108},"end":{"line":312,"column":null}},"line":308},"15":{"name":"parseArgs","decl":{"start":{"line":314,"column":9},"end":{"line":314,"column":19}},"loc":{"start":{"line":314,"column":82},"end":{"line":329,"column":null}},"line":314},"16":{"name":"main","decl":{"start":{"line":331,"column":15},"end":{"line":331,"column":37}},"loc":{"start":{"line":331,"column":37},"end":{"line":338,"column":null}},"line":331},"17":{"name":"(anonymous_17)","decl":{"start":{"line":341,"column":9},"end":{"line":341,"column":16}},"loc":{"start":{"line":341,"column":35},"end":{"line":344,"column":3}},"line":341}},"branchMap":{"0":{"loc":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":103},"1":{"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":105},"2":{"loc":{"start":{"line":127,"column":28},"end":{"line":127,"column":42}},"type":"binary-expr","locations":[{"start":{"line":127,"column":28},"end":{"line":127,"column":40}},{"start":{"line":127,"column":40},"end":{"line":127,"column":42}}],"line":127},"3":{"loc":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":128},"4":{"loc":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},{"start":{},"end":{}}],"line":130},"5":{"loc":{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":132,"column":null}},{"start":{},"end":{}}],"line":132},"6":{"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":null}},{"start":{},"end":{}}],"line":133},"7":{"loc":{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},"type":"if","locations":[{"start":{"line":137,"column":2},"end":{"line":139,"column":null}},{"start":{},"end":{}}],"line":137},"8":{"loc":{"start":{"line":137,"column":6},"end":{"line":137,"column":44}},"type":"binary-expr","locations":[{"start":{"line":137,"column":6},"end":{"line":137,"column":19}},{"start":{"line":137,"column":19},"end":{"line":137,"column":44}}],"line":137},"9":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":150,"column":34},"end":{"line":150,"column":61}},{"start":{"line":150,"column":61},"end":{"line":150,"column":null}}],"line":150},"10":{"loc":{"start":{"line":154,"column":25},"end":{"line":154,"column":null}},"type":"cond-expr","locations":[{"start":{"line":154,"column":38},"end":{"line":154,"column":76}},{"start":{"line":154,"column":76},"end":{"line":154,"column":null}}],"line":154},"11":{"loc":{"start":{"line":156,"column":21},"end":{"line":156,"column":null}},"type":"cond-expr","locations":[{"start":{"line":156,"column":44},"end":{"line":156,"column":86}},{"start":{"line":156,"column":86},"end":{"line":156,"column":null}}],"line":156},"12":{"loc":{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":161,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":161},"13":{"loc":{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":167,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":167},"14":{"loc":{"start":{"line":201,"column":42},"end":{"line":201,"column":93}},"type":"binary-expr","locations":[{"start":{"line":201,"column":42},"end":{"line":201,"column":71}},{"start":{"line":201,"column":71},"end":{"line":201,"column":93}}],"line":201},"15":{"loc":{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},"type":"if","locations":[{"start":{"line":202,"column":4},"end":{"line":202,"column":null}},{"start":{},"end":{}}],"line":202},"16":{"loc":{"start":{"line":239,"column":42},"end":{"line":239,"column":100}},"type":"default-arg","locations":[{"start":{"line":239,"column":71},"end":{"line":239,"column":100}}],"line":239},"17":{"loc":{"start":{"line":240,"column":20},"end":{"line":240,"column":null}},"type":"binary-expr","locations":[{"start":{"line":240,"column":20},"end":{"line":240,"column":40}},{"start":{"line":240,"column":40},"end":{"line":240,"column":null}}],"line":240},"18":{"loc":{"start":{"line":241,"column":18},"end":{"line":241,"column":null}},"type":"binary-expr","locations":[{"start":{"line":241,"column":18},"end":{"line":241,"column":36}},{"start":{"line":241,"column":36},"end":{"line":241,"column":null}}],"line":241},"19":{"loc":{"start":{"line":242,"column":20},"end":{"line":242,"column":null}},"type":"binary-expr","locations":[{"start":{"line":242,"column":20},"end":{"line":242,"column":38}},{"start":{"line":242,"column":38},"end":{"line":242,"column":null}}],"line":242},"20":{"loc":{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":8},"end":{"line":257,"column":null}},{"start":{},"end":{}}],"line":248},"21":{"loc":{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},"type":"if","locations":[{"start":{"line":264,"column":8},"end":{"line":274,"column":null}},{"start":{},"end":{}}],"line":264},"22":{"loc":{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},"type":"if","locations":[{"start":{"line":266,"column":10},"end":{"line":273,"column":null}},{"start":{},"end":{}}],"line":266},"23":{"loc":{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},"type":"if","locations":[{"start":{"line":269,"column":12},"end":{"line":272,"column":null}},{"start":{},"end":{}}],"line":269},"24":{"loc":{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},"type":"if","locations":[{"start":{"line":276,"column":8},"end":{"line":284,"column":null}},{"start":{},"end":{}}],"line":276},"25":{"loc":{"start":{"line":276,"column":12},"end":{"line":276,"column":65}},"type":"binary-expr","locations":[{"start":{"line":276,"column":12},"end":{"line":276,"column":45}},{"start":{"line":276,"column":45},"end":{"line":276,"column":65}}],"line":276},"26":{"loc":{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},"type":"if","locations":[{"start":{"line":278,"column":10},"end":{"line":283,"column":null}},{"start":{},"end":{}}],"line":278},"27":{"loc":{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":12},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":280},"28":{"loc":{"start":{"line":293,"column":17},"end":{"line":293,"column":null}},"type":"cond-expr","locations":[{"start":{"line":293,"column":42},"end":{"line":293,"column":58}},{"start":{"line":293,"column":58},"end":{"line":293,"column":null}}],"line":293},"29":{"loc":{"start":{"line":308,"column":63},"end":{"line":308,"column":108}},"type":"default-arg","locations":[{"start":{"line":308,"column":76},"end":{"line":308,"column":108}}],"line":308},"30":{"loc":{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":4},"end":{"line":323,"column":null}},{"start":{},"end":{}}],"line":319},"31":{"loc":{"start":{"line":320,"column":15},"end":{"line":320,"column":null}},"type":"binary-expr","locations":[{"start":{"line":320,"column":15},"end":{"line":320,"column":30}},{"start":{"line":320,"column":30},"end":{"line":320,"column":null}}],"line":320},"32":{"loc":{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},"type":"if","locations":[{"start":{"line":324,"column":4},"end":{"line":326,"column":null}},{"start":{},"end":{}}],"line":324},"33":{"loc":{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},"type":"if","locations":[{"start":{"line":334,"column":2},"end":{"line":336,"column":null}},{"start":{},"end":{}}],"line":334},"34":{"loc":{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},"type":"if","locations":[{"start":{"line":340,"column":0},"end":{"line":345,"column":null}},{"start":{},"end":{}}],"line":340},"35":{"loc":{"start":{"line":340,"column":66},"end":{"line":340,"column":87}},"type":"binary-expr","locations":[{"start":{"line":340,"column":66},"end":{"line":340,"column":85}},{"start":{"line":340,"column":85},"end":{"line":340,"column":87}}],"line":340},"36":{"loc":{"start":{"line":342,"column":36},"end":{"line":342,"column":92}},"type":"cond-expr","locations":[{"start":{"line":342,"column":61},"end":{"line":342,"column":77}},{"start":{"line":342,"column":77},"end":{"line":342,"column":92}}],"line":342}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":6,"15":24,"16":24,"17":32,"18":32,"19":16,"20":16,"21":16,"22":16,"23":8,"24":3,"25":1,"26":1,"27":1,"28":1,"29":0,"30":1,"31":1,"32":0,"33":1,"34":1,"35":0,"36":1,"37":0,"38":1,"39":0,"40":1,"41":0,"42":0,"43":3,"44":3,"45":3,"46":3,"47":3,"48":3,"49":3,"50":3,"51":3,"52":3,"53":24,"54":24,"55":16,"56":3,"57":3,"58":3,"59":0,"60":3,"61":3,"62":3,"63":3,"64":24,"65":24,"66":24,"67":24,"68":8,"69":16,"70":16,"71":16,"72":3,"73":3,"74":3,"75":0,"76":3,"77":3,"78":3,"79":3,"80":3,"81":2,"82":2,"83":2,"84":2,"85":2,"86":2,"87":2,"88":0,"89":2,"90":2,"91":2,"92":2,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":2,"101":2,"102":0,"103":0,"104":0,"105":0,"106":0,"107":2,"108":0,"109":2,"110":1,"111":1,"112":1,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":1,"131":0,"132":0,"133":0},"f":{"0":6,"1":24,"2":3,"3":1,"4":3,"5":3,"6":3,"7":24,"8":24,"9":16,"10":3,"11":0,"12":2,"13":2,"14":1,"15":0,"16":0,"17":0},"b":{"0":[16,16],"1":[16,0],"2":[1,0],"3":[0,1],"4":[0,1],"5":[0,1],"6":[0,1],"7":[0,1],"8":[1,0],"9":[2,1],"10":[1,2],"11":[1,2],"12":[16,8],"13":[3,0],"14":[24,16],"15":[8,16],"16":[2],"17":[2,0],"18":[2,0],"19":[2,0],"20":[0,2],"21":[1,1],"22":[1,0],"23":[1,0],"24":[0,2],"25":[2,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[1],"30":[0,0],"31":[0,0],"32":[0,0],"33":[0,0],"34":[0,1],"35":[1,0],"36":[0,0]},"meta":{"lastBranch":37,"lastFunction":18,"lastStatement":134,"seen":{"s:19:27:19:Infinity":0,"s:63:18:63:Infinity":1,"s:64:18:64:Infinity":2,"s:65:38:65:Infinity":3,"s:70:42:70:Infinity":4,"s:71:79:81:Infinity":5,"s:83:21:83:Infinity":6,"s:84:16:84:Infinity":7,"s:85:17:85:Infinity":8,"s:86:15:86:Infinity":9,"s:87:22:87:Infinity":10,"s:88:16:88:Infinity":11,"s:89:17:89:Infinity":12,"s:90:23:90:Infinity":13,"f:92:9:92:19":0,"s:93:2:93:Infinity":14,"f:96:9:96:34":1,"s:97:19:100:Infinity":15,"s:101:2:108:Infinity":16,"s:102:18:102:Infinity":17,"b:103:4:103:Infinity:undefined:undefined:undefined:undefined":0,"s:103:4:103:Infinity":18,"s:103:21:103:Infinity":19,"s:104:18:104:Infinity":20,"b:105:4:107:Infinity:undefined:undefined:undefined:undefined":1,"s:105:4:107:Infinity":21,"s:106:6:106:Infinity":22,"s:109:2:109:Infinity":23,"f:112:9:112:26":2,"s:118:2:118:Infinity":24,"f:121:9:121:32":3,"s:125:2:135:Infinity":25,"s:126:17:126:Infinity":26,"s:127:18:127:Infinity":27,"b:127:28:127:40:127:40:127:42":2,"b:128:4:128:Infinity:undefined:undefined:undefined:undefined":3,"s:128:4:128:Infinity":28,"s:128:15:128:Infinity":29,"s:129:21:129:Infinity":30,"b:130:4:130:Infinity:undefined:undefined:undefined:undefined":4,"s:130:4:130:Infinity":31,"s:130:59:130:Infinity":32,"s:131:21:131:Infinity":33,"b:132:4:132:Infinity:undefined:undefined:undefined:undefined":5,"s:132:4:132:Infinity":34,"s:132:32:132:Infinity":35,"b:133:4:133:Infinity:undefined:undefined:undefined:undefined":6,"s:133:4:133:Infinity":36,"s:133:36:133:Infinity":37,"s:134:4:134:Infinity":38,"s:136:20:136:Infinity":39,"b:137:2:139:Infinity:undefined:undefined:undefined:undefined":7,"s:137:2:139:Infinity":40,"b:137:6:137:19:137:19:137:44":8,"s:138:4:138:Infinity":41,"s:140:2:140:Infinity":42,"f:143:16:143:Infinity":4,"s:149:21:149:Infinity":43,"s:150:16:150:Infinity":44,"b:150:34:150:61:150:61:150:Infinity":9,"s:151:15:151:Infinity":45,"s:152:22:152:Infinity":46,"s:153:21:153:Infinity":47,"s:154:25:154:Infinity":48,"b:154:38:154:76:154:76:154:Infinity":10,"s:155:26:155:Infinity":49,"s:156:21:156:Infinity":50,"b:156:44:156:86:156:86:156:Infinity":11,"s:158:54:158:Infinity":51,"s:159:2:164:Infinity":52,"s:160:18:160:Infinity":53,"b:161:4:163:Infinity:undefined:undefined:undefined:undefined":12,"s:161:4:163:Infinity":54,"s:162:6:162:Infinity":55,"s:166:27:166:Infinity":56,"b:167:2:179:Infinity:undefined:undefined:undefined:undefined":13,"s:167:2:179:Infinity":57,"s:168:4:178:Infinity":58,"s:181:2:192:Infinity":59,"f:195:16:195:38":5,"s:196:20:196:Infinity":60,"f:196:26:196:34":6,"s:196:43:196:63":61,"s:197:71:197:Infinity":62,"s:198:2:208:Infinity":63,"s:199:19:201:Infinity":64,"f:200:7:200:12":7,"s:200:21:200:44":65,"f:201:7:201:15":8,"s:201:42:201:93":66,"b:201:42:201:71:201:71:201:93":14,"b:202:4:202:Infinity:undefined:undefined:undefined:undefined":15,"s:202:4:202:Infinity":67,"s:202:29:202:Infinity":68,"s:203:16:203:Infinity":69,"f:203:23:203:31":9,"s:203:46:203:59":70,"s:204:4:207:Infinity":71,"s:209:2:212:Infinity":72,"f:215:15:215:Infinity":10,"s:220:21:220:Infinity":73,"s:221:16:221:Infinity":74,"f:221:16:221:33":11,"s:221:33:221:53":75,"s:222:2:236:Infinity":76,"s:223:21:229:Infinity":77,"s:232:17:232:Infinity":78,"s:233:4:233:Infinity":79,"s:235:4:235:Infinity":80,"f:239:22:239:42":12,"b:239:71:239:100":16,"s:240:20:240:Infinity":81,"b:240:20:240:40:240:40:240:Infinity":17,"s:241:18:241:Infinity":82,"b:241:18:241:36:241:36:241:Infinity":18,"s:242:20:242:Infinity":83,"b:242:20:242:38:242:38:242:Infinity":19,"s:244:16:297:Infinity":84,"f:245:18:245:25":13,"s:246:6:295:Infinity":85,"s:247:41:247:Infinity":86,"b:248:8:257:Infinity:undefined:undefined:undefined:undefined":20,"s:248:8:257:Infinity":87,"s:249:10:256:Infinity":88,"s:261:28:261:Infinity":89,"s:262:29:262:Infinity":90,"s:263:32:263:Infinity":91,"b:264:8:274:Infinity:undefined:undefined:undefined:undefined":21,"s:264:8:274:Infinity":92,"s:265:39:265:Infinity":93,"b:266:10:273:Infinity:undefined:undefined:undefined:undefined":22,"s:266:10:273:Infinity":94,"s:267:12:267:Infinity":95,"s:268:71:268:Infinity":96,"b:269:12:272:Infinity:undefined:undefined:undefined:undefined":23,"s:269:12:272:Infinity":97,"s:270:14:270:Infinity":98,"s:271:14:271:Infinity":99,"s:275:19:275:Infinity":100,"b:276:8:284:Infinity:undefined:undefined:undefined:undefined":24,"s:276:8:284:Infinity":101,"b:276:12:276:45:276:45:276:65":25,"s:277:30:277:Infinity":102,"b:278:10:283:Infinity:undefined:undefined:undefined:undefined":26,"s:278:10:283:Infinity":103,"s:279:71:279:Infinity":104,"b:280:12:282:Infinity:undefined:undefined:undefined:undefined":27,"s:280:12:282:Infinity":105,"s:281:14:281:Infinity":106,"s:285:8:285:Infinity":107,"s:287:8:294:Infinity":108,"b:293:42:293:58:293:58:293:Infinity":28,"s:299:2:305:Infinity":109,"f:308:16:308:38":14,"b:308:76:308:108":29,"s:309:2:309:Infinity":110,"s:310:2:310:Infinity":111,"s:311:2:311:Infinity":112,"f:314:9:314:19":15,"s:315:15:315:Infinity":113,"s:316:16:316:Infinity":114,"s:317:2:327:Infinity":115,"s:317:15:317:18":116,"s:318:18:318:Infinity":117,"b:319:4:323:Infinity:undefined:undefined:undefined:undefined":30,"s:319:4:323:Infinity":118,"s:320:6:320:Infinity":119,"b:320:15:320:30:320:30:320:Infinity":31,"s:321:6:321:Infinity":120,"s:322:6:322:Infinity":121,"b:324:4:326:Infinity:undefined:undefined:undefined:undefined":32,"s:324:4:326:Infinity":122,"s:325:6:325:Infinity":123,"s:328:2:328:Infinity":124,"f:331:15:331:37":16,"s:332:15:332:Infinity":125,"s:333:18:333:Infinity":126,"b:334:2:336:Infinity:undefined:undefined:undefined:undefined":33,"s:334:2:336:Infinity":127,"s:335:4:335:Infinity":128,"s:337:2:337:Infinity":129,"b:340:0:345:Infinity:undefined:undefined:undefined:undefined":34,"s:340:0:345:Infinity":130,"b:340:66:340:85:340:85:340:87":35,"s:341:2:344:Infinity":131,"f:341:9:341:16":17,"s:342:4:342:Infinity":132,"b:342:61:342:77:342:77:342:92":36,"s:343:4:343:Infinity":133}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/grid.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/political-intelligence/render/grid.ts","statementMap":{"0":{"start":{"line":33,"column":2},"end":{"line":44,"column":null}},"1":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":4},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"renderCatalogGrid","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"loc":{"start":{"line":32,"column":10},"end":{"line":45,"column":null}},"line":32},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":17},"end":{"line":33,"column":22}},"loc":{"start":{"line":33,"column":28},"end":{"line":44,"column":3}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":18},"end":{"line":35,"column":49}},{"start":{"line":35,"column":49},"end":{"line":35,"column":null}}],"line":35}},"s":{"0":60,"1":1860,"2":1860,"3":1860},"f":{"0":60,"1":1860},"b":{"0":[1860,0]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":4,"seen":{"f:28:16:28:Infinity":0,"s:33:2:44:Infinity":0,"f:33:17:33:22":1,"s:34:17:34:Infinity":1,"s:35:18:35:Infinity":2,"b:35:18:35:49:35:49:35:Infinity":0,"s:36:4:42:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/postprocess-translated-brief.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/postprocess-translated-brief.ts","statementMap":{"0":{"start":{"line":36,"column":42},"end":{"line":39,"column":null}},"1":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"2":{"start":{"line":50,"column":19},"end":{"line":50,"column":null}},"3":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"4":{"start":{"line":51,"column":17},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":12},"end":{"line":52,"column":null}},"6":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"7":{"start":{"line":53,"column":10},"end":{"line":53,"column":null}},"8":{"start":{"line":54,"column":15},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"10":{"start":{"line":55,"column":29},"end":{"line":55,"column":null}},"11":{"start":{"line":59,"column":19},"end":{"line":59,"column":null}},"12":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"13":{"start":{"line":60,"column":56},"end":{"line":60,"column":null}},"14":{"start":{"line":61,"column":25},"end":{"line":61,"column":null}},"15":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"16":{"start":{"line":62,"column":35},"end":{"line":62,"column":null}},"17":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"18":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"19":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"20":{"start":{"line":98,"column":23},"end":{"line":98,"column":null}},"21":{"start":{"line":101,"column":26},"end":{"line":101,"column":null}},"22":{"start":{"line":104,"column":24},"end":{"line":104,"column":null}},"23":{"start":{"line":107,"column":25},"end":{"line":107,"column":null}},"24":{"start":{"line":126,"column":15},"end":{"line":126,"column":null}},"25":{"start":{"line":127,"column":2},"end":{"line":130,"column":null}},"26":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"27":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"28":{"start":{"line":131,"column":2},"end":{"line":131,"column":null}},"29":{"start":{"line":141,"column":22},"end":{"line":141,"column":null}},"30":{"start":{"line":142,"column":2},"end":{"line":197,"column":null}},"31":{"start":{"line":142,"column":15},"end":{"line":142,"column":18}},"32":{"start":{"line":143,"column":15},"end":{"line":143,"column":null}},"33":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"34":{"start":{"line":145,"column":6},"end":{"line":145,"column":null}},"35":{"start":{"line":146,"column":6},"end":{"line":146,"column":null}},"36":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"37":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"38":{"start":{"line":149,"column":31},"end":{"line":149,"column":null}},"39":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"40":{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},"41":{"start":{"line":159,"column":6},"end":{"line":159,"column":null}},"42":{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},"43":{"start":{"line":163,"column":19},"end":{"line":163,"column":null}},"44":{"start":{"line":164,"column":6},"end":{"line":164,"column":null}},"45":{"start":{"line":167,"column":19},"end":{"line":167,"column":null}},"46":{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},"47":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"48":{"start":{"line":172,"column":17},"end":{"line":172,"column":null}},"49":{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},"50":{"start":{"line":175,"column":30},"end":{"line":175,"column":null}},"51":{"start":{"line":176,"column":6},"end":{"line":189,"column":null}},"52":{"start":{"line":176,"column":19},"end":{"line":176,"column":26}},"53":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"54":{"start":{"line":178,"column":22},"end":{"line":178,"column":null}},"55":{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},"56":{"start":{"line":180,"column":10},"end":{"line":180,"column":null}},"57":{"start":{"line":181,"column":10},"end":{"line":186,"column":null}},"58":{"start":{"line":188,"column":8},"end":{"line":188,"column":null}},"59":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"60":{"start":{"line":196,"column":4},"end":{"line":196,"column":null}},"61":{"start":{"line":198,"column":2},"end":{"line":198,"column":null}},"62":{"start":{"line":206,"column":16},"end":{"line":206,"column":null}},"63":{"start":{"line":207,"column":16},"end":{"line":207,"column":null}},"64":{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},"65":{"start":{"line":210,"column":4},"end":{"line":210,"column":null}},"66":{"start":{"line":213,"column":25},"end":{"line":213,"column":null}},"67":{"start":{"line":214,"column":18},"end":{"line":214,"column":null}},"68":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"69":{"start":{"line":219,"column":4},"end":{"line":219,"column":null}},"70":{"start":{"line":227,"column":17},"end":{"line":227,"column":null}},"71":{"start":{"line":228,"column":16},"end":{"line":228,"column":null}},"72":{"start":{"line":229,"column":19},"end":{"line":229,"column":null}},"73":{"start":{"line":231,"column":2},"end":{"line":236,"column":null}},"74":{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},"75":{"start":{"line":252,"column":4},"end":{"line":252,"column":null}},"76":{"start":{"line":254,"column":17},"end":{"line":254,"column":null}},"77":{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},"78":{"start":{"line":256,"column":4},"end":{"line":256,"column":null}},"79":{"start":{"line":259,"column":2},"end":{"line":263,"column":null}},"80":{"start":{"line":260,"column":4},"end":{"line":260,"column":null}},"81":{"start":{"line":262,"column":4},"end":{"line":262,"column":null}},"82":{"start":{"line":264,"column":55},"end":{"line":268,"column":null}},"83":{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},"84":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"85":{"start":{"line":272,"column":2},"end":{"line":276,"column":null}},"86":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"87":{"start":{"line":275,"column":4},"end":{"line":275,"column":null}},"88":{"start":{"line":277,"column":2},"end":{"line":277,"column":null}},"89":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"90":{"start":{"line":282,"column":58},"end":{"line":282,"column":null}},"91":{"start":{"line":283,"column":2},"end":{"line":288,"column":null}},"92":{"start":{"line":284,"column":4},"end":{"line":285,"column":null}},"93":{"start":{"line":287,"column":4},"end":{"line":287,"column":null}},"94":{"start":{"line":292,"column":15},"end":{"line":292,"column":null}},"95":{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},"96":{"start":{"line":294,"column":4},"end":{"line":294,"column":null}},"97":{"start":{"line":295,"column":4},"end":{"line":295,"column":null}},"98":{"start":{"line":297,"column":19},"end":{"line":297,"column":null}},"99":{"start":{"line":298,"column":17},"end":{"line":298,"column":null}},"100":{"start":{"line":299,"column":2},"end":{"line":314,"column":null}},"101":{"start":{"line":300,"column":19},"end":{"line":300,"column":null}},"102":{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},"103":{"start":{"line":302,"column":6},"end":{"line":302,"column":null}},"104":{"start":{"line":303,"column":6},"end":{"line":305,"column":null}},"105":{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},"106":{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},"107":{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},"108":{"start":{"line":309,"column":6},"end":{"line":309,"column":null}},"109":{"start":{"line":311,"column":6},"end":{"line":311,"column":null}},"110":{"start":{"line":312,"column":6},"end":{"line":312,"column":null}},"111":{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},"112":{"start":{"line":315,"column":16},"end":{"line":315,"column":null}},"113":{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},"114":{"start":{"line":316,"column":19},"end":{"line":316,"column":null}},"115":{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},"116":{"start":{"line":320,"column":2},"end":{"line":320,"column":null}}},"fnMap":{"0":{"name":"parseBriefPath","decl":{"start":{"line":48,"column":16},"end":{"line":48,"column":31}},"loc":{"start":{"line":48,"column":95},"end":{"line":64,"column":null}},"line":48},"1":{"name":"stripInnerTags","decl":{"start":{"line":121,"column":9},"end":{"line":121,"column":24}},"loc":{"start":{"line":121,"column":46},"end":{"line":132,"column":null}},"line":121},"2":{"name":"findBodyH1","decl":{"start":{"line":140,"column":9},"end":{"line":140,"column":20}},"loc":{"start":{"line":140,"column":62},"end":{"line":199,"column":null}},"line":140},"3":{"name":"postprocessBriefMarkdown","decl":{"start":{"line":201,"column":16},"end":{"line":201,"column":null}},"loc":{"start":{"line":205,"column":95},"end":{"line":237,"column":null}},"line":205},"4":{"name":"postprocessBriefFile","decl":{"start":{"line":244,"column":16},"end":{"line":244,"column":37}},"loc":{"start":{"line":250,"column":2},"end":{"line":278,"column":null}},"line":250},"5":{"name":"isMainModule","decl":{"start":{"line":280,"column":9},"end":{"line":280,"column":33}},"loc":{"start":{"line":280,"column":33},"end":{"line":289,"column":null}},"line":280},"6":{"name":"main","decl":{"start":{"line":291,"column":9},"end":{"line":291,"column":22}},"loc":{"start":{"line":291,"column":22},"end":{"line":317,"column":null}},"line":291}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"3":{"loc":{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":60,"column":2},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":60},"4":{"loc":{"start":{"line":60,"column":6},"end":{"line":60,"column":56}},"type":"binary-expr","locations":[{"start":{"line":60,"column":6},"end":{"line":60,"column":22}},{"start":{"line":60,"column":22},"end":{"line":60,"column":56}}],"line":60},"5":{"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":62},"6":{"loc":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":144},"7":{"loc":{"start":{"line":144,"column":8},"end":{"line":144,"column":40}},"type":"binary-expr","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":19}},{"start":{"line":144,"column":19},"end":{"line":144,"column":40}}],"line":144},"8":{"loc":{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":4},"end":{"line":151,"column":null}},{"start":{},"end":{}}],"line":148},"9":{"loc":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},{"start":{},"end":{}}],"line":149},"10":{"loc":{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":153,"column":4},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":153},"11":{"loc":{"start":{"line":154,"column":6},"end":{"line":157,"column":null}},"type":"binary-expr","locations":[{"start":{"line":154,"column":6},"end":{"line":154,"column":null}},{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},{"start":{"line":156,"column":6},"end":{"line":156,"column":null}},{"start":{"line":157,"column":6},"end":{"line":157,"column":null}}],"line":154},"12":{"loc":{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":162},"13":{"loc":{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":4},"end":{"line":170,"column":null}},{"start":{},"end":{}}],"line":168},"14":{"loc":{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":173},"15":{"loc":{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},"type":"if","locations":[{"start":{"line":179,"column":8},"end":{"line":187,"column":null}},{"start":{},"end":{}}],"line":179},"16":{"loc":{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},"type":"if","locations":[{"start":{"line":209,"column":2},"end":{"line":211,"column":null}},{"start":{},"end":{}}],"line":209},"17":{"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":2},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"18":{"loc":{"start":{"line":218,"column":6},"end":{"line":218,"column":46}},"type":"binary-expr","locations":[{"start":{"line":218,"column":6},"end":{"line":218,"column":18}},{"start":{"line":218,"column":18},"end":{"line":218,"column":46}}],"line":218},"19":{"loc":{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},"type":"if","locations":[{"start":{"line":251,"column":2},"end":{"line":253,"column":null}},{"start":{},"end":{}}],"line":251},"20":{"loc":{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},"type":"if","locations":[{"start":{"line":255,"column":2},"end":{"line":257,"column":null}},{"start":{},"end":{}}],"line":255},"21":{"loc":{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},"type":"if","locations":[{"start":{"line":269,"column":2},"end":{"line":271,"column":null}},{"start":{},"end":{}}],"line":269},"22":{"loc":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"type":"if","locations":[{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},{"start":{},"end":{}}],"line":282},"23":{"loc":{"start":{"line":282,"column":6},"end":{"line":282,"column":58}},"type":"binary-expr","locations":[{"start":{"line":282,"column":6},"end":{"line":282,"column":40}},{"start":{"line":282,"column":40},"end":{"line":282,"column":58}}],"line":282},"24":{"loc":{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},"type":"if","locations":[{"start":{"line":293,"column":2},"end":{"line":296,"column":null}},{"start":{},"end":{}}],"line":293},"25":{"loc":{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":301,"column":4},"end":{"line":313,"column":null}},{"start":{"line":306,"column":11},"end":{"line":313,"column":null}}],"line":301},"26":{"loc":{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":306,"column":11},"end":{"line":313,"column":null}},{"start":{"line":308,"column":11},"end":{"line":313,"column":null}}],"line":306},"27":{"loc":{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},"type":"if","locations":[{"start":{"line":308,"column":11},"end":{"line":313,"column":null}},{"start":{"line":310,"column":11},"end":{"line":313,"column":null}}],"line":308},"28":{"loc":{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":315,"column":2},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":315},"29":{"loc":{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},"type":"if","locations":[{"start":{"line":316,"column":2},"end":{"line":316,"column":null}},{"start":{},"end":{}}],"line":316},"30":{"loc":{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},"type":"if","locations":[{"start":{"line":319,"column":0},"end":{"line":321,"column":null}},{"start":{},"end":{}}],"line":319}},"s":{"0":1,"1":9,"2":9,"3":9,"4":0,"5":9,"6":9,"7":4,"8":5,"9":5,"10":1,"11":4,"12":4,"13":0,"14":4,"15":4,"16":0,"17":4,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":3,"25":3,"26":4,"27":4,"28":3,"29":17,"30":17,"31":17,"32":35,"33":35,"34":2,"35":2,"36":33,"37":5,"38":2,"39":5,"40":28,"41":11,"42":17,"43":12,"44":12,"45":5,"46":5,"47":2,"48":3,"49":3,"50":1,"51":1,"52":1,"53":2,"54":2,"55":2,"56":1,"57":1,"58":1,"59":0,"60":2,"61":0,"62":17,"63":17,"64":17,"65":2,"66":15,"67":15,"68":15,"69":3,"70":12,"71":12,"72":12,"73":12,"74":4,"75":1,"76":3,"77":3,"78":1,"79":2,"80":2,"81":0,"82":2,"83":2,"84":1,"85":1,"86":1,"87":0,"88":1,"89":1,"90":0,"91":1,"92":1,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"116":0},"f":{"0":9,"1":3,"2":17,"3":17,"4":4,"5":1,"6":0},"b":{"0":[0,9],"1":[4,5],"2":[1,4],"3":[0,4],"4":[4,4],"5":[0,4],"6":[2,33],"7":[35,17],"8":[5,28],"9":[2,3],"10":[11,17],"11":[28,22,21,18],"12":[12,5],"13":[2,3],"14":[1,2],"15":[1,1],"16":[2,15],"17":[3,12],"18":[15,14],"19":[1,3],"20":[1,2],"21":[1,1],"22":[0,1],"23":[1,1],"24":[0,0],"25":[0,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,1]},"meta":{"lastBranch":31,"lastFunction":7,"lastStatement":117,"seen":{"s:36:42:39:Infinity":0,"f:48:16:48:31":0,"s:49:16:49:Infinity":1,"s:50:19:50:Infinity":2,"b:51:2:51:Infinity:undefined:undefined:undefined:undefined":0,"s:51:2:51:Infinity":3,"s:51:17:51:Infinity":4,"s:52:12:52:Infinity":5,"b:53:2:53:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:53:Infinity":6,"s:53:10:53:Infinity":7,"s:54:15:54:Infinity":8,"b:55:2:55:Infinity:undefined:undefined:undefined:undefined":2,"s:55:2:55:Infinity":9,"s:55:29:55:Infinity":10,"s:59:19:59:Infinity":11,"b:60:2:60:Infinity:undefined:undefined:undefined:undefined":3,"s:60:2:60:Infinity":12,"b:60:6:60:22:60:22:60:56":4,"s:60:56:60:Infinity":13,"s:61:25:61:Infinity":14,"b:62:2:62:Infinity:undefined:undefined:undefined:undefined":5,"s:62:2:62:Infinity":15,"s:62:35:62:Infinity":16,"s:63:2:63:Infinity":17,"s:92:2:92:Infinity":18,"s:95:22:95:Infinity":19,"s:98:23:98:Infinity":20,"s:101:26:101:Infinity":21,"s:104:24:104:Infinity":22,"s:107:25:107:Infinity":23,"f:121:9:121:24":1,"s:126:15:126:Infinity":24,"s:127:2:130:Infinity":25,"s:128:4:128:Infinity":26,"s:129:4:129:Infinity":27,"s:131:2:131:Infinity":28,"f:140:9:140:20":2,"s:141:22:141:Infinity":29,"s:142:2:197:Infinity":30,"s:142:15:142:18":31,"s:143:15:143:Infinity":32,"b:144:4:147:Infinity:undefined:undefined:undefined:undefined":6,"s:144:4:147:Infinity":33,"b:144:8:144:19:144:19:144:40":7,"s:145:6:145:Infinity":34,"s:146:6:146:Infinity":35,"b:148:4:151:Infinity:undefined:undefined:undefined:undefined":8,"s:148:4:151:Infinity":36,"b:149:6:149:Infinity:undefined:undefined:undefined:undefined":9,"s:149:6:149:Infinity":37,"s:149:31:149:Infinity":38,"s:150:6:150:Infinity":39,"b:153:4:160:Infinity:undefined:undefined:undefined:undefined":10,"s:153:4:160:Infinity":40,"b:154:6:154:Infinity:155:6:155:Infinity:156:6:156:Infinity:157:6:157:Infinity":11,"s:159:6:159:Infinity":41,"b:162:4:165:Infinity:undefined:undefined:undefined:undefined":12,"s:162:4:165:Infinity":42,"s:163:19:163:Infinity":43,"s:164:6:164:Infinity":44,"s:167:19:167:Infinity":45,"b:168:4:170:Infinity:undefined:undefined:undefined:undefined":13,"s:168:4:170:Infinity":46,"s:169:6:169:Infinity":47,"s:172:17:172:Infinity":48,"b:173:4:193:Infinity:undefined:undefined:undefined:undefined":14,"s:173:4:193:Infinity":49,"s:175:30:175:Infinity":50,"s:176:6:189:Infinity":51,"s:176:19:176:26":52,"s:177:22:177:Infinity":53,"s:178:22:178:Infinity":54,"b:179:8:187:Infinity:undefined:undefined:undefined:undefined":15,"s:179:8:187:Infinity":55,"s:180:10:180:Infinity":56,"s:181:10:186:Infinity":57,"s:188:8:188:Infinity":58,"s:192:6:192:Infinity":59,"s:196:4:196:Infinity":60,"s:198:2:198:Infinity":61,"f:201:16:201:Infinity":3,"s:206:16:206:Infinity":62,"s:207:16:207:Infinity":63,"b:209:2:211:Infinity:undefined:undefined:undefined:undefined":16,"s:209:2:211:Infinity":64,"s:210:4:210:Infinity":65,"s:213:25:213:Infinity":66,"s:214:18:214:Infinity":67,"b:218:2:220:Infinity:undefined:undefined:undefined:undefined":17,"s:218:2:220:Infinity":68,"b:218:6:218:18:218:18:218:46":18,"s:219:4:219:Infinity":69,"s:227:17:227:Infinity":70,"s:228:16:228:Infinity":71,"s:229:19:229:Infinity":72,"s:231:2:236:Infinity":73,"f:244:16:244:37":4,"b:251:2:253:Infinity:undefined:undefined:undefined:undefined":19,"s:251:2:253:Infinity":74,"s:252:4:252:Infinity":75,"s:254:17:254:Infinity":76,"b:255:2:257:Infinity:undefined:undefined:undefined:undefined":20,"s:255:2:257:Infinity":77,"s:256:4:256:Infinity":78,"s:259:2:263:Infinity":79,"s:260:4:260:Infinity":80,"s:262:4:262:Infinity":81,"s:264:55:268:Infinity":82,"b:269:2:271:Infinity:undefined:undefined:undefined:undefined":21,"s:269:2:271:Infinity":83,"s:270:4:270:Infinity":84,"s:272:2:276:Infinity":85,"s:273:4:273:Infinity":86,"s:275:4:275:Infinity":87,"s:277:2:277:Infinity":88,"f:280:9:280:33":5,"b:282:2:282:Infinity:undefined:undefined:undefined:undefined":22,"s:282:2:282:Infinity":89,"b:282:6:282:40:282:40:282:58":23,"s:282:58:282:Infinity":90,"s:283:2:288:Infinity":91,"s:284:4:285:Infinity":92,"s:287:4:287:Infinity":93,"f:291:9:291:22":6,"s:292:15:292:Infinity":94,"b:293:2:296:Infinity:undefined:undefined:undefined:undefined":24,"s:293:2:296:Infinity":95,"s:294:4:294:Infinity":96,"s:295:4:295:Infinity":97,"s:297:19:297:Infinity":98,"s:298:17:298:Infinity":99,"s:299:2:314:Infinity":100,"s:300:19:300:Infinity":101,"b:301:4:313:Infinity:306:11:313:Infinity":25,"s:301:4:313:Infinity":102,"s:302:6:302:Infinity":103,"s:303:6:305:Infinity":104,"b:306:11:313:Infinity:308:11:313:Infinity":26,"s:306:11:313:Infinity":105,"s:307:6:307:Infinity":106,"b:308:11:313:Infinity:310:11:313:Infinity":27,"s:308:11:313:Infinity":107,"s:309:6:309:Infinity":108,"s:311:6:311:Infinity":109,"s:312:6:312:Infinity":110,"b:315:2:315:Infinity:undefined:undefined:undefined:undefined":28,"s:315:2:315:Infinity":111,"s:315:16:315:Infinity":112,"b:316:2:316:Infinity:undefined:undefined:undefined:undefined":29,"s:316:2:316:Infinity":113,"s:316:19:316:Infinity":114,"b:319:0:321:Infinity:undefined:undefined:undefined:undefined":30,"s:319:0:321:Infinity":115,"s:320:2:320:Infinity":116}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/cli.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/cli.ts","statementMap":{"0":{"start":{"line":22,"column":24},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":42,"column":null}},"2":{"start":{"line":23,"column":15},"end":{"line":23,"column":18}},"3":{"start":{"line":24,"column":16},"end":{"line":24,"column":null}},"4":{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},"5":{"start":{"line":25,"column":26},"end":{"line":25,"column":null}},"6":{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},"7":{"start":{"line":26,"column":29},"end":{"line":26,"column":null}},"8":{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},"9":{"start":{"line":27,"column":31},"end":{"line":27,"column":null}},"10":{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},"11":{"start":{"line":28,"column":32},"end":{"line":28,"column":null}},"12":{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},"13":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"14":{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},"15":{"start":{"line":30,"column":46},"end":{"line":30,"column":null}},"16":{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},"17":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"18":{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},"19":{"start":{"line":34,"column":8},"end":{"line":34,"column":null}},"20":{"start":{"line":36,"column":21},"end":{"line":36,"column":null}},"21":{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},"22":{"start":{"line":38,"column":8},"end":{"line":38,"column":null}},"23":{"start":{"line":40,"column":6},"end":{"line":40,"column":null}},"24":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"25":{"start":{"line":47,"column":14},"end":{"line":47,"column":null}},"26":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"27":{"start":{"line":49,"column":15},"end":{"line":49,"column":null}},"28":{"start":{"line":49,"column":49},"end":{"line":49,"column":null}},"29":{"start":{"line":51,"column":2},"end":{"line":57,"column":null}},"30":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"31":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"32":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"33":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"34":{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},"35":{"start":{"line":65,"column":4},"end":{"line":67,"column":null}},"36":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"37":{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},"38":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"39":{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},"40":{"start":{"line":73,"column":6},"end":{"line":73,"column":null}},"41":{"start":{"line":75,"column":18},"end":{"line":75,"column":null}},"42":{"start":{"line":76,"column":21},"end":{"line":76,"column":null}},"43":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"44":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"45":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"46":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"47":{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},"48":{"start":{"line":82,"column":6},"end":{"line":82,"column":null}},"49":{"start":{"line":83,"column":6},"end":{"line":83,"column":null}},"50":{"start":{"line":84,"column":6},"end":{"line":84,"column":null}},"51":{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},"52":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"53":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"54":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"55":{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},"56":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"57":{"start":{"line":93,"column":4},"end":{"line":93,"column":null}},"58":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"59":{"start":{"line":96,"column":18},"end":{"line":96,"column":null}},"60":{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},"61":{"start":{"line":98,"column":6},"end":{"line":100,"column":null}},"62":{"start":{"line":101,"column":6},"end":{"line":101,"column":null}},"63":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"64":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"65":{"start":{"line":106,"column":4},"end":{"line":110,"column":null}},"66":{"start":{"line":111,"column":4},"end":{"line":111,"column":null}},"67":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"68":{"start":{"line":116,"column":2},"end":{"line":122,"column":null}},"69":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"70":{"start":{"line":119,"column":4},"end":{"line":119,"column":null}},"71":{"start":{"line":120,"column":4},"end":{"line":120,"column":null}},"72":{"start":{"line":121,"column":4},"end":{"line":121,"column":null}},"73":{"start":{"line":125,"column":2},"end":{"line":131,"column":null}},"74":{"start":{"line":126,"column":4},"end":{"line":126,"column":null}},"75":{"start":{"line":128,"column":4},"end":{"line":128,"column":null}},"76":{"start":{"line":129,"column":4},"end":{"line":129,"column":null}},"77":{"start":{"line":130,"column":4},"end":{"line":130,"column":null}},"78":{"start":{"line":133,"column":37},"end":{"line":133,"column":null}},"79":{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},"80":{"start":{"line":134,"column":14},"end":{"line":134,"column":null}},"81":{"start":{"line":135,"column":17},"end":{"line":135,"column":null}},"82":{"start":{"line":136,"column":15},"end":{"line":136,"column":null}},"83":{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},"84":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"85":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"86":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},"87":{"start":{"line":143,"column":33},"end":{"line":143,"column":null}},"88":{"start":{"line":144,"column":21},"end":{"line":144,"column":null}},"89":{"start":{"line":145,"column":2},"end":{"line":145,"column":null}},"90":{"start":{"line":147,"column":2},"end":{"line":150,"column":null}},"91":{"start":{"line":148,"column":50},"end":{"line":148,"column":69}},"92":{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},"93":{"start":{"line":153,"column":25},"end":{"line":153,"column":null}},"94":{"start":{"line":153,"column":56},"end":{"line":153,"column":64}},"95":{"start":{"line":154,"column":15},"end":{"line":154,"column":null}},"96":{"start":{"line":155,"column":19},"end":{"line":155,"column":null}},"97":{"start":{"line":156,"column":4},"end":{"line":156,"column":null}},"98":{"start":{"line":157,"column":4},"end":{"line":159,"column":null}}},"fnMap":{"0":{"name":"parseArgs","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":26}},"loc":{"start":{"line":21,"column":51},"end":{"line":44,"column":null}},"line":21},"1":{"name":"runMain","decl":{"start":{"line":46,"column":16},"end":{"line":46,"column":24}},"loc":{"start":{"line":46,"column":62},"end":{"line":161,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":49,"column":18},"end":{"line":49,"column":28}},"loc":{"start":{"line":49,"column":49},"end":{"line":49,"column":null}},"line":49},"3":{"name":"(anonymous_3)","decl":{"start":{"line":148,"column":36},"end":{"line":148,"column":44}},"loc":{"start":{"line":148,"column":50},"end":{"line":148,"column":69}},"line":148},"4":{"name":"(anonymous_4)","decl":{"start":{"line":153,"column":45},"end":{"line":153,"column":50}},"loc":{"start":{"line":153,"column":56},"end":{"line":153,"column":64}},"line":153}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":41,"column":null}},{"start":{"line":26,"column":9},"end":{"line":41,"column":null}}],"line":25},"1":{"loc":{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":9},"end":{"line":41,"column":null}},{"start":{"line":27,"column":9},"end":{"line":41,"column":null}}],"line":26},"2":{"loc":{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":9},"end":{"line":41,"column":null}},{"start":{"line":28,"column":9},"end":{"line":41,"column":null}}],"line":27},"3":{"loc":{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":9},"end":{"line":41,"column":null}},{"start":{"line":29,"column":9},"end":{"line":41,"column":null}}],"line":28},"4":{"loc":{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":9},"end":{"line":41,"column":null}},{"start":{"line":30,"column":9},"end":{"line":41,"column":null}}],"line":29},"5":{"loc":{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":9},"end":{"line":41,"column":null}},{"start":{"line":31,"column":9},"end":{"line":41,"column":null}}],"line":30},"6":{"loc":{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":9},"end":{"line":41,"column":null}},{"start":{},"end":{}}],"line":31},"7":{"loc":{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":6},"end":{"line":35,"column":null}},{"start":{},"end":{}}],"line":33},"8":{"loc":{"start":{"line":33,"column":10},"end":{"line":33,"column":40}},"type":"binary-expr","locations":[{"start":{"line":33,"column":10},"end":{"line":33,"column":18}},{"start":{"line":33,"column":18},"end":{"line":33,"column":40}}],"line":33},"9":{"loc":{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":6},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"10":{"loc":{"start":{"line":37,"column":10},"end":{"line":37,"column":82}},"type":"binary-expr","locations":[{"start":{"line":37,"column":10},"end":{"line":37,"column":42}},{"start":{"line":37,"column":42},"end":{"line":37,"column":70}},{"start":{"line":37,"column":70},"end":{"line":37,"column":82}}],"line":37},"11":{"loc":{"start":{"line":46,"column":40},"end":{"line":46,"column":62}},"type":"default-arg","locations":[{"start":{"line":46,"column":52},"end":{"line":46,"column":62}}],"line":46},"12":{"loc":{"start":{"line":47,"column":14},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":14},"end":{"line":47,"column":27}},{"start":{"line":47,"column":27},"end":{"line":47,"column":null}}],"line":47},"13":{"loc":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":14},"end":{"line":48,"column":27}},{"start":{"line":48,"column":27},"end":{"line":48,"column":null}}],"line":48},"14":{"loc":{"start":{"line":49,"column":15},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":15},"end":{"line":49,"column":28}},{"start":{"line":49,"column":18},"end":{"line":49,"column":null}}],"line":49},"15":{"loc":{"start":{"line":54,"column":40},"end":{"line":54,"column":74}},"type":"cond-expr","locations":[{"start":{"line":54,"column":61},"end":{"line":54,"column":73}},{"start":{"line":54,"column":73},"end":{"line":54,"column":74}}],"line":54},"16":{"loc":{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":113,"column":null}},{"start":{"line":86,"column":9},"end":{"line":113,"column":null}}],"line":64},"17":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":28}},"type":"binary-expr","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":19}},{"start":{"line":64,"column":19},"end":{"line":64,"column":28}}],"line":64},"18":{"loc":{"start":{"line":65,"column":17},"end":{"line":67,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":null}},{"start":{"line":67,"column":8},"end":{"line":67,"column":null}}],"line":65},"19":{"loc":{"start":{"line":68,"column":16},"end":{"line":68,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":43},"end":{"line":68,"column":53}},{"start":{"line":68,"column":53},"end":{"line":68,"column":null}}],"line":68},"20":{"loc":{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":4},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":70},"21":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":69},"end":{"line":77,"column":98}},{"start":{"line":77,"column":98},"end":{"line":77,"column":null}}],"line":77},"22":{"loc":{"start":{"line":77,"column":21},"end":{"line":77,"column":69}},"type":"binary-expr","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":38}},{"start":{"line":77,"column":38},"end":{"line":77,"column":69}}],"line":77},"23":{"loc":{"start":{"line":77,"column":69},"end":{"line":77,"column":98}},"type":"binary-expr","locations":[{"start":{"line":77,"column":69},"end":{"line":77,"column":92}},{"start":{"line":77,"column":92},"end":{"line":77,"column":98}}],"line":77},"24":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":70},"end":{"line":78,"column":99}},{"start":{"line":78,"column":99},"end":{"line":78,"column":null}}],"line":78},"25":{"loc":{"start":{"line":78,"column":22},"end":{"line":78,"column":70}},"type":"binary-expr","locations":[{"start":{"line":78,"column":22},"end":{"line":78,"column":39}},{"start":{"line":78,"column":39},"end":{"line":78,"column":70}}],"line":78},"26":{"loc":{"start":{"line":78,"column":70},"end":{"line":78,"column":99}},"type":"binary-expr","locations":[{"start":{"line":78,"column":70},"end":{"line":78,"column":93}},{"start":{"line":78,"column":93},"end":{"line":78,"column":99}}],"line":78},"27":{"loc":{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":81},"28":{"loc":{"start":{"line":81,"column":8},"end":{"line":81,"column":83}},"type":"binary-expr","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":51}},{"start":{"line":81,"column":51},"end":{"line":81,"column":83}}],"line":81},"29":{"loc":{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":86,"column":9},"end":{"line":113,"column":null}},{"start":{"line":105,"column":9},"end":{"line":113,"column":null}}],"line":86},"30":{"loc":{"start":{"line":86,"column":13},"end":{"line":86,"column":38}},"type":"binary-expr","locations":[{"start":{"line":86,"column":13},"end":{"line":86,"column":26}},{"start":{"line":86,"column":26},"end":{"line":86,"column":38}}],"line":86},"31":{"loc":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":87},"32":{"loc":{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":97},"33":{"loc":{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":134,"column":null}},{"start":{},"end":{}}],"line":134},"34":{"loc":{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":2},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":138},"35":{"loc":{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":143,"column":2},"end":{"line":143,"column":null}},{"start":{},"end":{}}],"line":143},"36":{"loc":{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},"type":"if","locations":[{"start":{"line":152,"column":2},"end":{"line":160,"column":null}},{"start":{},"end":{}}],"line":152},"37":{"loc":{"start":{"line":152,"column":6},"end":{"line":152,"column":60}},"type":"binary-expr","locations":[{"start":{"line":152,"column":6},"end":{"line":152,"column":32}},{"start":{"line":152,"column":32},"end":{"line":152,"column":60}}],"line":152}},"s":{"0":27,"1":27,"2":27,"3":45,"4":45,"5":14,"6":31,"7":14,"8":17,"9":4,"10":13,"11":4,"12":9,"13":2,"14":7,"15":1,"16":6,"17":6,"18":6,"19":1,"20":5,"21":5,"22":3,"23":2,"24":23,"25":17,"26":17,"27":17,"28":0,"29":17,"30":17,"31":1,"32":1,"33":1,"34":16,"35":13,"36":13,"37":13,"38":1,"39":1,"40":1,"41":12,"42":12,"43":12,"44":13,"45":13,"46":13,"47":13,"48":1,"49":1,"50":1,"51":3,"52":2,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":0,"65":1,"66":1,"67":1,"68":11,"69":11,"70":1,"71":1,"72":1,"73":10,"74":10,"75":1,"76":1,"77":1,"78":9,"79":9,"80":7,"81":9,"82":9,"83":9,"84":1,"85":1,"86":8,"87":7,"88":8,"89":8,"90":8,"91":16,"92":8,"93":5,"94":10,"95":5,"96":5,"97":5,"98":5},"f":{"0":27,"1":17,"2":0,"3":16,"4":10},"b":{"0":[14,31],"1":[14,17],"2":[4,13],"3":[4,9],"4":[2,7],"5":[1,6],"6":[6,0],"7":[1,5],"8":[6,5],"9":[3,2],"10":[5,4,4],"11":[17],"12":[17,0],"13":[17,0],"14":[17,0],"15":[1,0],"16":[13,3],"17":[16,13],"18":[13,0],"19":[13,0],"20":[1,12],"21":[12,0],"22":[12,12],"23":[12,0],"24":[11,1],"25":[13,12],"26":[11,0],"27":[1,12],"28":[13,11],"29":[2,1],"30":[3,2],"31":[1,1],"32":[1,0],"33":[7,2],"34":[1,8],"35":[7,1],"36":[5,3],"37":[8,7]},"meta":{"lastBranch":38,"lastFunction":5,"lastStatement":99,"seen":{"f:21:16:21:26":0,"s:22:24:22:Infinity":0,"s:23:2:42:Infinity":1,"s:23:15:23:18":2,"s:24:16:24:Infinity":3,"b:25:4:41:Infinity:26:9:41:Infinity":0,"s:25:4:41:Infinity":4,"s:25:26:25:Infinity":5,"b:26:9:41:Infinity:27:9:41:Infinity":1,"s:26:9:41:Infinity":6,"s:26:29:26:Infinity":7,"b:27:9:41:Infinity:28:9:41:Infinity":2,"s:27:9:41:Infinity":8,"s:27:31:27:Infinity":9,"b:28:9:41:Infinity:29:9:41:Infinity":3,"s:28:9:41:Infinity":10,"s:28:32:28:Infinity":11,"b:29:9:41:Infinity:30:9:41:Infinity":4,"s:29:9:41:Infinity":12,"s:29:34:29:Infinity":13,"b:30:9:41:Infinity:31:9:41:Infinity":5,"s:30:9:41:Infinity":14,"s:30:46:30:Infinity":15,"b:31:9:41:Infinity:undefined:undefined:undefined:undefined":6,"s:31:9:41:Infinity":16,"s:32:18:32:Infinity":17,"b:33:6:35:Infinity:undefined:undefined:undefined:undefined":7,"s:33:6:35:Infinity":18,"b:33:10:33:18:33:18:33:40":8,"s:34:8:34:Infinity":19,"s:36:21:36:Infinity":20,"b:37:6:39:Infinity:undefined:undefined:undefined:undefined":9,"s:37:6:39:Infinity":21,"b:37:10:37:42:37:42:37:70:37:70:37:82":10,"s:38:8:38:Infinity":22,"s:40:6:40:Infinity":23,"s:43:2:43:Infinity":24,"f:46:16:46:24":1,"b:46:52:46:62":11,"s:47:14:47:Infinity":25,"b:47:14:47:27:47:27:47:Infinity":12,"s:48:14:48:Infinity":26,"b:48:14:48:27:48:27:48:Infinity":13,"s:49:15:49:Infinity":27,"b:49:15:49:28:49:18:49:Infinity":14,"f:49:18:49:28":2,"s:49:49:49:Infinity":28,"s:51:2:57:Infinity":29,"s:52:4:52:Infinity":30,"s:54:4:54:Infinity":31,"b:54:61:54:73:54:73:54:74":15,"s:55:4:55:Infinity":32,"s:56:4:56:Infinity":33,"b:64:2:113:Infinity:86:9:113:Infinity":16,"s:64:2:113:Infinity":34,"b:64:6:64:19:64:19:64:28":17,"s:65:4:67:Infinity":35,"b:66:8:66:Infinity:67:8:67:Infinity":18,"s:68:4:68:Infinity":36,"b:68:43:68:53:68:53:68:Infinity":19,"b:70:4:74:Infinity:undefined:undefined:undefined:undefined":20,"s:70:4:74:Infinity":37,"s:71:6:71:Infinity":38,"s:72:6:72:Infinity":39,"s:73:6:73:Infinity":40,"s:75:18:75:Infinity":41,"s:76:21:76:Infinity":42,"s:77:21:77:Infinity":43,"b:77:69:77:98:77:98:77:Infinity":21,"b:77:21:77:38:77:38:77:69":22,"b:77:69:77:92:77:92:77:98":23,"s:78:22:78:Infinity":44,"b:78:70:78:99:78:99:78:Infinity":24,"b:78:22:78:39:78:39:78:70":25,"b:78:70:78:93:78:93:78:99":26,"s:79:4:79:Infinity":45,"s:80:4:80:Infinity":46,"b:81:4:85:Infinity:undefined:undefined:undefined:undefined":27,"s:81:4:85:Infinity":47,"b:81:8:81:51:81:51:81:83":28,"s:82:6:82:Infinity":48,"s:83:6:83:Infinity":49,"s:84:6:84:Infinity":50,"b:86:9:113:Infinity:105:9:113:Infinity":29,"s:86:9:113:Infinity":51,"b:86:13:86:26:86:26:86:38":30,"b:87:4:91:Infinity:undefined:undefined:undefined:undefined":31,"s:87:4:91:Infinity":52,"s:88:6:88:Infinity":53,"s:89:6:89:Infinity":54,"s:90:6:90:Infinity":55,"s:92:4:92:Infinity":56,"s:93:4:93:Infinity":57,"s:94:4:94:Infinity":58,"s:96:18:96:Infinity":59,"b:97:4:103:Infinity:undefined:undefined:undefined:undefined":32,"s:97:4:103:Infinity":60,"s:98:6:100:Infinity":61,"s:101:6:101:Infinity":62,"s:102:6:102:Infinity":63,"s:104:4:104:Infinity":64,"s:106:4:110:Infinity":65,"s:111:4:111:Infinity":66,"s:112:4:112:Infinity":67,"s:116:2:122:Infinity":68,"s:117:4:117:Infinity":69,"s:119:4:119:Infinity":70,"s:120:4:120:Infinity":71,"s:121:4:121:Infinity":72,"s:125:2:131:Infinity":73,"s:126:4:126:Infinity":74,"s:128:4:128:Infinity":75,"s:129:4:129:Infinity":76,"s:130:4:130:Infinity":77,"s:133:37:133:Infinity":78,"b:134:2:134:Infinity:undefined:undefined:undefined:undefined":33,"s:134:2:134:Infinity":79,"s:134:14:134:Infinity":80,"s:135:17:135:Infinity":81,"s:136:15:136:Infinity":82,"b:138:2:141:Infinity:undefined:undefined:undefined:undefined":34,"s:138:2:141:Infinity":83,"s:139:4:139:Infinity":84,"s:140:4:140:Infinity":85,"b:143:2:143:Infinity:undefined:undefined:undefined:undefined":35,"s:143:2:143:Infinity":86,"s:143:33:143:Infinity":87,"s:144:21:144:Infinity":88,"s:145:2:145:Infinity":89,"s:147:2:150:Infinity":90,"f:148:36:148:44":3,"s:148:50:148:69":91,"b:152:2:160:Infinity:undefined:undefined:undefined:undefined":36,"s:152:2:160:Infinity":92,"b:152:6:152:32:152:32:152:60":37,"s:153:25:153:Infinity":93,"f:153:45:153:50":4,"s:153:56:153:64":94,"s:154:15:154:Infinity":95,"s:155:19:155:Infinity":96,"s:156:4:156:Infinity":97,"s:157:4:159:Infinity":98}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rir-followups-client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rir-followups-client.ts","statementMap":{"0":{"start":{"line":119,"column":46},"end":{"line":119,"column":null}},"1":{"start":{"line":126,"column":34},"end":{"line":126,"column":null}},"2":{"start":{"line":129,"column":36},"end":{"line":129,"column":null}},"3":{"start":{"line":132,"column":36},"end":{"line":132,"column":null}},"4":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"5":{"start":{"line":161,"column":14},"end":{"line":161,"column":null}},"6":{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},"7":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"8":{"start":{"line":165,"column":15},"end":{"line":165,"column":null}},"9":{"start":{"line":166,"column":16},"end":{"line":166,"column":null}},"10":{"start":{"line":167,"column":14},"end":{"line":167,"column":null}},"11":{"start":{"line":169,"column":23},"end":{"line":169,"column":null}},"12":{"start":{"line":170,"column":8},"end":{"line":170,"column":null}},"13":{"start":{"line":172,"column":30},"end":{"line":172,"column":null}},"14":{"start":{"line":173,"column":22},"end":{"line":173,"column":null}},"15":{"start":{"line":175,"column":8},"end":{"line":175,"column":null}},"16":{"start":{"line":175,"column":37},"end":{"line":175,"column":null}},"17":{"start":{"line":176,"column":2},"end":{"line":176,"column":null}},"18":{"start":{"line":204,"column":14},"end":{"line":204,"column":null}},"19":{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},"20":{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},"21":{"start":{"line":211,"column":6},"end":{"line":211,"column":null}},"22":{"start":{"line":213,"column":4},"end":{"line":213,"column":null}},"23":{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},"24":{"start":{"line":217,"column":21},"end":{"line":217,"column":null}},"25":{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},"26":{"start":{"line":219,"column":6},"end":{"line":219,"column":null}},"27":{"start":{"line":223,"column":2},"end":{"line":223,"column":null}},"28":{"start":{"line":238,"column":14},"end":{"line":238,"column":null}},"29":{"start":{"line":239,"column":19},"end":{"line":239,"column":null}},"30":{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},"31":{"start":{"line":241,"column":4},"end":{"line":241,"column":null}},"32":{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},"33":{"start":{"line":244,"column":4},"end":{"line":244,"column":null}},"34":{"start":{"line":246,"column":17},"end":{"line":246,"column":null}},"35":{"start":{"line":247,"column":2},"end":{"line":247,"column":null}},"36":{"start":{"line":266,"column":14},"end":{"line":266,"column":null}},"37":{"start":{"line":267,"column":37},"end":{"line":267,"column":null}},"38":{"start":{"line":269,"column":2},"end":{"line":286,"column":null}},"39":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"40":{"start":{"line":270,"column":36},"end":{"line":270,"column":null}},"41":{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},"42":{"start":{"line":271,"column":38},"end":{"line":271,"column":null}},"43":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"44":{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},"45":{"start":{"line":275,"column":6},"end":{"line":284,"column":null}},"46":{"start":{"line":288,"column":2},"end":{"line":288,"column":null}},"47":{"start":{"line":288,"column":31},"end":{"line":288,"column":62}},"48":{"start":{"line":309,"column":14},"end":{"line":309,"column":null}},"49":{"start":{"line":312,"column":4},"end":{"line":312,"column":null}},"50":{"start":{"line":314,"column":4},"end":{"line":314,"column":null}},"51":{"start":{"line":316,"column":15},"end":{"line":333,"column":null}},"52":{"start":{"line":317,"column":19},"end":{"line":317,"column":null}},"53":{"start":{"line":318,"column":20},"end":{"line":320,"column":null}},"54":{"start":{"line":321,"column":23},"end":{"line":321,"column":null}},"55":{"start":{"line":322,"column":24},"end":{"line":327,"column":null}},"56":{"start":{"line":328,"column":24},"end":{"line":328,"column":null}},"57":{"start":{"line":329,"column":22},"end":{"line":331,"column":null}},"58":{"start":{"line":332,"column":4},"end":{"line":332,"column":null}},"59":{"start":{"line":335,"column":2},"end":{"line":335,"column":null}},"60":{"start":{"line":358,"column":16},"end":{"line":358,"column":null}},"61":{"start":{"line":359,"column":16},"end":{"line":367,"column":null}},"62":{"start":{"line":369,"column":22},"end":{"line":369,"column":null}},"63":{"start":{"line":370,"column":20},"end":{"line":370,"column":null}},"64":{"start":{"line":371,"column":19},"end":{"line":371,"column":null}},"65":{"start":{"line":372,"column":17},"end":{"line":372,"column":null}},"66":{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},"67":{"start":{"line":375,"column":4},"end":{"line":378,"column":null}},"68":{"start":{"line":382,"column":2},"end":{"line":382,"column":null}},"69":{"start":{"line":400,"column":13},"end":{"line":400,"column":null}},"70":{"start":{"line":401,"column":2},"end":{"line":403,"column":null}},"71":{"start":{"line":401,"column":25},"end":{"line":402,"column":null}},"72":{"start":{"line":402,"column":37},"end":{"line":402,"column":59}},"73":{"start":{"line":416,"column":2},"end":{"line":416,"column":null}},"74":{"start":{"line":416,"column":31},"end":{"line":416,"column":63}},"75":{"start":{"line":429,"column":46},"end":{"line":434,"column":null}},"76":{"start":{"line":435,"column":20},"end":{"line":435,"column":null}},"77":{"start":{"line":436,"column":2},"end":{"line":436,"column":null}},"78":{"start":{"line":436,"column":31},"end":{"line":436,"column":85}},"79":{"start":{"line":450,"column":27},"end":{"line":450,"column":null}},"80":{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},"81":{"start":{"line":453,"column":4},"end":{"line":453,"column":null}},"82":{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},"83":{"start":{"line":456,"column":4},"end":{"line":456,"column":null}},"84":{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},"85":{"start":{"line":459,"column":4},"end":{"line":459,"column":null}},"86":{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},"87":{"start":{"line":462,"column":4},"end":{"line":462,"column":null}},"88":{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},"89":{"start":{"line":465,"column":4},"end":{"line":465,"column":null}},"90":{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},"91":{"start":{"line":468,"column":4},"end":{"line":468,"column":null}},"92":{"start":{"line":470,"column":45},"end":{"line":470,"column":null}},"93":{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},"94":{"start":{"line":472,"column":4},"end":{"line":472,"column":null}},"95":{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},"96":{"start":{"line":475,"column":4},"end":{"line":475,"column":null}},"97":{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},"98":{"start":{"line":476,"column":66},"end":{"line":476,"column":88}},"99":{"start":{"line":477,"column":4},"end":{"line":477,"column":null}},"100":{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},"101":{"start":{"line":484,"column":4},"end":{"line":484,"column":null}},"102":{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},"103":{"start":{"line":490,"column":4},"end":{"line":490,"column":null}},"104":{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},"105":{"start":{"line":494,"column":4},"end":{"line":494,"column":null}},"106":{"start":{"line":497,"column":2},"end":{"line":497,"column":null}},"107":{"start":{"line":508,"column":19},"end":{"line":508,"column":null}},"108":{"start":{"line":509,"column":2},"end":{"line":514,"column":null}},"109":{"start":{"line":510,"column":19},"end":{"line":510,"column":null}},"110":{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},"111":{"start":{"line":512,"column":6},"end":{"line":512,"column":null}},"112":{"start":{"line":515,"column":2},"end":{"line":515,"column":null}},"113":{"start":{"line":533,"column":14},"end":{"line":533,"column":null}},"114":{"start":{"line":534,"column":2},"end":{"line":534,"column":null}},"115":{"start":{"line":552,"column":4},"end":{"line":556,"column":null}},"116":{"start":{"line":557,"column":2},"end":{"line":557,"column":null}}},"fnMap":{"0":{"name":"calculateSkrivelseDeadline","decl":{"start":{"line":156,"column":16},"end":{"line":156,"column":null}},"loc":{"start":{"line":159,"column":10},"end":{"line":177,"column":null}},"line":159},"1":{"name":"(anonymous_1)","decl":{"start":{"line":175,"column":8},"end":{"line":175,"column":15}},"loc":{"start":{"line":175,"column":37},"end":{"line":175,"column":null}},"line":175},"2":{"name":"deriveResponseStatus","decl":{"start":{"line":200,"column":16},"end":{"line":200,"column":null}},"loc":{"start":{"line":203,"column":21},"end":{"line":224,"column":null}},"line":203},"3":{"name":"daysOverdue","decl":{"start":{"line":234,"column":16},"end":{"line":234,"column":null}},"loc":{"start":{"line":237,"column":10},"end":{"line":248,"column":null}},"line":237},"4":{"name":"detectOverdueAlerts","decl":{"start":{"line":262,"column":16},"end":{"line":262,"column":null}},"loc":{"start":{"line":265,"column":31},"end":{"line":289,"column":null}},"line":265},"5":{"name":"(anonymous_5)","decl":{"start":{"line":288,"column":16},"end":{"line":288,"column":22}},"loc":{"start":{"line":288,"column":31},"end":{"line":288,"column":62}},"line":288},"6":{"name":"renderRirFollowUpTable","decl":{"start":{"line":305,"column":16},"end":{"line":305,"column":null}},"loc":{"start":{"line":308,"column":10},"end":{"line":336,"column":null}},"line":308},"7":{"name":"(anonymous_7)","decl":{"start":{"line":316,"column":23},"end":{"line":316,"column":28}},"loc":{"start":{"line":316,"column":34},"end":{"line":333,"column":3}},"line":316},"8":{"name":"injectRirTableIntoDocument","decl":{"start":{"line":353,"column":16},"end":{"line":353,"column":null}},"loc":{"start":{"line":357,"column":10},"end":{"line":383,"column":null}},"line":357},"9":{"name":"filterByCommittee","decl":{"start":{"line":396,"column":16},"end":{"line":396,"column":null}},"loc":{"start":{"line":399,"column":32},"end":{"line":404,"column":null}},"line":399},"10":{"name":"(anonymous_10)","decl":{"start":{"line":401,"column":17},"end":{"line":401,"column":25}},"loc":{"start":{"line":401,"column":25},"end":{"line":402,"column":null}},"line":401},"11":{"name":"(anonymous_11)","decl":{"start":{"line":402,"column":25},"end":{"line":402,"column":31}},"loc":{"start":{"line":402,"column":37},"end":{"line":402,"column":59}},"line":402},"12":{"name":"filterByStatus","decl":{"start":{"line":412,"column":16},"end":{"line":412,"column":null}},"loc":{"start":{"line":415,"column":32},"end":{"line":417,"column":null}},"line":415},"13":{"name":"(anonymous_13)","decl":{"start":{"line":416,"column":17},"end":{"line":416,"column":25}},"loc":{"start":{"line":416,"column":31},"end":{"line":416,"column":63}},"line":416},"14":{"name":"filterByMinRiskLevel","decl":{"start":{"line":425,"column":16},"end":{"line":425,"column":null}},"loc":{"start":{"line":428,"column":32},"end":{"line":437,"column":null}},"line":428},"15":{"name":"(anonymous_15)","decl":{"start":{"line":436,"column":17},"end":{"line":436,"column":25}},"loc":{"start":{"line":436,"column":31},"end":{"line":436,"column":85}},"line":436},"16":{"name":"validateRirRecord","decl":{"start":{"line":449,"column":16},"end":{"line":449,"column":34}},"loc":{"start":{"line":449,"column":80},"end":{"line":498,"column":null}},"line":449},"17":{"name":"(anonymous_17)","decl":{"start":{"line":476,"column":52},"end":{"line":476,"column":59}},"loc":{"start":{"line":476,"column":66},"end":{"line":476,"column":88}},"line":476},"18":{"name":"validateRirDataset","decl":{"start":{"line":505,"column":16},"end":{"line":505,"column":null}},"loc":{"start":{"line":507,"column":34},"end":{"line":516,"column":null}},"line":507},"19":{"name":"loadRirDataset","decl":{"start":{"line":529,"column":16},"end":{"line":529,"column":null}},"loc":{"start":{"line":532,"column":23},"end":{"line":535,"column":null}},"line":532},"20":{"name":"saveRirDataset","decl":{"start":{"line":545,"column":16},"end":{"line":545,"column":null}},"loc":{"start":{"line":550,"column":8},"end":{"line":558,"column":null}},"line":550}},"branchMap":{"0":{"loc":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"type":"default-arg","locations":[{"start":{"line":158,"column":39},"end":{"line":158,"column":null}}],"line":158},"1":{"loc":{"start":{"line":160,"column":17},"end":{"line":160,"column":null}},"type":"binary-expr","locations":[{"start":{"line":160,"column":17},"end":{"line":160,"column":43}},{"start":{"line":160,"column":43},"end":{"line":160,"column":null}}],"line":160},"2":{"loc":{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},"type":"if","locations":[{"start":{"line":162,"column":2},"end":{"line":164,"column":null}},{"start":{},"end":{}}],"line":162},"3":{"loc":{"start":{"line":202,"column":2},"end":{"line":202,"column":null}},"type":"default-arg","locations":[{"start":{"line":202,"column":24},"end":{"line":202,"column":null}}],"line":202},"4":{"loc":{"start":{"line":204,"column":14},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":204,"column":41},"end":{"line":204,"column":73}},{"start":{"line":204,"column":73},"end":{"line":204,"column":null}}],"line":204},"5":{"loc":{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":206},"6":{"loc":{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":212,"column":null}},{"start":{},"end":{}}],"line":207},"7":{"loc":{"start":{"line":208,"column":6},"end":{"line":209,"column":null}},"type":"binary-expr","locations":[{"start":{"line":208,"column":6},"end":{"line":208,"column":null}},{"start":{"line":209,"column":7},"end":{"line":209,"column":58}},{"start":{"line":209,"column":58},"end":{"line":209,"column":null}}],"line":208},"8":{"loc":{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":216},"9":{"loc":{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},"type":"if","locations":[{"start":{"line":218,"column":4},"end":{"line":220,"column":null}},{"start":{},"end":{}}],"line":218},"10":{"loc":{"start":{"line":236,"column":2},"end":{"line":236,"column":null}},"type":"default-arg","locations":[{"start":{"line":236,"column":24},"end":{"line":236,"column":null}}],"line":236},"11":{"loc":{"start":{"line":238,"column":14},"end":{"line":238,"column":null}},"type":"cond-expr","locations":[{"start":{"line":238,"column":41},"end":{"line":238,"column":73}},{"start":{"line":238,"column":73},"end":{"line":238,"column":null}}],"line":238},"12":{"loc":{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},"type":"if","locations":[{"start":{"line":240,"column":2},"end":{"line":242,"column":null}},{"start":{},"end":{}}],"line":240},"13":{"loc":{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},"type":"if","locations":[{"start":{"line":243,"column":2},"end":{"line":245,"column":null}},{"start":{},"end":{}}],"line":243},"14":{"loc":{"start":{"line":247,"column":9},"end":{"line":247,"column":null}},"type":"cond-expr","locations":[{"start":{"line":247,"column":22},"end":{"line":247,"column":67}},{"start":{"line":247,"column":67},"end":{"line":247,"column":null}}],"line":247},"15":{"loc":{"start":{"line":264,"column":2},"end":{"line":264,"column":null}},"type":"default-arg","locations":[{"start":{"line":264,"column":24},"end":{"line":264,"column":null}}],"line":264},"16":{"loc":{"start":{"line":266,"column":14},"end":{"line":266,"column":null}},"type":"cond-expr","locations":[{"start":{"line":266,"column":41},"end":{"line":266,"column":73}},{"start":{"line":266,"column":73},"end":{"line":266,"column":null}}],"line":266},"17":{"loc":{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":null}},{"start":{},"end":{}}],"line":270},"18":{"loc":{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},"type":"if","locations":[{"start":{"line":271,"column":4},"end":{"line":271,"column":null}},{"start":{},"end":{}}],"line":271},"19":{"loc":{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},"type":"if","locations":[{"start":{"line":274,"column":4},"end":{"line":285,"column":null}},{"start":{},"end":{}}],"line":274},"20":{"loc":{"start":{"line":282,"column":20},"end":{"line":282,"column":null}},"type":"binary-expr","locations":[{"start":{"line":282,"column":20},"end":{"line":282,"column":41}},{"start":{"line":282,"column":41},"end":{"line":282,"column":null}}],"line":282},"21":{"loc":{"start":{"line":307,"column":2},"end":{"line":307,"column":null}},"type":"default-arg","locations":[{"start":{"line":307,"column":24},"end":{"line":307,"column":null}}],"line":307},"22":{"loc":{"start":{"line":309,"column":14},"end":{"line":309,"column":null}},"type":"cond-expr","locations":[{"start":{"line":309,"column":41},"end":{"line":309,"column":73}},{"start":{"line":309,"column":73},"end":{"line":309,"column":null}}],"line":309},"23":{"loc":{"start":{"line":318,"column":20},"end":{"line":320,"column":null}},"type":"cond-expr","locations":[{"start":{"line":319,"column":8},"end":{"line":319,"column":null}},{"start":{"line":320,"column":8},"end":{"line":320,"column":null}}],"line":318},"24":{"loc":{"start":{"line":318,"column":20},"end":{"line":318,"column":null}},"type":"binary-expr","locations":[{"start":{"line":318,"column":20},"end":{"line":318,"column":44}},{"start":{"line":318,"column":44},"end":{"line":318,"column":null}}],"line":318},"25":{"loc":{"start":{"line":321,"column":23},"end":{"line":321,"column":null}},"type":"cond-expr","locations":[{"start":{"line":321,"column":37},"end":{"line":321,"column":55}},{"start":{"line":321,"column":55},"end":{"line":321,"column":null}}],"line":321},"26":{"loc":{"start":{"line":328,"column":24},"end":{"line":328,"column":null}},"type":"binary-expr","locations":[{"start":{"line":328,"column":24},"end":{"line":328,"column":48}},{"start":{"line":328,"column":48},"end":{"line":328,"column":null}}],"line":328},"27":{"loc":{"start":{"line":329,"column":22},"end":{"line":331,"column":null}},"type":"cond-expr","locations":[{"start":{"line":330,"column":8},"end":{"line":330,"column":null}},{"start":{"line":331,"column":8},"end":{"line":331,"column":null}}],"line":329},"28":{"loc":{"start":{"line":356,"column":2},"end":{"line":356,"column":null}},"type":"default-arg","locations":[{"start":{"line":356,"column":24},"end":{"line":356,"column":null}}],"line":356},"29":{"loc":{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},"type":"if","locations":[{"start":{"line":374,"column":2},"end":{"line":380,"column":null}},{"start":{},"end":{}}],"line":374},"30":{"loc":{"start":{"line":374,"column":6},"end":{"line":374,"column":61}},"type":"binary-expr","locations":[{"start":{"line":374,"column":6},"end":{"line":374,"column":25}},{"start":{"line":374,"column":25},"end":{"line":374,"column":42}},{"start":{"line":374,"column":42},"end":{"line":374,"column":61}}],"line":374},"31":{"loc":{"start":{"line":402,"column":5},"end":{"line":402,"column":23}},"type":"binary-expr","locations":[{"start":{"line":402,"column":5},"end":{"line":402,"column":21}},{"start":{"line":402,"column":21},"end":{"line":402,"column":23}}],"line":402},"32":{"loc":{"start":{"line":436,"column":37},"end":{"line":436,"column":76}},"type":"binary-expr","locations":[{"start":{"line":436,"column":37},"end":{"line":436,"column":53}},{"start":{"line":436,"column":53},"end":{"line":436,"column":76}}],"line":436},"33":{"loc":{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},"type":"if","locations":[{"start":{"line":452,"column":2},"end":{"line":454,"column":null}},{"start":{},"end":{}}],"line":452},"34":{"loc":{"start":{"line":452,"column":6},"end":{"line":452,"column":73}},"type":"binary-expr","locations":[{"start":{"line":452,"column":6},"end":{"line":452,"column":31}},{"start":{"line":452,"column":31},"end":{"line":452,"column":73}}],"line":452},"35":{"loc":{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},"type":"if","locations":[{"start":{"line":455,"column":2},"end":{"line":457,"column":null}},{"start":{},"end":{}}],"line":455},"36":{"loc":{"start":{"line":455,"column":6},"end":{"line":455,"column":72}},"type":"binary-expr","locations":[{"start":{"line":455,"column":6},"end":{"line":455,"column":28}},{"start":{"line":455,"column":28},"end":{"line":455,"column":72}}],"line":455},"37":{"loc":{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},"type":"if","locations":[{"start":{"line":458,"column":2},"end":{"line":460,"column":null}},{"start":{},"end":{}}],"line":458},"38":{"loc":{"start":{"line":458,"column":6},"end":{"line":458,"column":57}},"type":"binary-expr","locations":[{"start":{"line":458,"column":6},"end":{"line":458,"column":23}},{"start":{"line":458,"column":23},"end":{"line":458,"column":57}}],"line":458},"39":{"loc":{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},"type":"if","locations":[{"start":{"line":461,"column":2},"end":{"line":463,"column":null}},{"start":{},"end":{}}],"line":461},"40":{"loc":{"start":{"line":461,"column":6},"end":{"line":461,"column":59}},"type":"binary-expr","locations":[{"start":{"line":461,"column":6},"end":{"line":461,"column":24}},{"start":{"line":461,"column":24},"end":{"line":461,"column":59}}],"line":461},"41":{"loc":{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},"type":"if","locations":[{"start":{"line":464,"column":2},"end":{"line":466,"column":null}},{"start":{},"end":{}}],"line":464},"42":{"loc":{"start":{"line":464,"column":6},"end":{"line":464,"column":80}},"type":"binary-expr","locations":[{"start":{"line":464,"column":6},"end":{"line":464,"column":30}},{"start":{"line":464,"column":30},"end":{"line":464,"column":80}}],"line":464},"43":{"loc":{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":2},"end":{"line":469,"column":null}},{"start":{},"end":{}}],"line":467},"44":{"loc":{"start":{"line":467,"column":6},"end":{"line":467,"column":106}},"type":"binary-expr","locations":[{"start":{"line":467,"column":6},"end":{"line":467,"column":44}},{"start":{"line":467,"column":44},"end":{"line":467,"column":106}}],"line":467},"45":{"loc":{"start":{"line":467,"column":72},"end":{"line":467,"column":103}},"type":"binary-expr","locations":[{"start":{"line":467,"column":72},"end":{"line":467,"column":101}},{"start":{"line":467,"column":101},"end":{"line":467,"column":103}}],"line":467},"46":{"loc":{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},"type":"if","locations":[{"start":{"line":471,"column":2},"end":{"line":473,"column":null}},{"start":{},"end":{}}],"line":471},"47":{"loc":{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},"type":"if","locations":[{"start":{"line":474,"column":2},"end":{"line":478,"column":null}},{"start":{"line":476,"column":9},"end":{"line":478,"column":null}}],"line":474},"48":{"loc":{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},"type":"if","locations":[{"start":{"line":476,"column":9},"end":{"line":478,"column":null}},{"start":{},"end":{}}],"line":476},"49":{"loc":{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":2},"end":{"line":485,"column":null}},{"start":{},"end":{}}],"line":479},"50":{"loc":{"start":{"line":480,"column":4},"end":{"line":482,"column":null}},"type":"binary-expr","locations":[{"start":{"line":480,"column":4},"end":{"line":480,"column":null}},{"start":{"line":481,"column":5},"end":{"line":481,"column":null}},{"start":{"line":482,"column":6},"end":{"line":482,"column":null}}],"line":480},"51":{"loc":{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},"type":"if","locations":[{"start":{"line":486,"column":2},"end":{"line":491,"column":null}},{"start":{},"end":{}}],"line":486},"52":{"loc":{"start":{"line":487,"column":4},"end":{"line":488,"column":null}},"type":"binary-expr","locations":[{"start":{"line":487,"column":4},"end":{"line":487,"column":null}},{"start":{"line":488,"column":4},"end":{"line":488,"column":null}}],"line":487},"53":{"loc":{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},"type":"if","locations":[{"start":{"line":493,"column":2},"end":{"line":495,"column":null}},{"start":{},"end":{}}],"line":493},"54":{"loc":{"start":{"line":493,"column":6},"end":{"line":493,"column":83}},"type":"binary-expr","locations":[{"start":{"line":493,"column":6},"end":{"line":493,"column":52}},{"start":{"line":493,"column":52},"end":{"line":493,"column":83}}],"line":493},"55":{"loc":{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},"type":"if","locations":[{"start":{"line":511,"column":4},"end":{"line":513,"column":null}},{"start":{},"end":{}}],"line":511},"56":{"loc":{"start":{"line":512,"column":19},"end":{"line":512,"column":56}},"type":"binary-expr","locations":[{"start":{"line":512,"column":19},"end":{"line":512,"column":43}},{"start":{"line":512,"column":43},"end":{"line":512,"column":56}}],"line":512},"57":{"loc":{"start":{"line":531,"column":2},"end":{"line":531,"column":null}},"type":"default-arg","locations":[{"start":{"line":531,"column":67},"end":{"line":531,"column":null}}],"line":531},"58":{"loc":{"start":{"line":548,"column":2},"end":{"line":548,"column":null}},"type":"default-arg","locations":[{"start":{"line":548,"column":80},"end":{"line":548,"column":null}}],"line":548},"59":{"loc":{"start":{"line":549,"column":2},"end":{"line":549,"column":null}},"type":"default-arg","locations":[{"start":{"line":549,"column":18},"end":{"line":549,"column":null}}],"line":549}},"s":{"0":1,"1":1,"2":1,"3":1,"4":7,"5":7,"6":7,"7":1,"8":6,"9":6,"10":6,"11":6,"12":6,"13":6,"14":6,"15":6,"16":12,"17":6,"18":22,"19":22,"20":6,"21":2,"22":4,"23":16,"24":15,"25":15,"26":7,"27":9,"28":10,"29":10,"30":10,"31":1,"32":9,"33":1,"34":8,"35":8,"36":6,"37":6,"38":6,"39":16,"40":1,"41":15,"42":7,"43":8,"44":8,"45":4,"46":6,"47":1,"48":8,"49":8,"50":8,"51":8,"52":6,"53":6,"54":6,"55":6,"56":6,"57":6,"58":6,"59":8,"60":3,"61":3,"62":3,"63":3,"64":3,"65":3,"66":3,"67":2,"68":1,"69":5,"70":5,"71":17,"72":16,"73":4,"74":16,"75":5,"76":5,"77":5,"78":14,"79":20,"80":20,"81":2,"82":20,"83":1,"84":20,"85":0,"86":20,"87":0,"88":20,"89":1,"90":20,"91":0,"92":20,"93":20,"94":1,"95":20,"96":0,"97":20,"98":21,"99":1,"100":20,"101":1,"102":20,"103":1,"104":20,"105":2,"106":20,"107":3,"108":3,"109":10,"110":10,"111":2,"112":3,"113":2,"114":2,"115":2,"116":2},"f":{"0":7,"1":12,"2":22,"3":10,"4":6,"5":1,"6":8,"7":6,"8":3,"9":5,"10":17,"11":16,"12":4,"13":16,"14":5,"15":14,"16":20,"17":21,"18":3,"19":2,"20":2},"b":{"0":[7],"1":[7,5],"2":[1,6],"3":[22],"4":[7,15],"5":[6,16],"6":[2,4],"7":[6,5,5],"8":[15,1],"9":[7,8],"10":[10],"11":[5,5],"12":[1,9],"13":[1,8],"14":[6,2],"15":[6],"16":[6,0],"17":[1,15],"18":[7,8],"19":[4,4],"20":[4,0],"21":[8],"22":[8,0],"23":[1,5],"24":[6,1],"25":[1,5],"26":[6,0],"27":[3,3],"28":[3],"29":[2,1],"30":[3,2,2],"31":[17,1],"32":[14,2],"33":[2,18],"34":[20,18],"35":[1,19],"36":[20,20],"37":[0,20],"38":[20,20],"39":[0,20],"40":[20,20],"41":[1,19],"42":[20,20],"43":[0,20],"44":[20,19],"45":[19,0],"46":[1,19],"47":[0,20],"48":[1,19],"49":[1,19],"50":[20,20,20],"51":[1,19],"52":[20,6],"53":[2,18],"54":[20,5],"55":[2,8],"56":[2,0],"57":[2],"58":[2],"59":[2]},"meta":{"lastBranch":60,"lastFunction":21,"lastStatement":117,"seen":{"s:119:46:119:Infinity":0,"s:126:34:126:Infinity":1,"s:129:36:129:Infinity":2,"s:132:36:132:Infinity":3,"f:156:16:156:Infinity":0,"b:158:39:158:Infinity":0,"s:160:17:160:Infinity":4,"b:160:17:160:43:160:43:160:Infinity":1,"s:161:14:161:Infinity":5,"b:162:2:164:Infinity:undefined:undefined:undefined:undefined":2,"s:162:2:164:Infinity":6,"s:163:4:163:Infinity":7,"s:165:15:165:Infinity":8,"s:166:16:166:Infinity":9,"s:167:14:167:Infinity":10,"s:169:23:169:Infinity":11,"s:170:8:170:Infinity":12,"s:172:30:172:Infinity":13,"s:173:22:173:Infinity":14,"s:175:8:175:Infinity":15,"f:175:8:175:15":1,"s:175:37:175:Infinity":16,"s:176:2:176:Infinity":17,"f:200:16:200:Infinity":2,"b:202:24:202:Infinity":3,"s:204:14:204:Infinity":18,"b:204:41:204:73:204:73:204:Infinity":4,"b:206:2:214:Infinity:undefined:undefined:undefined:undefined":5,"s:206:2:214:Infinity":19,"b:207:4:212:Infinity:undefined:undefined:undefined:undefined":6,"s:207:4:212:Infinity":20,"b:208:6:208:Infinity:209:7:209:58:209:58:209:Infinity":7,"s:211:6:211:Infinity":21,"s:213:4:213:Infinity":22,"b:216:2:221:Infinity:undefined:undefined:undefined:undefined":8,"s:216:2:221:Infinity":23,"s:217:21:217:Infinity":24,"b:218:4:220:Infinity:undefined:undefined:undefined:undefined":9,"s:218:4:220:Infinity":25,"s:219:6:219:Infinity":26,"s:223:2:223:Infinity":27,"f:234:16:234:Infinity":3,"b:236:24:236:Infinity":10,"s:238:14:238:Infinity":28,"b:238:41:238:73:238:73:238:Infinity":11,"s:239:19:239:Infinity":29,"b:240:2:242:Infinity:undefined:undefined:undefined:undefined":12,"s:240:2:242:Infinity":30,"s:241:4:241:Infinity":31,"b:243:2:245:Infinity:undefined:undefined:undefined:undefined":13,"s:243:2:245:Infinity":32,"s:244:4:244:Infinity":33,"s:246:17:246:Infinity":34,"s:247:2:247:Infinity":35,"b:247:22:247:67:247:67:247:Infinity":14,"f:262:16:262:Infinity":4,"b:264:24:264:Infinity":15,"s:266:14:266:Infinity":36,"b:266:41:266:73:266:73:266:Infinity":16,"s:267:37:267:Infinity":37,"s:269:2:286:Infinity":38,"b:270:4:270:Infinity:undefined:undefined:undefined:undefined":17,"s:270:4:270:Infinity":39,"s:270:36:270:Infinity":40,"b:271:4:271:Infinity:undefined:undefined:undefined:undefined":18,"s:271:4:271:Infinity":41,"s:271:38:271:Infinity":42,"s:273:19:273:Infinity":43,"b:274:4:285:Infinity:undefined:undefined:undefined:undefined":19,"s:274:4:285:Infinity":44,"s:275:6:284:Infinity":45,"b:282:20:282:41:282:41:282:Infinity":20,"s:288:2:288:Infinity":46,"f:288:16:288:22":5,"s:288:31:288:62":47,"f:305:16:305:Infinity":6,"b:307:24:307:Infinity":21,"s:309:14:309:Infinity":48,"b:309:41:309:73:309:73:309:Infinity":22,"s:312:4:312:Infinity":49,"s:314:4:314:Infinity":50,"s:316:15:333:Infinity":51,"f:316:23:316:28":7,"s:317:19:317:Infinity":52,"s:318:20:320:Infinity":53,"b:319:8:319:Infinity:320:8:320:Infinity":23,"b:318:20:318:44:318:44:318:Infinity":24,"s:321:23:321:Infinity":54,"b:321:37:321:55:321:55:321:Infinity":25,"s:322:24:327:Infinity":55,"s:328:24:328:Infinity":56,"b:328:24:328:48:328:48:328:Infinity":26,"s:329:22:331:Infinity":57,"b:330:8:330:Infinity:331:8:331:Infinity":27,"s:332:4:332:Infinity":58,"s:335:2:335:Infinity":59,"f:353:16:353:Infinity":8,"b:356:24:356:Infinity":28,"s:358:16:358:Infinity":60,"s:359:16:367:Infinity":61,"s:369:22:369:Infinity":62,"s:370:20:370:Infinity":63,"s:371:19:371:Infinity":64,"s:372:17:372:Infinity":65,"b:374:2:380:Infinity:undefined:undefined:undefined:undefined":29,"s:374:2:380:Infinity":66,"b:374:6:374:25:374:25:374:42:374:42:374:61":30,"s:375:4:378:Infinity":67,"s:382:2:382:Infinity":68,"f:396:16:396:Infinity":9,"s:400:13:400:Infinity":69,"s:401:2:403:Infinity":70,"f:401:17:401:25":10,"s:401:25:402:Infinity":71,"b:402:5:402:21:402:21:402:23":31,"f:402:25:402:31":11,"s:402:37:402:59":72,"f:412:16:412:Infinity":12,"s:416:2:416:Infinity":73,"f:416:17:416:25":13,"s:416:31:416:63":74,"f:425:16:425:Infinity":14,"s:429:46:434:Infinity":75,"s:435:20:435:Infinity":76,"s:436:2:436:Infinity":77,"f:436:17:436:25":15,"s:436:31:436:85":78,"b:436:37:436:53:436:53:436:76":32,"f:449:16:449:34":16,"s:450:27:450:Infinity":79,"b:452:2:454:Infinity:undefined:undefined:undefined:undefined":33,"s:452:2:454:Infinity":80,"b:452:6:452:31:452:31:452:73":34,"s:453:4:453:Infinity":81,"b:455:2:457:Infinity:undefined:undefined:undefined:undefined":35,"s:455:2:457:Infinity":82,"b:455:6:455:28:455:28:455:72":36,"s:456:4:456:Infinity":83,"b:458:2:460:Infinity:undefined:undefined:undefined:undefined":37,"s:458:2:460:Infinity":84,"b:458:6:458:23:458:23:458:57":38,"s:459:4:459:Infinity":85,"b:461:2:463:Infinity:undefined:undefined:undefined:undefined":39,"s:461:2:463:Infinity":86,"b:461:6:461:24:461:24:461:59":40,"s:462:4:462:Infinity":87,"b:464:2:466:Infinity:undefined:undefined:undefined:undefined":41,"s:464:2:466:Infinity":88,"b:464:6:464:30:464:30:464:80":42,"s:465:4:465:Infinity":89,"b:467:2:469:Infinity:undefined:undefined:undefined:undefined":43,"s:467:2:469:Infinity":90,"b:467:6:467:44:467:44:467:106":44,"b:467:72:467:101:467:101:467:103":45,"s:468:4:468:Infinity":91,"s:470:45:470:Infinity":92,"b:471:2:473:Infinity:undefined:undefined:undefined:undefined":46,"s:471:2:473:Infinity":93,"s:472:4:472:Infinity":94,"b:474:2:478:Infinity:476:9:478:Infinity":47,"s:474:2:478:Infinity":95,"s:475:4:475:Infinity":96,"b:476:9:478:Infinity:undefined:undefined:undefined:undefined":48,"s:476:9:478:Infinity":97,"f:476:52:476:59":17,"s:476:66:476:88":98,"s:477:4:477:Infinity":99,"b:479:2:485:Infinity:undefined:undefined:undefined:undefined":49,"s:479:2:485:Infinity":100,"b:480:4:480:Infinity:481:5:481:Infinity:482:6:482:Infinity":50,"s:484:4:484:Infinity":101,"b:486:2:491:Infinity:undefined:undefined:undefined:undefined":51,"s:486:2:491:Infinity":102,"b:487:4:487:Infinity:488:4:488:Infinity":52,"s:490:4:490:Infinity":103,"b:493:2:495:Infinity:undefined:undefined:undefined:undefined":53,"s:493:2:495:Infinity":104,"b:493:6:493:52:493:52:493:83":54,"s:494:4:494:Infinity":105,"s:497:2:497:Infinity":106,"f:505:16:505:Infinity":18,"s:508:19:508:Infinity":107,"s:509:2:514:Infinity":108,"s:510:19:510:Infinity":109,"b:511:4:513:Infinity:undefined:undefined:undefined:undefined":55,"s:511:4:513:Infinity":110,"s:512:6:512:Infinity":111,"b:512:19:512:43:512:43:512:56":56,"s:515:2:515:Infinity":112,"f:529:16:529:Infinity":19,"b:531:67:531:Infinity":57,"s:533:14:533:Infinity":113,"s:534:2:534:Infinity":114,"f:545:16:545:Infinity":20,"b:548:80:548:Infinity":58,"b:549:18:549:Infinity":59,"s:552:4:556:Infinity":115,"s:557:2:557:Infinity":116}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/confidence.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/confidence.ts","statementMap":{"0":{"start":{"line":18,"column":14},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},"2":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"3":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"4":{"start":{"line":22,"column":42},"end":{"line":22,"column":null}},"5":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}}},"fnMap":{"0":{"name":"degrade","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":24}},"loc":{"start":{"line":17,"column":51},"end":{"line":24,"column":null}},"line":17}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":19,"column":2},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":19},"1":{"loc":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"type":"if","locations":[{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},{"start":{},"end":{}}],"line":22}},"s":{"0":35,"1":35,"2":1,"3":34,"4":2,"5":32},"f":{"0":35},"b":{"0":[1,34],"1":[2,32]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":6,"seen":{"f:17:16:17:24":0,"s:18:14:18:Infinity":0,"b:19:2:21:Infinity:undefined:undefined:undefined:undefined":0,"s:19:2:21:Infinity":1,"s:20:4:20:Infinity":2,"b:22:2:22:Infinity:undefined:undefined:undefined:undefined":1,"s:22:2:22:Infinity":3,"s:22:42:22:Infinity":4,"s:23:2:23:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/constants.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/constants.ts","statementMap":{"0":{"start":{"line":16,"column":18},"end":{"line":16,"column":null}},"1":{"start":{"line":19,"column":25},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":28},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":24},"end":{"line":21,"column":null}},"4":{"start":{"line":23,"column":28},"end":{"line":37,"column":null}},"5":{"start":{"line":39,"column":30},"end":{"line":45,"column":null}},"6":{"start":{"line":47,"column":46},"end":{"line":53,"column":null}},"7":{"start":{"line":54,"column":33},"end":{"line":54,"column":null}},"8":{"start":{"line":55,"column":30},"end":{"line":55,"column":null}},"9":{"start":{"line":62,"column":61},"end":{"line":76,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":4},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":10,"seen":{"s:16:18:16:Infinity":0,"s:19:25:19:Infinity":1,"s:20:28:20:Infinity":2,"s:21:24:21:Infinity":3,"s:23:28:37:Infinity":4,"s:39:30:45:Infinity":5,"s:47:46:53:Infinity":6,"s:54:33:54:Infinity":7,"s:55:30:55:Infinity":8,"s:62:61:76:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/date-helpers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/date-helpers.ts","statementMap":{"0":{"start":{"line":12,"column":12},"end":{"line":12,"column":null}},"1":{"start":{"line":13,"column":2},"end":{"line":13,"column":null}},"2":{"start":{"line":14,"column":2},"end":{"line":14,"column":null}},"3":{"start":{"line":19,"column":12},"end":{"line":19,"column":null}},"4":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"5":{"start":{"line":21,"column":2},"end":{"line":21,"column":null}}},"fnMap":{"0":{"name":"subtractDays","decl":{"start":{"line":11,"column":16},"end":{"line":11,"column":29}},"loc":{"start":{"line":11,"column":65},"end":{"line":15,"column":null}},"line":11},"1":{"name":"addDays","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":24}},"loc":{"start":{"line":18,"column":60},"end":{"line":22,"column":null}},"line":18}},"branchMap":{},"s":{"0":47,"1":47,"2":47,"3":39,"4":39,"5":39},"f":{"0":47,"1":39},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":6,"seen":{"f:11:16:11:29":0,"s:12:12:12:Infinity":0,"s:13:2:13:Infinity":1,"s:14:2:14:Infinity":2,"f:18:16:18:24":1,"s:19:12:19:Infinity":3,"s:20:2:20:Infinity":4,"s:21:2:21:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/horizon.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/horizon.ts","statementMap":{"0":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"1":{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},"2":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"3":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"4":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"5":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}}},"fnMap":{"0":{"name":"isLongHorizon","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":57},"end":{"line":19,"column":null}},"line":17},"1":{"name":"determineOrigin","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"loc":{"start":{"line":30,"column":28},"end":{"line":38,"column":null}},"line":30}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":2},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":31},"1":{"loc":{"start":{"line":32,"column":11},"end":{"line":32,"column":null}},"type":"cond-expr","locations":[{"start":{"line":32,"column":42},"end":{"line":32,"column":56}},{"start":{"line":32,"column":56},"end":{"line":32,"column":null}}],"line":32},"2":{"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":37,"column":9},"end":{"line":37,"column":null}},"type":"cond-expr","locations":[{"start":{"line":37,"column":61},"end":{"line":37,"column":75}},{"start":{"line":37,"column":75},"end":{"line":37,"column":null}}],"line":37},"4":{"loc":{"start":{"line":37,"column":9},"end":{"line":37,"column":61}},"type":"binary-expr","locations":[{"start":{"line":37,"column":9},"end":{"line":37,"column":30}},{"start":{"line":37,"column":30},"end":{"line":37,"column":61}}],"line":37}},"s":{"0":14,"1":33,"2":15,"3":18,"4":18,"5":0},"f":{"0":14,"1":33},"b":{"0":[15,18],"1":[14,1],"2":[18,0],"3":[0,0],"4":[0,0]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":6,"seen":{"f:17:16:17:30":0,"s:18:2:18:Infinity":0,"f:26:16:26:Infinity":1,"b:31:2:33:Infinity:undefined:undefined:undefined:undefined":0,"s:31:2:33:Infinity":1,"s:32:4:32:Infinity":2,"b:32:42:32:56:32:56:32:Infinity":1,"b:34:2:36:Infinity:undefined:undefined:undefined:undefined":2,"s:34:2:36:Infinity":3,"s:35:4:35:Infinity":4,"s:37:2:37:Infinity":5,"b:37:61:37:75:37:75:37:Infinity":3,"b:37:9:37:30:37:30:37:61":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/emitter.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/emitter.ts","statementMap":{"0":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"2":{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"5":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"6":{"start":{"line":48,"column":22},"end":{"line":48,"column":null}},"7":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"8":{"start":{"line":52,"column":21},"end":{"line":57,"column":null}},"9":{"start":{"line":54,"column":22},"end":{"line":54,"column":null}},"10":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"11":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"12":{"start":{"line":67,"column":26},"end":{"line":67,"column":null}},"13":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"14":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"15":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"16":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"17":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"18":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"19":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"20":{"start":{"line":77,"column":2},"end":{"line":77,"column":null}},"21":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"22":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"24":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"25":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"26":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"27":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"28":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"29":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"30":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"31":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"32":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"33":{"start":{"line":92,"column":2},"end":{"line":103,"column":null}},"34":{"start":{"line":93,"column":19},"end":{"line":93,"column":null}},"35":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"36":{"start":{"line":97,"column":6},"end":{"line":99,"column":null}},"37":{"start":{"line":100,"column":4},"end":{"line":102,"column":null}},"38":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"39":{"start":{"line":105,"column":2},"end":{"line":105,"column":null}},"40":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"41":{"start":{"line":108,"column":19},"end":{"line":108,"column":null}},"42":{"start":{"line":108,"column":45},"end":{"line":108,"column":64}},"43":{"start":{"line":109,"column":2},"end":{"line":109,"column":null}},"44":{"start":{"line":110,"column":2},"end":{"line":110,"column":null}},"45":{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},"46":{"start":{"line":112,"column":4},"end":{"line":112,"column":null}},"47":{"start":{"line":114,"column":4},"end":{"line":126,"column":null}},"48":{"start":{"line":115,"column":6},"end":{"line":115,"column":null}},"49":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"50":{"start":{"line":117,"column":6},"end":{"line":117,"column":null}},"51":{"start":{"line":118,"column":6},"end":{"line":118,"column":null}},"52":{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},"53":{"start":{"line":120,"column":8},"end":{"line":120,"column":null}},"54":{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},"55":{"start":{"line":123,"column":8},"end":{"line":123,"column":null}},"56":{"start":{"line":125,"column":6},"end":{"line":125,"column":null}},"57":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}},"58":{"start":{"line":129,"column":2},"end":{"line":129,"column":null}},"59":{"start":{"line":131,"column":23},"end":{"line":131,"column":null}},"60":{"start":{"line":131,"column":49},"end":{"line":131,"column":68}},"61":{"start":{"line":132,"column":2},"end":{"line":132,"column":null}},"62":{"start":{"line":133,"column":2},"end":{"line":133,"column":null}},"63":{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},"64":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"65":{"start":{"line":137,"column":4},"end":{"line":137,"column":null}},"66":{"start":{"line":138,"column":4},"end":{"line":138,"column":null}},"67":{"start":{"line":139,"column":4},"end":{"line":142,"column":null}},"68":{"start":{"line":140,"column":20},"end":{"line":140,"column":null}},"69":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"70":{"start":{"line":144,"column":2},"end":{"line":144,"column":null}},"71":{"start":{"line":146,"column":2},"end":{"line":146,"column":null}}},"fnMap":{"0":{"name":"emitRollforwardMd","decl":{"start":{"line":32,"column":16},"end":{"line":32,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":147,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":52,"column":28},"end":{"line":52,"column":null}},"loc":{"start":{"line":53,"column":13},"end":{"line":56,"column":7}},"line":53},"2":{"name":"(anonymous_2)","decl":{"start":{"line":108,"column":31},"end":{"line":108,"column":39}},"loc":{"start":{"line":108,"column":45},"end":{"line":108,"column":64}},"line":108},"3":{"name":"(anonymous_3)","decl":{"start":{"line":131,"column":35},"end":{"line":131,"column":43}},"loc":{"start":{"line":131,"column":49},"end":{"line":131,"column":68}},"line":131}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":63},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":19},"end":{"line":38,"column":39}},{"start":{"line":38,"column":39},"end":{"line":38,"column":null}}],"line":38},"2":{"loc":{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":50,"column":null}},{"start":{"line":47,"column":9},"end":{"line":50,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":46,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":52,"column":21},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":28},"end":{"line":56,"column":null}},{"start":{"line":57,"column":6},"end":{"line":57,"column":null}}],"line":52},"5":{"loc":{"start":{"line":55,"column":15},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":23},"end":{"line":55,"column":34}},{"start":{"line":55,"column":34},"end":{"line":55,"column":null}}],"line":55},"6":{"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":8},"end":{"line":64,"column":null}},{"start":{"line":65,"column":8},"end":{"line":65,"column":null}}],"line":59},"7":{"loc":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"type":"cond-expr","locations":[{"start":{"line":95,"column":30},"end":{"line":95,"column":65}},{"start":{"line":95,"column":65},"end":{"line":95,"column":null}}],"line":95},"8":{"loc":{"start":{"line":97,"column":6},"end":{"line":99,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":10},"end":{"line":98,"column":null}},{"start":{"line":99,"column":10},"end":{"line":99,"column":null}}],"line":97},"9":{"loc":{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":2},"end":{"line":127,"column":null}},{"start":{"line":113,"column":9},"end":{"line":127,"column":null}}],"line":111},"10":{"loc":{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":119},"11":{"loc":{"start":{"line":119,"column":10},"end":{"line":119,"column":61}},"type":"binary-expr","locations":[{"start":{"line":119,"column":10},"end":{"line":119,"column":31}},{"start":{"line":119,"column":31},"end":{"line":119,"column":61}}],"line":119},"12":{"loc":{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":122,"column":6},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":122},"13":{"loc":{"start":{"line":122,"column":10},"end":{"line":122,"column":61}},"type":"binary-expr","locations":[{"start":{"line":122,"column":10},"end":{"line":122,"column":31}},{"start":{"line":122,"column":31},"end":{"line":122,"column":61}}],"line":122},"14":{"loc":{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":2},"end":{"line":143,"column":null}},{"start":{"line":136,"column":9},"end":{"line":143,"column":null}}],"line":134},"15":{"loc":{"start":{"line":140,"column":20},"end":{"line":140,"column":null}},"type":"cond-expr","locations":[{"start":{"line":140,"column":41},"end":{"line":140,"column":62}},{"start":{"line":140,"column":62},"end":{"line":140,"column":null}}],"line":140}},"s":{"0":16,"1":16,"2":16,"3":16,"4":16,"5":0,"6":0,"7":0,"8":16,"9":16,"10":16,"11":16,"12":16,"13":16,"14":16,"15":16,"16":16,"17":16,"18":16,"19":16,"20":16,"21":16,"22":16,"23":16,"24":16,"25":16,"26":16,"27":16,"28":16,"29":16,"30":16,"31":16,"32":16,"33":16,"34":33,"35":33,"36":33,"37":33,"38":16,"39":16,"40":16,"41":16,"42":33,"43":16,"44":16,"45":16,"46":0,"47":16,"48":17,"49":17,"50":17,"51":17,"52":17,"53":16,"54":17,"55":16,"56":17,"57":16,"58":16,"59":16,"60":33,"61":16,"62":16,"63":16,"64":0,"65":16,"66":16,"67":16,"68":16,"69":16,"70":16,"71":16},"f":{"0":16,"1":16,"2":33,"3":33},"b":{"0":[16],"1":[16,5],"2":[16,0],"3":[0,16],"4":[16,0],"5":[16,0],"6":[16,0],"7":[17,16],"8":[17,16],"9":[0,16],"10":[16,1],"11":[17,17],"12":[16,1],"13":[17,17],"14":[0,16],"15":[16,0]},"meta":{"lastBranch":16,"lastFunction":4,"lastStatement":72,"seen":{"f:32:16:32:Infinity":0,"b:36:63:36:Infinity":0,"s:38:19:38:Infinity":0,"b:38:19:38:39:38:39:38:Infinity":1,"s:39:22:39:Infinity":1,"b:42:2:50:Infinity:47:9:50:Infinity":2,"s:42:2:50:Infinity":2,"s:43:4:43:Infinity":3,"b:44:4:46:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:46:Infinity":4,"s:45:6:45:Infinity":5,"s:48:22:48:Infinity":6,"s:49:4:49:Infinity":7,"s:52:21:57:Infinity":8,"b:52:28:56:Infinity:57:6:57:Infinity":4,"f:52:28:52:Infinity":1,"s:54:22:54:Infinity":9,"s:55:8:55:Infinity":10,"b:55:23:55:34:55:34:55:Infinity":5,"s:59:4:65:Infinity":11,"b:60:8:64:Infinity:65:8:65:Infinity":6,"s:67:26:67:Infinity":12,"s:69:2:69:Infinity":13,"s:70:2:70:Infinity":14,"s:71:2:71:Infinity":15,"s:72:2:72:Infinity":16,"s:73:2:73:Infinity":17,"s:74:2:74:Infinity":18,"s:75:2:75:Infinity":19,"s:77:2:77:Infinity":20,"s:78:2:78:Infinity":21,"s:79:2:79:Infinity":22,"s:80:2:80:Infinity":23,"s:81:2:81:Infinity":24,"s:82:2:82:Infinity":25,"s:83:2:83:Infinity":26,"s:84:2:84:Infinity":27,"s:85:2:85:Infinity":28,"s:87:2:87:Infinity":29,"s:88:2:88:Infinity":30,"s:89:2:89:Infinity":31,"s:90:2:90:Infinity":32,"s:92:2:103:Infinity":33,"s:93:19:93:Infinity":34,"s:95:6:95:Infinity":35,"b:95:30:95:65:95:65:95:Infinity":7,"s:97:6:99:Infinity":36,"b:98:10:98:Infinity:99:10:99:Infinity":8,"s:100:4:102:Infinity":37,"s:104:2:104:Infinity":38,"s:105:2:105:Infinity":39,"s:106:2:106:Infinity":40,"s:108:19:108:Infinity":41,"f:108:31:108:39":2,"s:108:45:108:64":42,"s:109:2:109:Infinity":43,"s:110:2:110:Infinity":44,"b:111:2:127:Infinity:113:9:127:Infinity":9,"s:111:2:127:Infinity":45,"s:112:4:112:Infinity":46,"s:114:4:126:Infinity":47,"s:115:6:115:Infinity":48,"s:116:6:116:Infinity":49,"s:117:6:117:Infinity":50,"s:118:6:118:Infinity":51,"b:119:6:121:Infinity:undefined:undefined:undefined:undefined":10,"s:119:6:121:Infinity":52,"b:119:10:119:31:119:31:119:61":11,"s:120:8:120:Infinity":53,"b:122:6:124:Infinity:undefined:undefined:undefined:undefined":12,"s:122:6:124:Infinity":54,"b:122:10:122:31:122:31:122:61":13,"s:123:8:123:Infinity":55,"s:125:6:125:Infinity":56,"s:128:2:128:Infinity":57,"s:129:2:129:Infinity":58,"s:131:23:131:Infinity":59,"f:131:35:131:43":3,"s:131:49:131:68":60,"s:132:2:132:Infinity":61,"s:133:2:133:Infinity":62,"b:134:2:143:Infinity:136:9:143:Infinity":14,"s:134:2:143:Infinity":63,"s:135:4:135:Infinity":64,"s:137:4:137:Infinity":65,"s:138:4:138:Infinity":66,"s:139:4:142:Infinity":67,"s:140:20:140:Infinity":68,"b:140:41:140:62:140:62:140:Infinity":15,"s:141:6:141:Infinity":69,"s:144:2:144:Infinity":70,"s:146:2:146:Infinity":71}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/roll-forward.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/roll-forward.ts","statementMap":{"0":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"1":{"start":{"line":33,"column":36},"end":{"line":33,"column":null}},"2":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"3":{"start":{"line":36,"column":27},"end":{"line":47,"column":null}},"4":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"5":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"6":{"start":{"line":40,"column":50},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":4},"end":{"line":46,"column":null}},"9":{"start":{"line":49,"column":25},"end":{"line":49,"column":null}},"10":{"start":{"line":51,"column":4},"end":{"line":55,"column":null}},"11":{"start":{"line":57,"column":2},"end":{"line":65,"column":null}}},"fnMap":{"0":{"name":"rollForward","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"loc":{"start":{"line":32,"column":17},"end":{"line":66,"column":null}},"line":32},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":22},"end":{"line":33,"column":36}},"loc":{"start":{"line":33,"column":36},"end":{"line":33,"column":null}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":39},"end":{"line":36,"column":44}},"loc":{"start":{"line":36,"column":50},"end":{"line":47,"column":3}},"line":36}},"branchMap":{"0":{"loc":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"type":"default-arg","locations":[{"start":{"line":31,"column":53},"end":{"line":31,"column":null}}],"line":31},"1":{"loc":{"start":{"line":33,"column":14},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":14},"end":{"line":33,"column":36}},{"start":{"line":33,"column":22},"end":{"line":33,"column":null}}],"line":33},"2":{"loc":{"start":{"line":34,"column":19},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":19},"end":{"line":34,"column":39}},{"start":{"line":34,"column":39},"end":{"line":34,"column":null}}],"line":34},"3":{"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"4":{"loc":{"start":{"line":45,"column":26},"end":{"line":45,"column":50}},"type":"binary-expr","locations":[{"start":{"line":45,"column":26},"end":{"line":45,"column":45}},{"start":{"line":45,"column":45},"end":{"line":45,"column":50}}],"line":45},"5":{"loc":{"start":{"line":51,"column":4},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},{"start":{"line":55,"column":8},"end":{"line":55,"column":null}}],"line":51},"6":{"loc":{"start":{"line":51,"column":4},"end":{"line":53,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},{"start":{"line":53,"column":4},"end":{"line":53,"column":null}}],"line":51}},"s":{"0":30,"1":2,"2":30,"3":30,"4":56,"5":27,"6":29,"7":29,"8":29,"9":30,"10":30,"11":30},"f":{"0":30,"1":2,"2":56},"b":{"0":[30],"1":[30,2],"2":[30,16],"3":[27,29],"4":[29,2],"5":[13,17],"6":[30,30,13]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":12,"seen":{"f:26:16:26:Infinity":0,"b:31:53:31:Infinity":0,"s:33:14:33:Infinity":0,"b:33:14:33:36:33:22:33:Infinity":1,"f:33:22:33:36":1,"s:33:36:33:Infinity":1,"s:34:19:34:Infinity":2,"b:34:19:34:39:34:39:34:Infinity":2,"s:36:27:47:Infinity":3,"f:36:39:36:44":2,"b:37:4:39:Infinity:undefined:undefined:undefined:undefined":3,"s:37:4:39:Infinity":4,"s:38:6:38:Infinity":5,"s:40:50:40:Infinity":6,"s:41:4:41:Infinity":7,"s:42:4:46:Infinity":8,"b:45:26:45:45:45:45:45:50":4,"s:49:25:49:Infinity":9,"s:51:4:55:Infinity":10,"b:54:8:54:Infinity:55:8:55:Infinity":5,"b:51:4:51:Infinity:52:4:52:Infinity:53:4:53:Infinity":6,"s:57:2:65:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/source-locator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/source-locator.ts","statementMap":{"0":{"start":{"line":26,"column":2},"end":{"line":34,"column":null}},"1":{"start":{"line":26,"column":15},"end":{"line":26,"column":18}},"2":{"start":{"line":27,"column":22},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"4":{"start":{"line":33,"column":34},"end":{"line":33,"column":null}},"5":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}}},"fnMap":{"0":{"name":"findLatestSource","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":null}},"loc":{"start":{"line":25,"column":17},"end":{"line":36,"column":null}},"line":25}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"default-arg","locations":[{"start":{"line":23,"column":16},"end":{"line":23,"column":null}}],"line":23},"1":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"default-arg","locations":[{"start":{"line":24,"column":24},"end":{"line":24,"column":null}}],"line":24},"2":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33}},"s":{"0":5,"1":5,"2":38,"3":38,"4":2,"5":3},"f":{"0":5},"b":{"0":[5],"1":[5],"2":[2,36]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":6,"seen":{"f:20:16:20:Infinity":0,"b:23:16:23:Infinity":0,"b:24:24:24:Infinity":1,"s:26:2:34:Infinity":0,"s:26:15:26:18":1,"s:27:22:32:Infinity":2,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":2,"s:33:4:33:Infinity":3,"s:33:34:33:Infinity":4,"s:35:2:35:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/roll-forward-pirs/validator.ts","statementMap":{"0":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"2":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":34,"column":null}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"5":{"start":{"line":33,"column":23},"end":{"line":33,"column":null}},"6":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"7":{"start":{"line":36,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},"9":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"10":{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},"11":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"12":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"13":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"14":{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},"15":{"start":{"line":50,"column":4},"end":{"line":52,"column":null}},"16":{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},"17":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"18":{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},"19":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"20":{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},"21":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"22":{"start":{"line":67,"column":2},"end":{"line":103,"column":null}},"23":{"start":{"line":67,"column":15},"end":{"line":67,"column":18}},"24":{"start":{"line":68,"column":15},"end":{"line":68,"column":null}},"25":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"26":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"27":{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},"28":{"start":{"line":73,"column":6},"end":{"line":75,"column":null}},"29":{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},"30":{"start":{"line":78,"column":6},"end":{"line":80,"column":null}},"31":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"32":{"start":{"line":83,"column":6},"end":{"line":85,"column":null}},"33":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"34":{"start":{"line":88,"column":6},"end":{"line":90,"column":null}},"35":{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},"36":{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},"37":{"start":{"line":94,"column":8},"end":{"line":96,"column":null}},"38":{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},"39":{"start":{"line":99,"column":6},"end":{"line":101,"column":null}},"40":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}}},"fnMap":{"0":{"name":"validateSource","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":31}},"loc":{"start":{"line":27,"column":78},"end":{"line":105,"column":null}},"line":27}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":2},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":28},"1":{"loc":{"start":{"line":28,"column":6},"end":{"line":28,"column":47}},"type":"binary-expr","locations":[{"start":{"line":28,"column":6},"end":{"line":28,"column":33}},{"start":{"line":28,"column":33},"end":{"line":28,"column":47}}],"line":28},"2":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"3":{"loc":{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":35,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":35},"4":{"loc":{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":2},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":40},"5":{"loc":{"start":{"line":40,"column":6},"end":{"line":40,"column":88}},"type":"binary-expr","locations":[{"start":{"line":40,"column":6},"end":{"line":40,"column":42}},{"start":{"line":40,"column":42},"end":{"line":40,"column":88}}],"line":40},"6":{"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":43},"7":{"loc":{"start":{"line":43,"column":6},"end":{"line":43,"column":83}},"type":"binary-expr","locations":[{"start":{"line":43,"column":6},"end":{"line":43,"column":41}},{"start":{"line":43,"column":41},"end":{"line":43,"column":83}}],"line":43},"8":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"9":{"loc":{"start":{"line":46,"column":6},"end":{"line":46,"column":77}},"type":"binary-expr","locations":[{"start":{"line":46,"column":6},"end":{"line":46,"column":46}},{"start":{"line":46,"column":46},"end":{"line":46,"column":77}}],"line":46},"10":{"loc":{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":49},"11":{"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":2},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":54},"12":{"loc":{"start":{"line":54,"column":6},"end":{"line":54,"column":96}},"type":"binary-expr","locations":[{"start":{"line":54,"column":6},"end":{"line":54,"column":49}},{"start":{"line":54,"column":49},"end":{"line":54,"column":96}}],"line":54},"13":{"loc":{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":57},"14":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":null}},{"start":{"line":59,"column":4},"end":{"line":59,"column":null}},{"start":{"line":60,"column":4},"end":{"line":60,"column":null}}],"line":58},"15":{"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":2},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"16":{"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":4},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69},"17":{"loc":{"start":{"line":69,"column":8},"end":{"line":69,"column":45}},"type":"binary-expr","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":33}},{"start":{"line":69,"column":33},"end":{"line":69,"column":45}}],"line":69},"18":{"loc":{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":4},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":72},"19":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":78}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":43}},{"start":{"line":72,"column":43},"end":{"line":72,"column":78}}],"line":72},"20":{"loc":{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":77,"column":4},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":77},"21":{"loc":{"start":{"line":77,"column":8},"end":{"line":77,"column":74}},"type":"binary-expr","locations":[{"start":{"line":77,"column":8},"end":{"line":77,"column":46}},{"start":{"line":77,"column":46},"end":{"line":77,"column":74}}],"line":77},"22":{"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":82},"23":{"loc":{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":87},"24":{"loc":{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":102,"column":null}},{"start":{"line":98,"column":11},"end":{"line":102,"column":null}}],"line":92},"25":{"loc":{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":6},"end":{"line":97,"column":null}},{"start":{},"end":{}}],"line":93},"26":{"loc":{"start":{"line":93,"column":10},"end":{"line":93,"column":87}},"type":"binary-expr","locations":[{"start":{"line":93,"column":10},"end":{"line":93,"column":53}},{"start":{"line":93,"column":53},"end":{"line":93,"column":87}}],"line":93},"27":{"loc":{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":98,"column":11},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":98}},"s":{"0":30,"1":2,"2":28,"3":28,"4":159,"5":2,"6":26,"7":1,"8":25,"9":1,"10":24,"11":1,"12":23,"13":1,"14":22,"15":1,"16":21,"17":1,"18":20,"19":1,"20":19,"21":1,"22":18,"23":18,"24":28,"25":28,"26":1,"27":27,"28":1,"29":26,"30":1,"31":25,"32":1,"33":24,"34":2,"35":22,"36":11,"37":1,"38":11,"39":1,"40":10},"f":{"0":30},"b":{"0":[2,28],"1":[30,29],"2":[2,157],"3":[1,25],"4":[1,24],"5":[25,25],"6":[1,23],"7":[24,24],"8":[1,22],"9":[23,23],"10":[1,21],"11":[1,20],"12":[21,21],"13":[1,19],"14":[20,20,1],"15":[1,18],"16":[1,27],"17":[28,27],"18":[1,26],"19":[27,27],"20":[1,25],"21":[26,26],"22":[1,24],"23":[2,22],"24":[11,11],"25":[1,10],"26":[11,10],"27":[1,10]},"meta":{"lastBranch":28,"lastFunction":1,"lastStatement":41,"seen":{"f:27:16:27:31":0,"b:28:2:30:Infinity:undefined:undefined:undefined:undefined":0,"s:28:2:30:Infinity":0,"b:28:6:28:33:28:33:28:47":1,"s:29:4:29:Infinity":1,"s:31:14:31:Infinity":2,"s:32:2:34:Infinity":3,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":2,"s:33:4:33:Infinity":4,"s:33:23:33:Infinity":5,"b:35:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:35:2:39:Infinity":6,"s:36:4:38:Infinity":7,"b:40:2:42:Infinity:undefined:undefined:undefined:undefined":4,"s:40:2:42:Infinity":8,"b:40:6:40:42:40:42:40:88":5,"s:41:4:41:Infinity":9,"b:43:2:45:Infinity:undefined:undefined:undefined:undefined":6,"s:43:2:45:Infinity":10,"b:43:6:43:41:43:41:43:83":7,"s:44:4:44:Infinity":11,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":8,"s:46:2:48:Infinity":12,"b:46:6:46:46:46:46:46:77":9,"s:47:4:47:Infinity":13,"b:49:2:53:Infinity:undefined:undefined:undefined:undefined":10,"s:49:2:53:Infinity":14,"s:50:4:52:Infinity":15,"b:54:2:56:Infinity:undefined:undefined:undefined:undefined":11,"s:54:2:56:Infinity":16,"b:54:6:54:49:54:49:54:96":12,"s:55:4:55:Infinity":17,"b:57:2:63:Infinity:undefined:undefined:undefined:undefined":13,"s:57:2:63:Infinity":18,"b:58:4:58:Infinity:59:4:59:Infinity:60:4:60:Infinity":14,"s:62:4:62:Infinity":19,"b:64:2:66:Infinity:undefined:undefined:undefined:undefined":15,"s:64:2:66:Infinity":20,"s:65:4:65:Infinity":21,"s:67:2:103:Infinity":22,"s:67:15:67:18":23,"s:68:15:68:Infinity":24,"b:69:4:71:Infinity:undefined:undefined:undefined:undefined":16,"s:69:4:71:Infinity":25,"b:69:8:69:33:69:33:69:45":17,"s:70:6:70:Infinity":26,"b:72:4:76:Infinity:undefined:undefined:undefined:undefined":18,"s:72:4:76:Infinity":27,"b:72:8:72:43:72:43:72:78":19,"s:73:6:75:Infinity":28,"b:77:4:81:Infinity:undefined:undefined:undefined:undefined":20,"s:77:4:81:Infinity":29,"b:77:8:77:46:77:46:77:74":21,"s:78:6:80:Infinity":30,"b:82:4:86:Infinity:undefined:undefined:undefined:undefined":22,"s:82:4:86:Infinity":31,"s:83:6:85:Infinity":32,"b:87:4:91:Infinity:undefined:undefined:undefined:undefined":23,"s:87:4:91:Infinity":33,"s:88:6:90:Infinity":34,"b:92:4:102:Infinity:98:11:102:Infinity":24,"s:92:4:102:Infinity":35,"b:93:6:97:Infinity:undefined:undefined:undefined:undefined":25,"s:93:6:97:Infinity":36,"b:93:10:93:53:93:53:93:87":26,"s:94:8:96:Infinity":37,"b:98:11:102:Infinity:undefined:undefined:undefined:undefined":27,"s:98:11:102:Infinity":38,"s:99:6:101:Infinity":39,"s:104:2:104:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss-watch.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss-watch.ts","statementMap":{"0":{"start":{"line":37,"column":18},"end":{"line":37,"column":null}},"1":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"2":{"start":{"line":39,"column":34},"end":{"line":39,"column":null}},"3":{"start":{"line":43,"column":36},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":38},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"6":{"start":{"line":49,"column":20},"end":{"line":49,"column":null}},"7":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"8":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"9":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"10":{"start":{"line":61,"column":27},"end":{"line":61,"column":null}},"11":{"start":{"line":62,"column":2},"end":{"line":75,"column":null}},"12":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"13":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"14":{"start":{"line":65,"column":17},"end":{"line":65,"column":null}},"15":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"17":{"start":{"line":67,"column":34},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":4},"end":{"line":74,"column":null}},"19":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"20":{"start":{"line":83,"column":18},"end":{"line":83,"column":null}},"21":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"22":{"start":{"line":88,"column":24},"end":{"line":90,"column":null}},"23":{"start":{"line":89,"column":20},"end":{"line":89,"column":46}},"24":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"25":{"start":{"line":91,"column":34},"end":{"line":91,"column":null}},"26":{"start":{"line":92,"column":2},"end":{"line":97,"column":null}},"27":{"start":{"line":93,"column":21},"end":{"line":93,"column":null}},"28":{"start":{"line":94,"column":26},"end":{"line":94,"column":null}},"29":{"start":{"line":94,"column":58},"end":{"line":94,"column":95}},"30":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"31":{"start":{"line":95,"column":36},"end":{"line":95,"column":null}},"32":{"start":{"line":96,"column":4},"end":{"line":96,"column":null}},"33":{"start":{"line":105,"column":20},"end":{"line":105,"column":null}},"34":{"start":{"line":106,"column":21},"end":{"line":106,"column":null}},"35":{"start":{"line":107,"column":16},"end":{"line":107,"column":null}},"36":{"start":{"line":107,"column":33},"end":{"line":107,"column":53}},"37":{"start":{"line":108,"column":2},"end":{"line":174,"column":null}},"38":{"start":{"line":109,"column":21},"end":{"line":115,"column":null}},"39":{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},"40":{"start":{"line":117,"column":6},"end":{"line":127,"column":null}},"41":{"start":{"line":129,"column":16},"end":{"line":129,"column":null}},"42":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"43":{"start":{"line":135,"column":6},"end":{"line":145,"column":null}},"44":{"start":{"line":147,"column":18},"end":{"line":147,"column":null}},"45":{"start":{"line":148,"column":20},"end":{"line":148,"column":null}},"46":{"start":{"line":149,"column":4},"end":{"line":159,"column":null}},"47":{"start":{"line":161,"column":4},"end":{"line":171,"column":null}},"48":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"49":{"start":{"line":178,"column":2},"end":{"line":178,"column":null}},"50":{"start":{"line":179,"column":2},"end":{"line":179,"column":null}},"51":{"start":{"line":180,"column":2},"end":{"line":180,"column":null}},"52":{"start":{"line":184,"column":16},"end":{"line":184,"column":null}},"53":{"start":{"line":185,"column":32},"end":{"line":185,"column":null}},"54":{"start":{"line":186,"column":15},"end":{"line":186,"column":null}},"55":{"start":{"line":187,"column":16},"end":{"line":187,"column":null}},"56":{"start":{"line":188,"column":2},"end":{"line":209,"column":null}},"57":{"start":{"line":188,"column":15},"end":{"line":188,"column":18}},"58":{"start":{"line":189,"column":18},"end":{"line":189,"column":null}},"59":{"start":{"line":190,"column":17},"end":{"line":190,"column":null}},"60":{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},"61":{"start":{"line":192,"column":6},"end":{"line":192,"column":null}},"62":{"start":{"line":193,"column":6},"end":{"line":193,"column":null}},"63":{"start":{"line":194,"column":6},"end":{"line":194,"column":null}},"64":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"65":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"66":{"start":{"line":197,"column":53},"end":{"line":197,"column":65}},"67":{"start":{"line":198,"column":6},"end":{"line":198,"column":null}},"68":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"69":{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},"70":{"start":{"line":202,"column":6},"end":{"line":202,"column":null}},"71":{"start":{"line":203,"column":6},"end":{"line":203,"column":null}},"72":{"start":{"line":204,"column":6},"end":{"line":204,"column":null}},"73":{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},"74":{"start":{"line":207,"column":6},"end":{"line":207,"column":null}},"75":{"start":{"line":210,"column":2},"end":{"line":210,"column":null}},"76":{"start":{"line":214,"column":15},"end":{"line":214,"column":null}},"77":{"start":{"line":215,"column":17},"end":{"line":215,"column":null}},"78":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"79":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"80":{"start":{"line":219,"column":2},"end":{"line":219,"column":null}},"81":{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},"82":{"start":{"line":223,"column":2},"end":{"line":226,"column":null}},"83":{"start":{"line":224,"column":4},"end":{"line":224,"column":null}},"84":{"start":{"line":225,"column":4},"end":{"line":225,"column":null}}},"fnMap":{"0":{"name":"decodeXml","decl":{"start":{"line":51,"column":9},"end":{"line":51,"column":19}},"loc":{"start":{"line":51,"column":54},"end":{"line":53,"column":null}},"line":51},"1":{"name":"getTag","decl":{"start":{"line":55,"column":9},"end":{"line":55,"column":16}},"loc":{"start":{"line":55,"column":68},"end":{"line":58,"column":null}},"line":55},"2":{"name":"parseRssItems","decl":{"start":{"line":60,"column":16},"end":{"line":60,"column":30}},"loc":{"start":{"line":60,"column":54},"end":{"line":77,"column":null}},"line":60},"3":{"name":"dokIdMatchesHaystack","decl":{"start":{"line":79,"column":9},"end":{"line":79,"column":30}},"loc":{"start":{"line":79,"column":72},"end":{"line":85,"column":null}},"line":79},"4":{"name":"buildRssSignals","decl":{"start":{"line":87,"column":16},"end":{"line":87,"column":32}},"loc":{"start":{"line":87,"column":106},"end":{"line":98,"column":null}},"line":87},"5":{"name":"(anonymous_5)","decl":{"start":{"line":89,"column":5},"end":{"line":89,"column":10}},"loc":{"start":{"line":89,"column":20},"end":{"line":89,"column":46}},"line":89},"6":{"name":"(anonymous_6)","decl":{"start":{"line":92,"column":15},"end":{"line":92,"column":24}},"loc":{"start":{"line":92,"column":33},"end":{"line":97,"column":3}},"line":92},"7":{"name":"(anonymous_7)","decl":{"start":{"line":94,"column":40},"end":{"line":94,"column":48}},"loc":{"start":{"line":94,"column":58},"end":{"line":94,"column":95}},"line":94},"8":{"name":"watchRssFeed","decl":{"start":{"line":100,"column":22},"end":{"line":100,"column":null}},"loc":{"start":{"line":104,"column":27},"end":{"line":175,"column":null}},"line":104},"9":{"name":"(anonymous_9)","decl":{"start":{"line":107,"column":16},"end":{"line":107,"column":33}},"loc":{"start":{"line":107,"column":33},"end":{"line":107,"column":53}},"line":107},"10":{"name":"persistRssWatch","decl":{"start":{"line":177,"column":16},"end":{"line":177,"column":32}},"loc":{"start":{"line":177,"column":97},"end":{"line":181,"column":null}},"line":177},"11":{"name":"parseArgs","decl":{"start":{"line":183,"column":9},"end":{"line":183,"column":19}},"loc":{"start":{"line":183,"column":124},"end":{"line":211,"column":null}},"line":183},"12":{"name":"(anonymous_12)","decl":{"start":{"line":197,"column":38},"end":{"line":197,"column":43}},"loc":{"start":{"line":197,"column":53},"end":{"line":197,"column":65}},"line":197},"13":{"name":"main","decl":{"start":{"line":213,"column":15},"end":{"line":213,"column":37}},"loc":{"start":{"line":213,"column":37},"end":{"line":220,"column":null}},"line":213},"14":{"name":"(anonymous_14)","decl":{"start":{"line":223,"column":9},"end":{"line":223,"column":16}},"loc":{"start":{"line":223,"column":35},"end":{"line":226,"column":3}},"line":223}},"branchMap":{"0":{"loc":{"start":{"line":52,"column":29},"end":{"line":52,"column":40}},"type":"binary-expr","locations":[{"start":{"line":52,"column":29},"end":{"line":52,"column":38}},{"start":{"line":52,"column":38},"end":{"line":52,"column":40}}],"line":52},"1":{"loc":{"start":{"line":57,"column":9},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":22},"end":{"line":57,"column":44}},{"start":{"line":57,"column":44},"end":{"line":57,"column":null}}],"line":57},"2":{"loc":{"start":{"line":63,"column":18},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":18},"end":{"line":63,"column":30}},{"start":{"line":63,"column":30},"end":{"line":63,"column":null}}],"line":63},"3":{"loc":{"start":{"line":66,"column":17},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":17},"end":{"line":66,"column":42}},{"start":{"line":66,"column":42},"end":{"line":66,"column":null}}],"line":66},"4":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"5":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":34}},"type":"binary-expr","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":18}},{"start":{"line":67,"column":18},"end":{"line":67,"column":27}},{"start":{"line":67,"column":27},"end":{"line":67,"column":34}}],"line":67},"6":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"7":{"loc":{"start":{"line":93,"column":64},"end":{"line":93,"column":89}},"type":"binary-expr","locations":[{"start":{"line":93,"column":64},"end":{"line":93,"column":84}},{"start":{"line":93,"column":84},"end":{"line":93,"column":89}}],"line":93},"8":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"9":{"loc":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}},"type":"default-arg","locations":[{"start":{"line":101,"column":12},"end":{"line":101,"column":null}}],"line":101},"10":{"loc":{"start":{"line":102,"column":2},"end":{"line":102,"column":null}},"type":"default-arg","locations":[{"start":{"line":102,"column":37},"end":{"line":102,"column":null}}],"line":102},"11":{"loc":{"start":{"line":103,"column":2},"end":{"line":103,"column":null}},"type":"default-arg","locations":[{"start":{"line":103,"column":26},"end":{"line":103,"column":null}}],"line":103},"12":{"loc":{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":4},"end":{"line":128,"column":null}},{"start":{},"end":{}}],"line":116},"13":{"loc":{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":146,"column":null}},{"start":{},"end":{}}],"line":134},"14":{"loc":{"start":{"line":158,"column":13},"end":{"line":158,"column":null}},"type":"cond-expr","locations":[{"start":{"line":158,"column":40},"end":{"line":158,"column":113}},{"start":{"line":158,"column":113},"end":{"line":158,"column":null}}],"line":158},"15":{"loc":{"start":{"line":170,"column":13},"end":{"line":170,"column":null}},"type":"cond-expr","locations":[{"start":{"line":170,"column":38},"end":{"line":170,"column":54}},{"start":{"line":170,"column":54},"end":{"line":170,"column":null}}],"line":170},"16":{"loc":{"start":{"line":177,"column":56},"end":{"line":177,"column":97}},"type":"default-arg","locations":[{"start":{"line":177,"column":69},"end":{"line":177,"column":97}}],"line":177},"17":{"loc":{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},"type":"if","locations":[{"start":{"line":191,"column":4},"end":{"line":195,"column":null}},{"start":{},"end":{}}],"line":191},"18":{"loc":{"start":{"line":191,"column":8},"end":{"line":191,"column":40}},"type":"binary-expr","locations":[{"start":{"line":191,"column":8},"end":{"line":191,"column":34}},{"start":{"line":191,"column":34},"end":{"line":191,"column":40}}],"line":191},"19":{"loc":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"type":"if","locations":[{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},{"start":{},"end":{}}],"line":196},"20":{"loc":{"start":{"line":196,"column":8},"end":{"line":196,"column":39}},"type":"binary-expr","locations":[{"start":{"line":196,"column":8},"end":{"line":196,"column":33}},{"start":{"line":196,"column":33},"end":{"line":196,"column":39}}],"line":196},"21":{"loc":{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},"type":"if","locations":[{"start":{"line":201,"column":4},"end":{"line":205,"column":null}},{"start":{},"end":{}}],"line":201},"22":{"loc":{"start":{"line":201,"column":8},"end":{"line":201,"column":38}},"type":"binary-expr","locations":[{"start":{"line":201,"column":8},"end":{"line":201,"column":32}},{"start":{"line":201,"column":32},"end":{"line":201,"column":38}}],"line":201},"23":{"loc":{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":206,"column":4},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":206},"24":{"loc":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},{"start":{},"end":{}}],"line":216},"25":{"loc":{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":0},"end":{"line":227,"column":null}},{"start":{},"end":{}}],"line":222},"26":{"loc":{"start":{"line":222,"column":66},"end":{"line":222,"column":87}},"type":"binary-expr","locations":[{"start":{"line":222,"column":66},"end":{"line":222,"column":85}},{"start":{"line":222,"column":85},"end":{"line":222,"column":87}}],"line":222},"27":{"loc":{"start":{"line":224,"column":32},"end":{"line":224,"column":88}},"type":"cond-expr","locations":[{"start":{"line":224,"column":57},"end":{"line":224,"column":73}},{"start":{"line":224,"column":73},"end":{"line":224,"column":88}}],"line":224}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":10,"8":15,"9":15,"10":3,"11":3,"12":3,"13":3,"14":3,"15":3,"16":3,"17":0,"18":3,"19":3,"20":3,"21":3,"22":3,"23":3,"24":3,"25":0,"26":3,"27":3,"28":3,"29":3,"30":3,"31":1,"32":2,"33":1,"34":1,"35":1,"36":0,"37":1,"38":1,"39":1,"40":0,"41":1,"42":1,"43":0,"44":1,"45":1,"46":1,"47":0,"48":1,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":1,"82":0,"83":0,"84":0},"f":{"0":10,"1":15,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":1,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},"b":{"0":[10,0],"1":[10,5],"2":[3,0],"3":[3,0],"4":[0,3],"5":[3,3,3],"6":[0,3],"7":[3,2],"8":[1,2],"9":[1],"10":[1],"11":[1],"12":[0,1],"13":[0,1],"14":[1,0],"15":[0,0],"16":[0],"17":[0,0],"18":[0,0],"19":[0,0],"20":[0,0],"21":[0,0],"22":[0,0],"23":[0,0],"24":[0,0],"25":[0,1],"26":[1,0],"27":[0,0]},"meta":{"lastBranch":28,"lastFunction":15,"lastStatement":85,"seen":{"s:37:18:37:Infinity":0,"s:38:18:38:Infinity":1,"s:39:34:39:Infinity":2,"s:43:36:43:Infinity":3,"s:44:38:44:Infinity":4,"s:45:16:45:Infinity":5,"s:49:20:49:Infinity":6,"f:51:9:51:19":0,"s:52:2:52:Infinity":7,"b:52:29:52:38:52:38:52:40":0,"f:55:9:55:16":1,"s:56:16:56:Infinity":8,"s:57:2:57:Infinity":9,"b:57:22:57:44:57:44:57:Infinity":1,"f:60:16:60:30":2,"s:61:27:61:Infinity":10,"s:62:2:75:Infinity":11,"s:63:18:63:Infinity":12,"b:63:18:63:30:63:30:63:Infinity":2,"s:64:18:64:Infinity":13,"s:65:17:65:Infinity":14,"s:66:17:66:Infinity":15,"b:66:17:66:42:66:42:66:Infinity":3,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":4,"s:67:4:67:Infinity":16,"b:67:8:67:18:67:18:67:27:67:27:67:34":5,"s:67:34:67:Infinity":17,"s:68:4:74:Infinity":18,"s:76:2:76:Infinity":19,"f:79:9:79:30":3,"s:83:18:83:Infinity":20,"s:84:2:84:Infinity":21,"f:87:16:87:32":4,"s:88:24:90:Infinity":22,"f:89:5:89:10":5,"s:89:20:89:46":23,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":6,"s:91:2:91:Infinity":24,"s:91:34:91:Infinity":25,"s:92:2:97:Infinity":26,"f:92:15:92:24":6,"s:93:21:93:Infinity":27,"b:93:64:93:84:93:84:93:89":7,"s:94:26:94:Infinity":28,"f:94:40:94:48":7,"s:94:58:94:95":29,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":8,"s:95:4:95:Infinity":30,"s:95:36:95:Infinity":31,"s:96:4:96:Infinity":32,"f:100:22:100:Infinity":8,"b:101:12:101:Infinity":9,"b:102:37:102:Infinity":10,"b:103:26:103:Infinity":11,"s:105:20:105:Infinity":33,"s:106:21:106:Infinity":34,"s:107:16:107:Infinity":35,"f:107:16:107:33":9,"s:107:33:107:53":36,"s:108:2:174:Infinity":37,"s:109:21:115:Infinity":38,"b:116:4:128:Infinity:undefined:undefined:undefined:undefined":12,"s:116:4:128:Infinity":39,"s:117:6:127:Infinity":40,"s:129:16:129:Infinity":41,"b:134:4:146:Infinity:undefined:undefined:undefined:undefined":13,"s:134:4:146:Infinity":42,"s:135:6:145:Infinity":43,"s:147:18:147:Infinity":44,"s:148:20:148:Infinity":45,"s:149:4:159:Infinity":46,"b:158:40:158:113:158:113:158:Infinity":14,"s:161:4:171:Infinity":47,"b:170:38:170:54:170:54:170:Infinity":15,"s:173:4:173:Infinity":48,"f:177:16:177:32":10,"b:177:69:177:97":16,"s:178:2:178:Infinity":49,"s:179:2:179:Infinity":50,"s:180:2:180:Infinity":51,"f:183:9:183:19":11,"s:184:16:184:Infinity":52,"s:185:32:185:Infinity":53,"s:186:15:186:Infinity":54,"s:187:16:187:Infinity":55,"s:188:2:209:Infinity":56,"s:188:15:188:18":57,"s:189:18:189:Infinity":58,"s:190:17:190:Infinity":59,"b:191:4:195:Infinity:undefined:undefined:undefined:undefined":17,"s:191:4:195:Infinity":60,"b:191:8:191:34:191:34:191:40":18,"s:192:6:192:Infinity":61,"s:193:6:193:Infinity":62,"s:194:6:194:Infinity":63,"b:196:4:200:Infinity:undefined:undefined:undefined:undefined":19,"s:196:4:200:Infinity":64,"b:196:8:196:33:196:33:196:39":20,"s:197:6:197:Infinity":65,"f:197:38:197:43":12,"s:197:53:197:65":66,"s:198:6:198:Infinity":67,"s:199:6:199:Infinity":68,"b:201:4:205:Infinity:undefined:undefined:undefined:undefined":21,"s:201:4:205:Infinity":69,"b:201:8:201:32:201:32:201:38":22,"s:202:6:202:Infinity":70,"s:203:6:203:Infinity":71,"s:204:6:204:Infinity":72,"b:206:4:208:Infinity:undefined:undefined:undefined:undefined":23,"s:206:4:208:Infinity":73,"s:207:6:207:Infinity":74,"s:210:2:210:Infinity":75,"f:213:15:213:37":13,"s:214:15:214:Infinity":76,"s:215:17:215:Infinity":77,"b:216:2:218:Infinity:undefined:undefined:undefined:undefined":24,"s:216:2:218:Infinity":78,"s:217:4:217:Infinity":79,"s:219:2:219:Infinity":80,"b:222:0:227:Infinity:undefined:undefined:undefined:undefined":25,"s:222:0:227:Infinity":81,"b:222:66:222:85:222:85:222:87":26,"s:223:2:226:Infinity":82,"f:223:9:223:16":14,"s:224:4:224:Infinity":83,"b:224:57:224:73:224:73:224:88":27,"s:225:4:225:Infinity":84}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/article-meta.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/article-meta.ts","statementMap":{"0":{"start":{"line":35,"column":23},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":2},"end":{"line":59,"column":null}},"2":{"start":{"line":37,"column":20},"end":{"line":37,"column":null}},"3":{"start":{"line":38,"column":23},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":25},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":24},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":25},"end":{"line":42,"column":null}},"8":{"start":{"line":44,"column":4},"end":{"line":50,"column":null}},"9":{"start":{"line":52,"column":4},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"extractArticleMeta","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":66},"end":{"line":60,"column":null}},"line":34}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":13},"end":{"line":45,"column":null}},"type":"cond-expr","locations":[{"start":{"line":45,"column":26},"end":{"line":45,"column":50}},{"start":{"line":45,"column":50},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":31},"end":{"line":46,"column":54}},{"start":{"line":46,"column":54},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":15},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":30},"end":{"line":47,"column":56}},{"start":{"line":47,"column":56},"end":{"line":47,"column":null}}],"line":47},"3":{"loc":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":28},"end":{"line":48,"column":53}},{"start":{"line":48,"column":53},"end":{"line":48,"column":null}}],"line":48},"4":{"loc":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":31},"end":{"line":49,"column":57}},{"start":{"line":49,"column":57},"end":{"line":49,"column":null}}],"line":49}},"s":{"0":8141,"1":8141,"2":8141,"3":8141,"4":8141,"5":8141,"6":8141,"7":8141,"8":8141,"9":3},"f":{"0":8141},"b":{"0":[8138,0],"1":[8138,0],"2":[7966,172],"3":[8040,98],"4":[7954,184]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":10,"seen":{"f:34:16:34:35":0,"s:35:23:35:Infinity":0,"s:36:2:59:Infinity":1,"s:37:20:37:Infinity":2,"s:38:23:38:Infinity":3,"s:39:22:39:Infinity":4,"s:40:25:40:Infinity":5,"s:41:24:41:Infinity":6,"s:42:25:42:Infinity":7,"s:44:4:50:Infinity":8,"b:45:26:45:50:45:50:45:Infinity":0,"b:46:31:46:54:46:54:46:Infinity":1,"b:47:30:47:56:47:56:47:Infinity":2,"b:48:28:48:53:48:53:48:Infinity":3,"b:49:31:49:57:49:57:49:Infinity":4,"s:52:4:58:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/hreflang.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":24,"column":21},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"hreflangCode","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":29}},"loc":{"start":{"line":23,"column":51},"end":{"line":26,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":24}},"s":{"0":3434,"1":245,"2":3189},"f":{"0":3434},"b":{"0":[245,3189]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:23:16:23:29":0,"b:24:2:24:Infinity:undefined:undefined:undefined:undefined":0,"s:24:2:24:Infinity":0,"s:24:21:24:Infinity":1,"s:25:2:25:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/escape.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/escape.ts","statementMap":{"0":{"start":{"line":22,"column":2},"end":{"line":27,"column":null}}},"fnMap":{"0":{"name":"escapeXml","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":26}},"loc":{"start":{"line":21,"column":48},"end":{"line":28,"column":null}},"line":21}},"branchMap":{},"s":{"0":4981},"f":{"0":4981},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:21:16:21:26":0,"s:22:2:27:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/pub-date.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/pub-date.ts","statementMap":{"0":{"start":{"line":28,"column":19},"end":{"line":28,"column":null}},"1":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"2":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"4":{"start":{"line":33,"column":2},"end":{"line":37,"column":null}},"5":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"stablePubDate","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":30}},"loc":{"start":{"line":27,"column":56},"end":{"line":38,"column":null}},"line":27}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30}},"s":{"0":8145,"1":8145,"2":8145,"3":8073,"4":72,"5":72,"6":1},"f":{"0":8145},"b":{"0":[8073,72]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:27:16:27:30":0,"s:28:19:28:Infinity":0,"s:29:20:29:Infinity":1,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":0,"s:30:2:32:Infinity":2,"s:31:4:31:Infinity":3,"s:33:2:37:Infinity":4,"s:34:4:34:Infinity":5,"s:36:4:36:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/render/feed.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/render/feed.ts","statementMap":{"0":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"1":{"start":{"line":34,"column":12},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},"4":{"start":{"line":54,"column":4},"end":{"line":60,"column":null}},"5":{"start":{"line":63,"column":15},"end":{"line":63,"column":null}},"6":{"start":{"line":64,"column":12},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":2},"end":{"line":70,"column":null}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"9":{"start":{"line":81,"column":18},"end":{"line":81,"column":null}},"10":{"start":{"line":82,"column":19},"end":{"line":82,"column":null}},"11":{"start":{"line":83,"column":14},"end":{"line":83,"column":null}},"12":{"start":{"line":85,"column":24},"end":{"line":87,"column":null}},"13":{"start":{"line":89,"column":12},"end":{"line":115,"column":null}},"14":{"start":{"line":117,"column":28},"end":{"line":120,"column":null}},"15":{"start":{"line":121,"column":2},"end":{"line":124,"column":null}},"16":{"start":{"line":122,"column":4},"end":{"line":123,"column":null}},"17":{"start":{"line":126,"column":2},"end":{"line":151,"column":null}},"18":{"start":{"line":127,"column":22},"end":{"line":127,"column":null}},"19":{"start":{"line":128,"column":22},"end":{"line":128,"column":null}},"20":{"start":{"line":129,"column":26},"end":{"line":131,"column":null}},"21":{"start":{"line":133,"column":4},"end":{"line":142,"column":null}},"22":{"start":{"line":144,"column":4},"end":{"line":147,"column":null}},"23":{"start":{"line":145,"column":6},"end":{"line":146,"column":null}},"24":{"start":{"line":149,"column":4},"end":{"line":149,"column":null}},"25":{"start":{"line":153,"column":2},"end":{"line":153,"column":null}},"26":{"start":{"line":157,"column":2},"end":{"line":157,"column":null}}},"fnMap":{"0":{"name":"subfolderFromBaseSlug","decl":{"start":{"line":33,"column":9},"end":{"line":33,"column":31}},"loc":{"start":{"line":33,"column":64},"end":{"line":36,"column":null}},"line":33},"1":{"name":"channelStrings","decl":{"start":{"line":52,"column":9},"end":{"line":52,"column":24}},"loc":{"start":{"line":52,"column":60},"end":{"line":71,"column":null}},"line":52},"2":{"name":"generateRss","decl":{"start":{"line":78,"column":16},"end":{"line":78,"column":28}},"loc":{"start":{"line":78,"column":63},"end":{"line":158,"column":null}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":9},"end":{"line":35,"column":null}},"type":"cond-expr","locations":[{"start":{"line":35,"column":13},"end":{"line":35,"column":21}},{"start":{"line":35,"column":21},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":78,"column":28},"end":{"line":78,"column":63}},"type":"default-arg","locations":[{"start":{"line":78,"column":49},"end":{"line":78,"column":63}}],"line":78},"3":{"loc":{"start":{"line":85,"column":24},"end":{"line":87,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":6},"end":{"line":86,"column":null}},{"start":{"line":87,"column":6},"end":{"line":87,"column":null}}],"line":85},"4":{"loc":{"start":{"line":102,"column":27},"end":{"line":102,"column":140}},"type":"cond-expr","locations":[{"start":{"line":102,"column":49},"end":{"line":102,"column":99}},{"start":{"line":102,"column":99},"end":{"line":102,"column":140}}],"line":102},"5":{"loc":{"start":{"line":128,"column":22},"end":{"line":128,"column":null}},"type":"cond-expr","locations":[{"start":{"line":128,"column":34},"end":{"line":128,"column":62}},{"start":{"line":128,"column":62},"end":{"line":128,"column":null}}],"line":128},"6":{"loc":{"start":{"line":129,"column":26},"end":{"line":131,"column":null}},"type":"cond-expr","locations":[{"start":{"line":130,"column":8},"end":{"line":130,"column":null}},{"start":{"line":131,"column":8},"end":{"line":131,"column":null}}],"line":129}},"s":{"0":1,"1":250,"2":250,"3":5,"4":1,"5":4,"6":4,"7":4,"8":5,"9":5,"10":5,"11":5,"12":5,"13":5,"14":5,"15":5,"16":30,"17":5,"18":250,"19":250,"20":250,"21":250,"22":250,"23":3178,"24":250,"25":5,"26":5},"f":{"0":250,"1":5,"2":5},"b":{"0":[244,6],"1":[1,4],"2":[5],"3":[5,0],"4":[5,0],"5":[244,6],"6":[214,36]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":27,"seen":{"s:27:17:27:Infinity":0,"f:33:9:33:31":0,"s:34:12:34:Infinity":1,"s:35:2:35:Infinity":2,"b:35:13:35:21:35:21:35:Infinity":0,"f:52:9:52:24":1,"b:53:2:61:Infinity:undefined:undefined:undefined:undefined":1,"s:53:2:61:Infinity":3,"s:54:4:60:Infinity":4,"s:63:15:63:Infinity":5,"s:64:12:64:Infinity":6,"s:65:2:70:Infinity":7,"f:78:16:78:28":2,"b:78:49:78:63":2,"s:79:2:79:Infinity":8,"s:81:18:81:Infinity":9,"s:82:19:82:Infinity":10,"s:83:14:83:Infinity":11,"s:85:24:87:Infinity":12,"b:86:6:86:Infinity:87:6:87:Infinity":3,"s:89:12:115:Infinity":13,"b:102:49:102:99:102:99:102:140":4,"s:117:28:120:Infinity":14,"s:121:2:124:Infinity":15,"s:122:4:123:Infinity":16,"s:126:2:151:Infinity":17,"s:127:22:127:Infinity":18,"s:128:22:128:Infinity":19,"b:128:34:128:62:128:62:128:Infinity":5,"s:129:26:131:Infinity":20,"b:130:8:130:Infinity:131:8:131:Infinity":6,"s:133:4:142:Infinity":21,"s:144:4:147:Infinity":22,"s:145:6:146:Infinity":23,"s:149:4:149:Infinity":24,"s:153:2:153:Infinity":25,"s:157:2:157:Infinity":26}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/scanner.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/scanner.ts","statementMap":{"0":{"start":{"line":30,"column":19},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":18},"end":{"line":31,"column":null}},"2":{"start":{"line":33,"column":17},"end":{"line":33,"column":null}},"3":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":18},"end":{"line":35,"column":null}},"5":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"6":{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},"7":{"start":{"line":68,"column":4},"end":{"line":68,"column":null}},"8":{"start":{"line":69,"column":4},"end":{"line":69,"column":null}},"9":{"start":{"line":72,"column":16},"end":{"line":74,"column":null}},"10":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"11":{"start":{"line":76,"column":24},"end":{"line":76,"column":null}},"12":{"start":{"line":77,"column":2},"end":{"line":87,"column":null}},"13":{"start":{"line":78,"column":18},"end":{"line":78,"column":null}},"14":{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":80,"column":23},"end":{"line":80,"column":null}},"16":{"start":{"line":81,"column":19},"end":{"line":81,"column":null}},"17":{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},"18":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"19":{"start":{"line":85,"column":6},"end":{"line":85,"column":null}},"20":{"start":{"line":89,"column":33},"end":{"line":89,"column":null}},"21":{"start":{"line":91,"column":2},"end":{"line":122,"column":null}},"22":{"start":{"line":92,"column":24},"end":{"line":92,"column":null}},"23":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"24":{"start":{"line":95,"column":22},"end":{"line":95,"column":null}},"25":{"start":{"line":97,"column":21},"end":{"line":97,"column":null}},"26":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"27":{"start":{"line":100,"column":64},"end":{"line":100,"column":null}},"28":{"start":{"line":101,"column":4},"end":{"line":108,"column":null}},"29":{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},"30":{"start":{"line":103,"column":8},"end":{"line":106,"column":null}},"31":{"start":{"line":110,"column":4},"end":{"line":121,"column":null}},"32":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"33":{"start":{"line":124,"column":26},"end":{"line":124,"column":87}},"34":{"start":{"line":126,"column":2},"end":{"line":126,"column":null}},"35":{"start":{"line":128,"column":2},"end":{"line":128,"column":null}}},"fnMap":{"0":{"name":"getRssArticles","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":31}},"loc":{"start":{"line":64,"column":72},"end":{"line":129,"column":null}},"line":64},"1":{"name":"(anonymous_1)","decl":{"start":{"line":74,"column":5},"end":{"line":74,"column":13}},"loc":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"line":74},"2":{"name":"(anonymous_2)","decl":{"start":{"line":124,"column":11},"end":{"line":124,"column":17}},"loc":{"start":{"line":124,"column":26},"end":{"line":124,"column":87}},"line":124}},"branchMap":{"0":{"loc":{"start":{"line":64,"column":31},"end":{"line":64,"column":72}},"type":"default-arg","locations":[{"start":{"line":64,"column":52},"end":{"line":64,"column":72}}],"line":64},"1":{"loc":{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":2},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":67},"2":{"loc":{"start":{"line":74,"column":22},"end":{"line":74,"column":99}},"type":"binary-expr","locations":[{"start":{"line":74,"column":22},"end":{"line":74,"column":48}},{"start":{"line":74,"column":48},"end":{"line":74,"column":73}},{"start":{"line":74,"column":73},"end":{"line":74,"column":99}}],"line":74},"3":{"loc":{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":79},"4":{"loc":{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":6},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":82},"5":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"6":{"loc":{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":6},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":102}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":16,"6":16,"7":0,"8":0,"9":16,"10":97456,"11":16,"12":16,"13":97392,"14":97392,"15":97360,"16":97360,"17":97360,"18":8384,"19":97360,"20":16,"21":16,"22":8384,"23":8384,"24":246,"25":8138,"26":8138,"27":8138,"28":8138,"29":96441,"30":88303,"31":8138,"32":16,"33":37006,"34":16,"35":16},"f":{"0":16,"1":97456,"2":37006},"b":{"0":[16],"1":[0,16],"2":[97456,97392,97392],"3":[97360,32],"4":[8384,88976],"5":[246,8138],"6":[88303,8138]},"meta":{"lastBranch":7,"lastFunction":3,"lastStatement":36,"seen":{"s:30:19:30:Infinity":0,"s:31:18:31:Infinity":1,"s:33:17:33:Infinity":2,"s:34:17:34:Infinity":3,"s:35:18:35:Infinity":4,"f:64:16:64:31":0,"b:64:52:64:72":0,"s:65:2:65:Infinity":5,"b:67:2:70:Infinity:undefined:undefined:undefined:undefined":1,"s:67:2:70:Infinity":6,"s:68:4:68:Infinity":7,"s:69:4:69:Infinity":8,"s:72:16:74:Infinity":9,"f:74:5:74:13":1,"s:74:22:74:99":10,"b:74:22:74:48:74:48:74:73:74:73:74:99":2,"s:76:24:76:Infinity":11,"s:77:2:87:Infinity":12,"s:78:18:78:Infinity":13,"b:79:4:86:Infinity:undefined:undefined:undefined:undefined":3,"s:79:4:86:Infinity":14,"s:80:23:80:Infinity":15,"s:81:19:81:Infinity":16,"b:82:6:84:Infinity:undefined:undefined:undefined:undefined":4,"s:82:6:84:Infinity":17,"s:83:8:83:Infinity":18,"s:85:6:85:Infinity":19,"s:89:33:89:Infinity":20,"s:91:2:122:Infinity":21,"s:92:24:92:Infinity":22,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":5,"s:95:4:95:Infinity":23,"s:95:22:95:Infinity":24,"s:97:21:97:Infinity":25,"s:98:17:98:Infinity":26,"s:100:64:100:Infinity":27,"s:101:4:108:Infinity":28,"b:102:6:107:Infinity:undefined:undefined:undefined:undefined":6,"s:102:6:107:Infinity":29,"s:103:8:106:Infinity":30,"s:110:4:121:Infinity":31,"s:124:2:124:Infinity":32,"f:124:11:124:17":2,"s:124:26:124:87":33,"s:126:2:126:Infinity":34,"s:128:2:128:Infinity":35}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/rss/validator.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"6":{"start":{"line":35,"column":4},"end":{"line":35,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"9":{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},"10":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"11":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"12":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"13":{"start":{"line":50,"column":8},"end":{"line":50,"column":null}},"14":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"15":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"16":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"17":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"18":{"start":{"line":58,"column":8},"end":{"line":58,"column":null}},"19":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"20":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"21":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"22":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"23":{"start":{"line":66,"column":4},"end":{"line":66,"column":null}},"24":{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},"25":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"26":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"27":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}}},"fnMap":{"0":{"name":"validateRss","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":28}},"loc":{"start":{"line":23,"column":50},"end":{"line":75,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":26},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"2":{"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":null}},{"start":{},"end":{}}],"line":34},"3":{"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":38},"4":{"loc":{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":42},"5":{"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":null}},{"start":{},"end":{}}],"line":46},"6":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":47}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":45}},{"start":{"line":50,"column":45},"end":{"line":50,"column":47}}],"line":50},"7":{"loc":{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":57,"column":22},"end":{"line":57,"column":63}},"type":"binary-expr","locations":[{"start":{"line":57,"column":22},"end":{"line":57,"column":61}},{"start":{"line":57,"column":61},"end":{"line":57,"column":63}}],"line":57},"9":{"loc":{"start":{"line":58,"column":21},"end":{"line":58,"column":61}},"type":"binary-expr","locations":[{"start":{"line":58,"column":21},"end":{"line":58,"column":59}},{"start":{"line":58,"column":59},"end":{"line":58,"column":61}}],"line":58},"10":{"loc":{"start":{"line":59,"column":21},"end":{"line":59,"column":46}},"type":"binary-expr","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":44}},{"start":{"line":59,"column":44},"end":{"line":59,"column":46}}],"line":59},"11":{"loc":{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":61},"12":{"loc":{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":65},"13":{"loc":{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":69}},"s":{"0":13,"1":13,"2":2,"3":11,"4":2,"5":9,"6":2,"7":7,"8":0,"9":7,"10":0,"11":7,"12":0,"13":7,"14":13,"15":13,"16":2,"17":5,"18":13,"19":13,"20":13,"21":0,"22":5,"23":0,"24":5,"25":1,"26":4,"27":4},"f":{"0":13},"b":{"0":[2,11],"1":[2,9],"2":[2,7],"3":[0,7],"4":[0,7],"5":[0,7],"6":[7,2],"7":[2,11],"8":[5,0],"9":[13,0],"10":[13,1],"11":[0,13],"12":[0,5],"13":[1,4]},"meta":{"lastBranch":14,"lastFunction":1,"lastStatement":28,"seen":{"f:23:16:23:28":0,"s:24:2:24:Infinity":0,"b:26:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:26:2:28:Infinity":1,"s:27:4:27:Infinity":2,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":1,"s:30:2:32:Infinity":3,"s:31:4:31:Infinity":4,"b:34:2:36:Infinity:undefined:undefined:undefined:undefined":2,"s:34:2:36:Infinity":5,"s:35:4:35:Infinity":6,"b:38:2:40:Infinity:undefined:undefined:undefined:undefined":3,"s:38:2:40:Infinity":7,"s:39:4:39:Infinity":8,"b:42:2:44:Infinity:undefined:undefined:undefined:undefined":4,"s:42:2:44:Infinity":9,"s:43:4:43:Infinity":10,"b:46:2:48:Infinity:undefined:undefined:undefined:undefined":5,"s:46:2:48:Infinity":11,"s:47:4:47:Infinity":12,"s:50:8:50:Infinity":13,"b:50:21:50:45:50:45:50:47":6,"s:51:2:51:Infinity":14,"b:53:2:55:Infinity:undefined:undefined:undefined:undefined":7,"s:53:2:55:Infinity":15,"s:54:4:54:Infinity":16,"s:57:8:57:Infinity":17,"b:57:22:57:61:57:61:57:63":8,"s:58:8:58:Infinity":18,"b:58:21:58:59:58:59:58:61":9,"s:59:8:59:Infinity":19,"b:59:21:59:44:59:44:59:46":10,"b:61:2:63:Infinity:undefined:undefined:undefined:undefined":11,"s:61:2:63:Infinity":20,"s:62:4:62:Infinity":21,"b:65:2:67:Infinity:undefined:undefined:undefined:undefined":12,"s:65:2:67:Infinity":22,"s:66:4:66:Infinity":23,"b:69:2:71:Infinity:undefined:undefined:undefined:undefined":13,"s:69:2:71:Infinity":24,"s:70:4:70:Infinity":25,"s:73:2:73:Infinity":26,"s:74:2:74:Infinity":27}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/scb-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/scb-context.ts","statementMap":{"0":{"start":{"line":54,"column":70},"end":{"line":175,"column":null}},"1":{"start":{"line":185,"column":84},"end":{"line":256,"column":null}},"2":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"3":{"start":{"line":274,"column":2},"end":{"line":274,"column":null}},"4":{"start":{"line":284,"column":12},"end":{"line":284,"column":null}},"5":{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},"6":{"start":{"line":286,"column":4},"end":{"line":286,"column":null}},"7":{"start":{"line":288,"column":2},"end":{"line":294,"column":null}},"8":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"9":{"start":{"line":293,"column":35},"end":{"line":293,"column":64}},"10":{"start":{"line":304,"column":12},"end":{"line":304,"column":null}},"11":{"start":{"line":305,"column":2},"end":{"line":313,"column":null}},"12":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"13":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"14":{"start":{"line":311,"column":40},"end":{"line":311,"column":64}},"15":{"start":{"line":324,"column":15},"end":{"line":324,"column":null}},"16":{"start":{"line":325,"column":38},"end":{"line":340,"column":null}},"17":{"start":{"line":342,"column":2},"end":{"line":342,"column":null}},"18":{"start":{"line":342,"column":36},"end":{"line":342,"column":54}},"19":{"start":{"line":352,"column":2},"end":{"line":358,"column":null}},"20":{"start":{"line":353,"column":19},"end":{"line":353,"column":38}},"21":{"start":{"line":354,"column":17},"end":{"line":358,"column":6}}},"fnMap":{"0":{"name":"getSCBHeading","decl":{"start":{"line":269,"column":16},"end":{"line":269,"column":null}},"loc":{"start":{"line":272,"column":10},"end":{"line":275,"column":null}},"line":272},"1":{"name":"findRelevantSCBIndicators","decl":{"start":{"line":283,"column":16},"end":{"line":283,"column":42}},"loc":{"start":{"line":283,"column":89},"end":{"line":295,"column":null}},"line":283},"2":{"name":"(anonymous_2)","decl":{"start":{"line":288,"column":32},"end":{"line":288,"column":null}},"loc":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"line":290},"3":{"name":"(anonymous_3)","decl":{"start":{"line":293,"column":21},"end":{"line":293,"column":27}},"loc":{"start":{"line":293,"column":35},"end":{"line":293,"column":64}},"line":293},"4":{"name":"getSCBTablesForCommittee","decl":{"start":{"line":303,"column":16},"end":{"line":303,"column":41}},"loc":{"start":{"line":303,"column":88},"end":{"line":314,"column":null}},"line":303},"5":{"name":"(anonymous_5)","decl":{"start":{"line":305,"column":21},"end":{"line":305,"column":null}},"loc":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"line":307},"6":{"name":"(anonymous_6)","decl":{"start":{"line":308,"column":29},"end":{"line":308,"column":null}},"loc":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"line":310},"7":{"name":"(anonymous_7)","decl":{"start":{"line":311,"column":25},"end":{"line":311,"column":31}},"loc":{"start":{"line":311,"column":40},"end":{"line":311,"column":64}},"line":311},"8":{"name":"hasSCBContext","decl":{"start":{"line":323,"column":16},"end":{"line":323,"column":30}},"loc":{"start":{"line":323,"column":56},"end":{"line":343,"column":null}},"line":323},"9":{"name":"(anonymous_9)","decl":{"start":{"line":342,"column":18},"end":{"line":342,"column":24}},"loc":{"start":{"line":342,"column":36},"end":{"line":342,"column":54}},"line":342},"10":{"name":"getSCBQueryParams","decl":{"start":{"line":351,"column":16},"end":{"line":351,"column":111}},"loc":{"start":{"line":351,"column":111},"end":{"line":359,"column":null}},"line":351},"11":{"name":"(anonymous_11)","decl":{"start":{"line":353,"column":5},"end":{"line":353,"column":13}},"loc":{"start":{"line":353,"column":19},"end":{"line":353,"column":38}},"line":353},"12":{"name":"(anonymous_12)","decl":{"start":{"line":354,"column":5},"end":{"line":354,"column":10}},"loc":{"start":{"line":354,"column":17},"end":{"line":358,"column":6}},"line":354}},"branchMap":{"0":{"loc":{"start":{"line":273,"column":19},"end":{"line":273,"column":null}},"type":"binary-expr","locations":[{"start":{"line":273,"column":19},"end":{"line":273,"column":61}},{"start":{"line":273,"column":61},"end":{"line":273,"column":null}}],"line":273},"1":{"loc":{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},"type":"if","locations":[{"start":{"line":285,"column":2},"end":{"line":287,"column":null}},{"start":{},"end":{}}],"line":285},"2":{"loc":{"start":{"line":290,"column":6},"end":{"line":293,"column":null}},"type":"binary-expr","locations":[{"start":{"line":290,"column":6},"end":{"line":290,"column":null}},{"start":{"line":291,"column":6},"end":{"line":291,"column":null}},{"start":{"line":292,"column":6},"end":{"line":292,"column":null}},{"start":{"line":293,"column":6},"end":{"line":293,"column":null}}],"line":290},"3":{"loc":{"start":{"line":307,"column":6},"end":{"line":312,"column":null}},"type":"binary-expr","locations":[{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},{"start":{"line":308,"column":6},"end":{"line":312,"column":null}}],"line":307},"4":{"loc":{"start":{"line":310,"column":10},"end":{"line":311,"column":null}},"type":"binary-expr","locations":[{"start":{"line":310,"column":10},"end":{"line":310,"column":null}},{"start":{"line":311,"column":10},"end":{"line":311,"column":null}}],"line":310}},"s":{"0":1,"1":1,"2":4,"3":4,"4":7,"5":7,"6":2,"7":5,"8":75,"9":167,"10":7,"11":7,"12":105,"13":1089,"14":94,"15":8,"16":8,"17":8,"18":58,"19":4,"20":60,"21":44},"f":{"0":4,"1":7,"2":75,"3":167,"4":7,"5":105,"6":1089,"7":94,"8":8,"9":58,"10":4,"11":60,"12":44},"b":{"0":[4,1],"1":[2,5],"2":[75,73,73,72],"3":[105,77],"4":[1089,77]},"meta":{"lastBranch":5,"lastFunction":13,"lastStatement":22,"seen":{"s:54:70:175:Infinity":0,"s:185:84:256:Infinity":1,"f:269:16:269:Infinity":0,"s:273:19:273:Infinity":2,"b:273:19:273:61:273:61:273:Infinity":0,"s:274:2:274:Infinity":3,"f:283:16:283:42":1,"s:284:12:284:Infinity":4,"b:285:2:287:Infinity:undefined:undefined:undefined:undefined":1,"s:285:2:287:Infinity":5,"s:286:4:286:Infinity":6,"s:288:2:294:Infinity":7,"f:288:32:288:Infinity":2,"s:290:6:293:Infinity":8,"b:290:6:290:Infinity:291:6:291:Infinity:292:6:292:Infinity:293:6:293:Infinity":2,"f:293:21:293:27":3,"s:293:35:293:64":9,"f:303:16:303:41":4,"s:304:12:304:Infinity":10,"s:305:2:313:Infinity":11,"f:305:21:305:Infinity":5,"s:307:6:312:Infinity":12,"b:307:6:307:Infinity:308:6:312:Infinity":3,"f:308:29:308:Infinity":6,"s:310:10:311:Infinity":13,"b:310:10:310:Infinity:311:10:311:Infinity":4,"f:311:25:311:31":7,"s:311:40:311:64":14,"f:323:16:323:30":8,"s:324:15:324:Infinity":15,"s:325:38:340:Infinity":16,"s:342:2:342:Infinity":17,"f:342:18:342:24":9,"s:342:36:342:54":18,"f:351:16:351:111":10,"s:352:2:358:Infinity":19,"f:353:5:353:13":11,"s:353:19:353:38":20,"f:354:5:354:10":12,"s:354:17:358:6":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/shared/theme-init.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/shared/theme-init.ts","statementMap":{"0":{"start":{"line":21,"column":19},"end":{"line":21,"column":null}},"1":{"start":{"line":22,"column":18},"end":{"line":22,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":43,"column":null}},"3":{"start":{"line":47,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"5":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"6":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"7":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"8":{"start":{"line":60,"column":41},"end":{"line":60,"column":null}},"9":{"start":{"line":70,"column":45},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"minifyBootstrap","decl":{"start":{"line":33,"column":9},"end":{"line":33,"column":25}},"loc":{"start":{"line":33,"column":46},"end":{"line":44,"column":null}},"line":33},"1":{"name":"loadBootstrap","decl":{"start":{"line":46,"column":9},"end":{"line":46,"column":33}},"loc":{"start":{"line":46,"column":33},"end":{"line":54,"column":null}},"line":46}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":0,"8":1,"9":1},"f":{"0":1,"1":1},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":10,"seen":{"s:21:19:21:Infinity":0,"s:22:18:22:Infinity":1,"f:33:9:33:25":0,"s:34:2:43:Infinity":2,"f:46:9:46:33":1,"s:47:2:53:Infinity":3,"s:48:17:48:Infinity":4,"s:49:16:49:Infinity":5,"s:50:4:50:Infinity":6,"s:52:4:52:Infinity":7,"s:60:41:60:Infinity":8,"s:70:45:70:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/escape.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/escape.ts","statementMap":{"0":{"start":{"line":22,"column":2},"end":{"line":28,"column":null}}},"fnMap":{"0":{"name":"escapeHtml","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":27}},"loc":{"start":{"line":21,"column":49},"end":{"line":29,"column":null}},"line":21}},"branchMap":{},"s":{"0":970326},"f":{"0":970326},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":1,"seen":{"f:21:16:21:27":0,"s:22:2:28:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/scanner.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/scanner.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"5":{"start":{"line":63,"column":2},"end":{"line":96,"column":null}},"6":{"start":{"line":64,"column":20},"end":{"line":64,"column":null}},"7":{"start":{"line":65,"column":25},"end":{"line":65,"column":null}},"8":{"start":{"line":66,"column":23},"end":{"line":66,"column":null}},"9":{"start":{"line":67,"column":24},"end":{"line":67,"column":null}},"10":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"11":{"start":{"line":69,"column":10},"end":{"line":80,"column":null}},"12":{"start":{"line":70,"column":6},"end":{"line":79,"column":null}},"13":{"start":{"line":71,"column":18},"end":{"line":71,"column":null}},"14":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"15":{"start":{"line":72,"column":16},"end":{"line":72,"column":null}},"16":{"start":{"line":73,"column":23},"end":{"line":73,"column":null}},"17":{"start":{"line":74,"column":8},"end":{"line":76,"column":null}},"18":{"start":{"line":78,"column":8},"end":{"line":78,"column":null}},"19":{"start":{"line":82,"column":23},"end":{"line":84,"column":null}},"20":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"21":{"start":{"line":84,"column":22},"end":{"line":84,"column":41}},"22":{"start":{"line":85,"column":24},"end":{"line":85,"column":null}},"23":{"start":{"line":87,"column":10},"end":{"line":87,"column":null}},"24":{"start":{"line":88,"column":18},"end":{"line":88,"column":null}},"25":{"start":{"line":90,"column":4},"end":{"line":93,"column":null}},"26":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"27":{"start":{"line":109,"column":25},"end":{"line":109,"column":null}},"28":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},"29":{"start":{"line":111,"column":32},"end":{"line":111,"column":null}},"30":{"start":{"line":114,"column":20},"end":{"line":114,"column":null}},"31":{"start":{"line":115,"column":4},"end":{"line":148,"column":null}},"32":{"start":{"line":116,"column":23},"end":{"line":116,"column":null}},"33":{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},"34":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"35":{"start":{"line":118,"column":69},"end":{"line":118,"column":null}},"36":{"start":{"line":119,"column":8},"end":{"line":119,"column":null}},"37":{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},"38":{"start":{"line":126,"column":22},"end":{"line":126,"column":null}},"39":{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},"40":{"start":{"line":127,"column":20},"end":{"line":127,"column":null}},"41":{"start":{"line":129,"column":25},"end":{"line":129,"column":null}},"42":{"start":{"line":130,"column":21},"end":{"line":130,"column":null}},"43":{"start":{"line":131,"column":21},"end":{"line":131,"column":null}},"44":{"start":{"line":133,"column":23},"end":{"line":133,"column":null}},"45":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"46":{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},"47":{"start":{"line":137,"column":10},"end":{"line":137,"column":null}},"48":{"start":{"line":139,"column":8},"end":{"line":146,"column":null}},"49":{"start":{"line":151,"column":2},"end":{"line":151,"column":null}},"50":{"start":{"line":153,"column":2},"end":{"line":158,"column":null}},"51":{"start":{"line":154,"column":4},"end":{"line":157,"column":null}},"52":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"53":{"start":{"line":155,"column":29},"end":{"line":155,"column":null}},"54":{"start":{"line":156,"column":6},"end":{"line":156,"column":null}},"55":{"start":{"line":160,"column":2},"end":{"line":160,"column":null}}},"fnMap":{"0":{"name":"extractArticleDate","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":35}},"loc":{"start":{"line":44,"column":61},"end":{"line":47,"column":null}},"line":44},"1":{"name":"extractArticleMeta","decl":{"start":{"line":62,"column":16},"end":{"line":62,"column":35}},"loc":{"start":{"line":62,"column":93},"end":{"line":97,"column":null}},"line":62},"2":{"name":"(anonymous_2)","decl":{"start":{"line":69,"column":10},"end":{"line":69,"column":30}},"loc":{"start":{"line":69,"column":30},"end":{"line":80,"column":5}},"line":69},"3":{"name":"(anonymous_3)","decl":{"start":{"line":83,"column":7},"end":{"line":83,"column":15}},"loc":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"line":83},"4":{"name":"(anonymous_4)","decl":{"start":{"line":84,"column":7},"end":{"line":84,"column":13}},"loc":{"start":{"line":84,"column":22},"end":{"line":84,"column":41}},"line":84},"5":{"name":"getArticlesByLanguage","decl":{"start":{"line":108,"column":16},"end":{"line":108,"column":70}},"loc":{"start":{"line":108,"column":70},"end":{"line":161,"column":null}},"line":108},"6":{"name":"scanDir","decl":{"start":{"line":113,"column":11},"end":{"line":113,"column":19}},"loc":{"start":{"line":113,"column":38},"end":{"line":149,"column":null}},"line":113},"7":{"name":"(anonymous_7)","decl":{"start":{"line":154,"column":9},"end":{"line":154,"column":15}},"loc":{"start":{"line":154,"column":24},"end":{"line":157,"column":5}},"line":154}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":17},"end":{"line":46,"column":29}},{"start":{"line":46,"column":29},"end":{"line":46,"column":null}}],"line":46},"1":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"2":{"loc":{"start":{"line":74,"column":15},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":75,"column":12},"end":{"line":75,"column":null}},{"start":{"line":76,"column":12},"end":{"line":76,"column":null}}],"line":74},"3":{"loc":{"start":{"line":74,"column":15},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":15},"end":{"line":74,"column":57}},{"start":{"line":74,"column":57},"end":{"line":74,"column":null}}],"line":74},"4":{"loc":{"start":{"line":83,"column":34},"end":{"line":83,"column":53}},"type":"binary-expr","locations":[{"start":{"line":83,"column":34},"end":{"line":83,"column":41}},{"start":{"line":83,"column":41},"end":{"line":83,"column":53}}],"line":83},"5":{"loc":{"start":{"line":85,"column":24},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":24},"end":{"line":85,"column":41}},{"start":{"line":85,"column":41},"end":{"line":85,"column":null}}],"line":85},"6":{"loc":{"start":{"line":87,"column":22},"end":{"line":87,"column":64}},"type":"binary-expr","locations":[{"start":{"line":87,"column":22},"end":{"line":87,"column":43}},{"start":{"line":87,"column":43},"end":{"line":87,"column":62}},{"start":{"line":87,"column":62},"end":{"line":87,"column":64}}],"line":87},"7":{"loc":{"start":{"line":91,"column":13},"end":{"line":91,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":32},"end":{"line":91,"column":40}},{"start":{"line":91,"column":40},"end":{"line":91,"column":null}}],"line":91},"8":{"loc":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":2},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":111},"9":{"loc":{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":6},"end":{"line":147,"column":null}},{"start":{"line":120,"column":13},"end":{"line":147,"column":null}}],"line":117},"10":{"loc":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},{"start":{},"end":{}}],"line":118},"11":{"loc":{"start":{"line":118,"column":12},"end":{"line":118,"column":69}},"type":"binary-expr","locations":[{"start":{"line":118,"column":12},"end":{"line":118,"column":41}},{"start":{"line":118,"column":41},"end":{"line":118,"column":69}}],"line":118},"12":{"loc":{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":13},"end":{"line":147,"column":null}},{"start":{},"end":{}}],"line":120},"13":{"loc":{"start":{"line":121,"column":8},"end":{"line":124,"column":null}},"type":"binary-expr","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},{"start":{"line":122,"column":8},"end":{"line":122,"column":null}},{"start":{"line":123,"column":8},"end":{"line":123,"column":null}},{"start":{"line":124,"column":8},"end":{"line":124,"column":null}}],"line":121},"14":{"loc":{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":null}},{"start":{},"end":{}}],"line":127},"15":{"loc":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"type":"cond-expr","locations":[{"start":{"line":134,"column":34},"end":{"line":134,"column":62}},{"start":{"line":134,"column":62},"end":{"line":134,"column":null}}],"line":134},"16":{"loc":{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":136,"column":8},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":136},"17":{"loc":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"type":"if","locations":[{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},{"start":{},"end":{}}],"line":155}},"s":{"0":30,"1":30,"2":30,"3":158210,"4":158210,"5":158210,"6":158210,"7":158210,"8":158210,"9":158210,"10":158210,"11":158210,"12":158210,"13":158210,"14":158210,"15":78,"16":158132,"17":158132,"18":598,"19":158210,"20":474630,"21":316732,"22":158210,"23":158210,"24":158210,"25":158210,"26":0,"27":26,"28":26,"29":0,"30":156,"31":156,"32":159172,"33":159172,"34":156,"35":26,"36":130,"37":159016,"38":158262,"39":158262,"40":52,"41":158210,"42":158210,"43":158210,"44":158210,"45":158210,"46":158262,"47":364,"48":158210,"49":26,"50":26,"51":364,"52":159458,"53":36088,"54":123370,"55":26},"f":{"0":158210,"1":158210,"2":158210,"3":474630,"4":316732,"5":26,"6":156,"7":159458},"b":{"0":[157950,260],"1":[78,158132],"2":[156182,1352],"3":[158132,156182],"4":[474630,472342],"5":[158210,0],"6":[158210,0,0],"7":[158210,0],"8":[0,26],"9":[156,159016],"10":[26,130],"11":[156,130],"12":[158262,754],"13":[159016,159016,158626,158600],"14":[52,158210],"15":[0,158210],"16":[364,157898],"17":[36088,123370]},"meta":{"lastBranch":18,"lastFunction":8,"lastStatement":56,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"f:44:16:44:35":0,"s:45:16:45:Infinity":3,"s:46:2:46:Infinity":4,"b:46:17:46:29:46:29:46:Infinity":0,"f:62:16:62:35":1,"s:63:2:96:Infinity":5,"s:64:20:64:Infinity":6,"s:65:25:65:Infinity":7,"s:66:23:66:Infinity":8,"s:67:24:67:Infinity":9,"s:68:22:68:Infinity":10,"s:69:10:80:Infinity":11,"f:69:10:69:30":2,"s:70:6:79:Infinity":12,"s:71:18:71:Infinity":13,"b:72:8:72:Infinity:undefined:undefined:undefined:undefined":1,"s:72:8:72:Infinity":14,"s:72:16:72:Infinity":15,"s:73:23:73:Infinity":16,"s:74:8:76:Infinity":17,"b:75:12:75:Infinity:76:12:76:Infinity":2,"b:74:15:74:57:74:57:74:Infinity":3,"s:78:8:78:Infinity":18,"s:82:23:84:Infinity":19,"f:83:7:83:15":3,"s:83:34:83:53":20,"b:83:34:83:41:83:41:83:53":4,"f:84:7:84:13":4,"s:84:22:84:41":21,"s:85:24:85:Infinity":22,"b:85:24:85:41:85:41:85:Infinity":5,"s:87:10:87:Infinity":23,"b:87:22:87:43:87:43:87:62:87:62:87:64":6,"s:88:18:88:Infinity":24,"s:90:4:93:Infinity":25,"b:91:32:91:40:91:40:91:Infinity":7,"s:95:4:95:Infinity":26,"f:108:16:108:70":5,"s:109:25:109:Infinity":27,"b:111:2:111:Infinity:undefined:undefined:undefined:undefined":8,"s:111:2:111:Infinity":28,"s:111:32:111:Infinity":29,"f:113:11:113:19":6,"s:114:20:114:Infinity":30,"s:115:4:148:Infinity":31,"s:116:23:116:Infinity":32,"b:117:6:147:Infinity:120:13:147:Infinity":9,"s:117:6:147:Infinity":33,"b:118:8:118:Infinity:undefined:undefined:undefined:undefined":10,"s:118:8:118:Infinity":34,"b:118:12:118:41:118:41:118:69":11,"s:118:69:118:Infinity":35,"s:119:8:119:Infinity":36,"b:120:13:147:Infinity:undefined:undefined:undefined:undefined":12,"s:120:13:147:Infinity":37,"b:121:8:121:Infinity:122:8:122:Infinity:123:8:123:Infinity:124:8:124:Infinity":13,"s:126:22:126:Infinity":38,"b:127:8:127:Infinity:undefined:undefined:undefined:undefined":14,"s:127:8:127:Infinity":39,"s:127:20:127:Infinity":40,"s:129:25:129:Infinity":41,"s:130:21:130:Infinity":42,"s:131:21:131:Infinity":43,"s:133:23:133:Infinity":44,"s:134:25:134:Infinity":45,"b:134:34:134:62:134:62:134:Infinity":15,"b:136:8:138:Infinity:undefined:undefined:undefined:undefined":16,"s:136:8:138:Infinity":46,"s:137:10:137:Infinity":47,"s:139:8:146:Infinity":48,"s:151:2:151:Infinity":49,"s:153:2:158:Infinity":50,"s:154:4:157:Infinity":51,"f:154:9:154:15":7,"b:155:6:155:Infinity:undefined:undefined:undefined:undefined":17,"s:155:6:155:Infinity":52,"s:155:29:155:Infinity":53,"s:156:6:156:Infinity":54,"s:160:2:160:Infinity":55}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/docs-sections.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/articles/docs-sections.ts","statementMap":{"0":{"start":{"line":22,"column":19},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":18},"end":{"line":23,"column":null}},"2":{"start":{"line":25,"column":17},"end":{"line":25,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"getDocsSections","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":48}},"loc":{"start":{"line":41,"column":48},"end":{"line":49,"column":null}},"line":41}},"branchMap":{},"s":{"0":30,"1":30,"2":30,"3":23},"f":{"0":23},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":4,"seen":{"s:22:19:22:Infinity":0,"s:23:18:23:Infinity":1,"s:25:17:25:Infinity":2,"f:41:16:41:48":0,"s:42:2:48:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/git-timestamps.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/git-timestamps.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":34,"column":26},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":26},"end":{"line":35,"column":null}},"5":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"6":{"start":{"line":45,"column":27},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":66,"column":null}},"9":{"start":{"line":48,"column":19},"end":{"line":53,"column":null}},"10":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"11":{"start":{"line":55,"column":4},"end":{"line":63,"column":null}},"12":{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},"13":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"14":{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},"15":{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},"17":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"18":{"start":{"line":76,"column":2},"end":{"line":76,"column":null}},"19":{"start":{"line":77,"column":23},"end":{"line":77,"column":null}},"20":{"start":{"line":78,"column":17},"end":{"line":78,"column":null}},"21":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"22":{"start":{"line":79,"column":14},"end":{"line":79,"column":null}},"23":{"start":{"line":80,"column":2},"end":{"line":85,"column":null}},"24":{"start":{"line":81,"column":18},"end":{"line":81,"column":null}},"25":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"26":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}}},"fnMap":{"0":{"name":"loadGitTimestamps","decl":{"start":{"line":44,"column":16},"end":{"line":44,"column":42}},"loc":{"start":{"line":44,"column":42},"end":{"line":67,"column":null}},"line":44},"1":{"name":"getFileModTime","decl":{"start":{"line":75,"column":16},"end":{"line":75,"column":31}},"loc":{"start":{"line":75,"column":57},"end":{"line":86,"column":null}},"line":75}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"1":{"loc":{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":62,"column":null}},{"start":{"line":58,"column":13},"end":{"line":62,"column":null}}],"line":56},"2":{"loc":{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":50}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":32}},{"start":{"line":58,"column":32},"end":{"line":58,"column":50}}],"line":58},"4":{"loc":{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":199538,"6":199535,"7":3,"8":3,"9":3,"10":3,"11":3,"12":82131,"13":3,"14":82128,"15":82122,"16":82122,"17":0,"18":199538,"19":199538,"20":199538,"21":199538,"22":199002,"23":536,"24":536,"25":536,"26":19},"f":{"0":199538,"1":199538},"b":{"0":[199535,3],"1":[3,82128],"2":[82122,6],"3":[82128,82122],"4":[82122,0],"5":[199002,536]},"meta":{"lastBranch":6,"lastFunction":2,"lastStatement":27,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"s:34:26:34:Infinity":3,"s:35:26:35:Infinity":4,"f:44:16:44:42":0,"b:45:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:45:2:45:Infinity":5,"s:45:27:45:Infinity":6,"s:46:2:46:Infinity":7,"s:47:2:66:Infinity":8,"s:48:19:53:Infinity":9,"s:54:27:54:Infinity":10,"s:55:4:63:Infinity":11,"b:56:6:62:Infinity:58:13:62:Infinity":1,"s:56:6:62:Infinity":12,"s:57:8:57:Infinity":13,"b:58:13:62:Infinity:undefined:undefined:undefined:undefined":2,"s:58:13:62:Infinity":14,"b:58:17:58:32:58:32:58:50":3,"b:59:8:61:Infinity:undefined:undefined:undefined:undefined":4,"s:59:8:61:Infinity":15,"s:60:10:60:Infinity":16,"s:65:4:65:Infinity":17,"f:75:16:75:31":1,"s:76:2:76:Infinity":18,"s:77:23:77:Infinity":19,"s:78:17:78:Infinity":20,"b:79:2:79:Infinity:undefined:undefined:undefined:undefined":5,"s:79:2:79:Infinity":21,"s:79:14:79:Infinity":22,"s:80:2:85:Infinity":23,"s:81:18:81:Infinity":24,"s:82:4:82:Infinity":25,"s:84:4:84:Infinity":26}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/hreflang.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/hreflang.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":23,"column":21},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}}},"fnMap":{"0":{"name":"hreflangCode","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":29}},"loc":{"start":{"line":22,"column":51},"end":{"line":25,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23}},"s":{"0":1508993,"1":100199,"2":1408794},"f":{"0":1508993},"b":{"0":[100199,1408794]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:22:16:22:29":0,"b:23:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:23:2:23:Infinity":0,"s:23:21:23:Infinity":1,"s:24:2:24:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/i18n.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/i18n.ts","statementMap":{"0":{"start":{"line":113,"column":61},"end":{"line":548,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":32},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:113:61:548:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/render/page.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-html/render/page.ts","statementMap":{"0":{"start":{"line":32,"column":19},"end":{"line":32,"column":null}},"1":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"2":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"3":{"start":{"line":36,"column":17},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":39},"end":{"line":38,"column":null}},"5":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":12},"end":{"line":45,"column":null}},"7":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"11":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"12":{"start":{"line":52,"column":25},"end":{"line":52,"column":null}},"13":{"start":{"line":54,"column":23},"end":{"line":54,"column":39}},"14":{"start":{"line":56,"column":29},"end":{"line":65,"column":null}},"15":{"start":{"line":57,"column":19},"end":{"line":57,"column":29}},"16":{"start":{"line":59,"column":17},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":19},"end":{"line":60,"column":null}},"18":{"start":{"line":61,"column":6},"end":{"line":62,"column":null}},"19":{"start":{"line":67,"column":25},"end":{"line":73,"column":null}},"20":{"start":{"line":68,"column":15},"end":{"line":68,"column":null}},"21":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"22":{"start":{"line":70,"column":4},"end":{"line":71,"column":null}},"23":{"start":{"line":75,"column":25},"end":{"line":83,"column":null}},"24":{"start":{"line":76,"column":15},"end":{"line":76,"column":null}},"25":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"26":{"start":{"line":78,"column":21},"end":{"line":78,"column":null}},"27":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"28":{"start":{"line":79,"column":34},"end":{"line":79,"column":null}},"29":{"start":{"line":80,"column":4},"end":{"line":81,"column":null}},"30":{"start":{"line":85,"column":26},"end":{"line":96,"column":null}},"31":{"start":{"line":86,"column":25},"end":{"line":86,"column":null}},"32":{"start":{"line":87,"column":24},"end":{"line":87,"column":null}},"33":{"start":{"line":88,"column":21},"end":{"line":90,"column":null}},"34":{"start":{"line":91,"column":4},"end":{"line":94,"column":null}},"35":{"start":{"line":98,"column":17},"end":{"line":98,"column":null}},"36":{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},"37":{"start":{"line":100,"column":4},"end":{"line":102,"column":null}},"38":{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},"39":{"start":{"line":105,"column":6},"end":{"line":108,"column":null}},"40":{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},"41":{"start":{"line":112,"column":6},"end":{"line":115,"column":null}},"42":{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},"43":{"start":{"line":119,"column":6},"end":{"line":122,"column":null}},"44":{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},"45":{"start":{"line":126,"column":6},"end":{"line":129,"column":null}},"46":{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},"47":{"start":{"line":133,"column":6},"end":{"line":136,"column":null}},"48":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"49":{"start":{"line":144,"column":64},"end":{"line":144,"column":null}},"50":{"start":{"line":145,"column":2},"end":{"line":147,"column":null}},"51":{"start":{"line":146,"column":4},"end":{"line":146,"column":null}},"52":{"start":{"line":149,"column":43},"end":{"line":149,"column":null}},"53":{"start":{"line":150,"column":43},"end":{"line":150,"column":null}},"54":{"start":{"line":151,"column":18},"end":{"line":151,"column":null}},"55":{"start":{"line":152,"column":18},"end":{"line":152,"column":null}},"56":{"start":{"line":154,"column":23},"end":{"line":154,"column":null}},"57":{"start":{"line":155,"column":26},"end":{"line":155,"column":null}},"58":{"start":{"line":156,"column":25},"end":{"line":156,"column":null}},"59":{"start":{"line":157,"column":23},"end":{"line":157,"column":null}},"60":{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},"61":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"62":{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},"63":{"start":{"line":161,"column":16},"end":{"line":161,"column":null}},"64":{"start":{"line":162,"column":4},"end":{"line":162,"column":null}},"65":{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},"66":{"start":{"line":164,"column":6},"end":{"line":164,"column":null}},"67":{"start":{"line":167,"column":22},"end":{"line":178,"column":null}},"68":{"start":{"line":179,"column":19},"end":{"line":179,"column":null}},"69":{"start":{"line":181,"column":19},"end":{"line":181,"column":null}},"70":{"start":{"line":183,"column":28},"end":{"line":221,"column":null}},"71":{"start":{"line":223,"column":19},"end":{"line":223,"column":null}},"72":{"start":{"line":224,"column":2},"end":{"line":236,"column":null}},"73":{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},"74":{"start":{"line":239,"column":27},"end":{"line":239,"column":null}},"75":{"start":{"line":240,"column":4},"end":{"line":253,"column":null}},"76":{"start":{"line":247,"column":59},"end":{"line":252,"column":8}},"77":{"start":{"line":256,"column":21},"end":{"line":256,"column":null}},"78":{"start":{"line":399,"column":17},"end":{"line":418,"column":null}},"79":{"start":{"line":420,"column":15},"end":{"line":524,"column":null}},"80":{"start":{"line":521,"column":22},"end":{"line":524,"column":24}},"81":{"start":{"line":528,"column":2},"end":{"line":531,"column":null}}},"fnMap":{"0":{"name":"generateSitemapHtml","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":36}},"loc":{"start":{"line":43,"column":106},"end":{"line":532,"column":null}},"line":43},"1":{"name":"(anonymous_1)","decl":{"start":{"line":57,"column":5},"end":{"line":57,"column":13}},"loc":{"start":{"line":57,"column":19},"end":{"line":57,"column":29}},"line":57},"2":{"name":"(anonymous_2)","decl":{"start":{"line":58,"column":5},"end":{"line":58,"column":10}},"loc":{"start":{"line":58,"column":16},"end":{"line":64,"column":5}},"line":58},"3":{"name":"(anonymous_3)","decl":{"start":{"line":67,"column":35},"end":{"line":67,"column":40}},"loc":{"start":{"line":67,"column":46},"end":{"line":73,"column":3}},"line":67},"4":{"name":"(anonymous_4)","decl":{"start":{"line":75,"column":35},"end":{"line":75,"column":40}},"loc":{"start":{"line":75,"column":46},"end":{"line":83,"column":3}},"line":75},"5":{"name":"(anonymous_5)","decl":{"start":{"line":85,"column":41},"end":{"line":85,"column":46}},"loc":{"start":{"line":85,"column":58},"end":{"line":96,"column":3}},"line":85},"6":{"name":"(anonymous_6)","decl":{"start":{"line":247,"column":38},"end":{"line":247,"column":43}},"loc":{"start":{"line":247,"column":59},"end":{"line":252,"column":8}},"line":247},"7":{"name":"(anonymous_7)","decl":{"start":{"line":521,"column":11},"end":{"line":521,"column":16}},"loc":{"start":{"line":521,"column":22},"end":{"line":524,"column":24}},"line":521}},"branchMap":{"0":{"loc":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":47,"column":34},"end":{"line":47,"column":51}},{"start":{"line":47,"column":51},"end":{"line":47,"column":null}}],"line":47},"1":{"loc":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"type":"cond-expr","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":47}},{"start":{"line":48,"column":47},"end":{"line":48,"column":null}}],"line":48},"2":{"loc":{"start":{"line":49,"column":24},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":36},"end":{"line":49,"column":56}},{"start":{"line":49,"column":56},"end":{"line":49,"column":null}}],"line":49},"3":{"loc":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":51,"column":19},"end":{"line":51,"column":47}},{"start":{"line":51,"column":47},"end":{"line":51,"column":null}}],"line":51},"4":{"loc":{"start":{"line":60,"column":19},"end":{"line":60,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":32},"end":{"line":60,"column":49}},{"start":{"line":60,"column":49},"end":{"line":60,"column":null}}],"line":60},"5":{"loc":{"start":{"line":69,"column":17},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":69,"column":30},"end":{"line":69,"column":45}},{"start":{"line":69,"column":45},"end":{"line":69,"column":null}}],"line":69},"6":{"loc":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"type":"cond-expr","locations":[{"start":{"line":77,"column":31},"end":{"line":77,"column":56}},{"start":{"line":77,"column":56},"end":{"line":77,"column":null}}],"line":77},"7":{"loc":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},{"start":{},"end":{}}],"line":79},"8":{"loc":{"start":{"line":88,"column":21},"end":{"line":90,"column":null}},"type":"cond-expr","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},{"start":{"line":90,"column":8},"end":{"line":90,"column":null}}],"line":88},"9":{"loc":{"start":{"line":94,"column":26},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":40},"end":{"line":94,"column":94}},{"start":{"line":94,"column":94},"end":{"line":94,"column":null}}],"line":94},"10":{"loc":{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":99},"11":{"loc":{"start":{"line":99,"column":6},"end":{"line":99,"column":123}},"type":"binary-expr","locations":[{"start":{"line":99,"column":6},"end":{"line":99,"column":28}},{"start":{"line":99,"column":28},"end":{"line":99,"column":48}},{"start":{"line":99,"column":48},"end":{"line":99,"column":73}},{"start":{"line":99,"column":73},"end":{"line":99,"column":101}},{"start":{"line":99,"column":101},"end":{"line":99,"column":123}}],"line":99},"12":{"loc":{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":4},"end":{"line":110,"column":null}},{"start":{},"end":{}}],"line":104},"13":{"loc":{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":111},"14":{"loc":{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":118,"column":4},"end":{"line":124,"column":null}},{"start":{},"end":{}}],"line":118},"15":{"loc":{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":125,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":125},"16":{"loc":{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":138,"column":null}},{"start":{},"end":{}}],"line":132},"17":{"loc":{"start":{"line":146,"column":28},"end":{"line":146,"column":null}},"type":"cond-expr","locations":[{"start":{"line":146,"column":41},"end":{"line":146,"column":58}},{"start":{"line":146,"column":58},"end":{"line":146,"column":null}}],"line":146},"18":{"loc":{"start":{"line":151,"column":18},"end":{"line":151,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":40},"end":{"line":151,"column":45}},{"start":{"line":151,"column":45},"end":{"line":151,"column":null}}],"line":151},"19":{"loc":{"start":{"line":151,"column":45},"end":{"line":151,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":67},"end":{"line":151,"column":73}},{"start":{"line":151,"column":73},"end":{"line":151,"column":null}}],"line":151},"20":{"loc":{"start":{"line":152,"column":18},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":40},"end":{"line":152,"column":46}},{"start":{"line":152,"column":46},"end":{"line":152,"column":null}}],"line":152},"21":{"loc":{"start":{"line":152,"column":46},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":152,"column":68},"end":{"line":152,"column":74}},{"start":{"line":152,"column":74},"end":{"line":152,"column":null}}],"line":152},"22":{"loc":{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":158,"column":2},"end":{"line":166,"column":null}},{"start":{"line":160,"column":9},"end":{"line":166,"column":null}}],"line":158},"23":{"loc":{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":160,"column":9},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":160},"24":{"loc":{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":165,"column":null}},{"start":{},"end":{}}],"line":163},"25":{"loc":{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":238,"column":2},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":238},"26":{"loc":{"start":{"line":408,"column":13},"end":{"line":408,"column":null}},"type":"cond-expr","locations":[{"start":{"line":408,"column":29},"end":{"line":408,"column":42}},{"start":{"line":408,"column":42},"end":{"line":408,"column":null}}],"line":408},"27":{"loc":{"start":{"line":433,"column":82},"end":{"line":434,"column":null}},"type":"cond-expr","locations":[{"start":{"line":433,"column":93},"end":{"line":434,"column":88}},{"start":{"line":434,"column":88},"end":{"line":434,"column":null}}],"line":433},"28":{"loc":{"start":{"line":473,"column":31},"end":{"line":473,"column":117}},"type":"cond-expr","locations":[{"start":{"line":473,"column":47},"end":{"line":473,"column":79}},{"start":{"line":473,"column":79},"end":{"line":473,"column":117}}],"line":473},"29":{"loc":{"start":{"line":477,"column":14},"end":{"line":481,"column":null}},"type":"cond-expr","locations":[{"start":{"line":477,"column":42},"end":{"line":481,"column":null}},{"start":{"line":481,"column":21},"end":{"line":481,"column":null}}],"line":477}},"s":{"0":30,"1":30,"2":30,"3":30,"4":30,"5":23,"6":23,"7":23,"8":23,"9":23,"10":23,"11":23,"12":23,"13":23,"14":23,"15":322,"16":299,"17":299,"18":299,"19":23,"20":322,"21":322,"22":322,"23":23,"24":322,"25":322,"26":322,"27":322,"28":0,"29":322,"30":23,"31":11472,"32":11472,"33":11472,"34":11472,"35":23,"36":23,"37":23,"38":23,"39":23,"40":23,"41":23,"42":23,"43":23,"44":23,"45":0,"46":23,"47":23,"48":23,"49":23,"50":23,"51":322,"52":23,"53":23,"54":23,"55":23,"56":23,"57":23,"58":23,"59":23,"60":23,"61":0,"62":23,"63":0,"64":0,"65":0,"66":0,"67":23,"68":23,"69":23,"70":23,"71":23,"72":23,"73":23,"74":23,"75":23,"76":4600,"77":23,"78":23,"79":23,"80":115,"81":23},"f":{"0":23,"1":322,"2":299,"3":322,"4":322,"5":11472,"6":4600,"7":115},"b":{"0":[13,10],"1":[13,10],"2":[13,10],"3":[23,0],"4":[10,289],"5":[23,299],"6":[23,299],"7":[0,322],"8":[11382,90],"9":[11472,0],"10":[23,0],"11":[23,0,0,0,0],"12":[23,0],"13":[23,0],"14":[23,0],"15":[0,23],"16":[23,0],"17":[23,299],"18":[2,21],"19":[3,18],"20":[2,21],"21":[3,18],"22":[0,23],"23":[0,23],"24":[0,0],"25":[23,0],"26":[13,10],"27":[23,0],"28":[13,10],"29":[23,0]},"meta":{"lastBranch":30,"lastFunction":8,"lastStatement":82,"seen":{"s:32:19:32:Infinity":0,"s:33:18:33:Infinity":1,"s:35:17:35:Infinity":2,"s:36:17:36:Infinity":3,"s:38:39:38:Infinity":4,"f:43:16:43:36":0,"s:44:15:44:Infinity":5,"s:45:12:45:Infinity":6,"s:46:20:46:Infinity":7,"s:47:22:47:Infinity":8,"b:47:34:47:51:47:51:47:Infinity":0,"s:48:20:48:Infinity":9,"b:48:32:48:47:48:47:48:Infinity":1,"s:49:24:49:Infinity":10,"b:49:36:49:56:49:56:49:Infinity":2,"s:51:19:51:Infinity":11,"b:51:19:51:47:51:47:51:Infinity":3,"s:52:25:52:Infinity":12,"s:54:23:54:39":13,"s:56:29:65:Infinity":14,"f:57:5:57:13":1,"s:57:19:57:29":15,"f:58:5:58:10":2,"s:59:17:59:Infinity":16,"s:60:19:60:Infinity":17,"b:60:32:60:49:60:49:60:Infinity":4,"s:61:6:62:Infinity":18,"s:67:25:73:Infinity":19,"f:67:35:67:40":3,"s:68:15:68:Infinity":20,"s:69:17:69:Infinity":21,"b:69:30:69:45:69:45:69:Infinity":5,"s:70:4:71:Infinity":22,"s:75:25:83:Infinity":23,"f:75:35:75:40":4,"s:76:15:76:Infinity":24,"s:77:18:77:Infinity":25,"b:77:31:77:56:77:56:77:Infinity":6,"s:78:21:78:Infinity":26,"b:79:4:79:Infinity:undefined:undefined:undefined:undefined":7,"s:79:4:79:Infinity":27,"s:79:34:79:Infinity":28,"s:80:4:81:Infinity":29,"s:85:26:96:Infinity":30,"f:85:41:85:46":5,"s:86:25:86:Infinity":31,"s:87:24:87:Infinity":32,"s:88:21:90:Infinity":33,"b:89:8:89:Infinity:90:8:90:Infinity":8,"s:91:4:94:Infinity":34,"b:94:40:94:94:94:94:94:Infinity":9,"s:98:17:98:Infinity":35,"b:99:2:142:Infinity:undefined:undefined:undefined:undefined":10,"s:99:2:142:Infinity":36,"b:99:6:99:28:99:28:99:48:99:48:99:73:99:73:99:101:99:101:99:123":11,"s:100:4:102:Infinity":37,"b:104:4:110:Infinity:undefined:undefined:undefined:undefined":12,"s:104:4:110:Infinity":38,"s:105:6:108:Infinity":39,"b:111:4:117:Infinity:undefined:undefined:undefined:undefined":13,"s:111:4:117:Infinity":40,"s:112:6:115:Infinity":41,"b:118:4:124:Infinity:undefined:undefined:undefined:undefined":14,"s:118:4:124:Infinity":42,"s:119:6:122:Infinity":43,"b:125:4:131:Infinity:undefined:undefined:undefined:undefined":15,"s:125:4:131:Infinity":44,"s:126:6:129:Infinity":45,"b:132:4:138:Infinity:undefined:undefined:undefined:undefined":16,"s:132:4:138:Infinity":46,"s:133:6:136:Infinity":47,"s:139:4:139:Infinity":48,"s:144:64:144:Infinity":49,"s:145:2:147:Infinity":50,"s:146:4:146:Infinity":51,"b:146:41:146:58:146:58:146:Infinity":17,"s:149:43:149:Infinity":52,"s:150:43:150:Infinity":53,"s:151:18:151:Infinity":54,"b:151:40:151:45:151:45:151:Infinity":18,"b:151:67:151:73:151:73:151:Infinity":19,"s:152:18:152:Infinity":55,"b:152:40:152:46:152:46:152:Infinity":20,"b:152:68:152:74:152:74:152:Infinity":21,"s:154:23:154:Infinity":56,"s:155:26:155:Infinity":57,"s:156:25:156:Infinity":58,"s:157:23:157:Infinity":59,"b:158:2:166:Infinity:160:9:166:Infinity":22,"s:158:2:166:Infinity":60,"s:159:4:159:Infinity":61,"b:160:9:166:Infinity:undefined:undefined:undefined:undefined":23,"s:160:9:166:Infinity":62,"s:161:16:161:Infinity":63,"s:162:4:162:Infinity":64,"b:163:4:165:Infinity:undefined:undefined:undefined:undefined":24,"s:163:4:165:Infinity":65,"s:164:6:164:Infinity":66,"s:167:22:178:Infinity":67,"s:179:19:179:Infinity":68,"s:181:19:181:Infinity":69,"s:183:28:221:Infinity":70,"s:223:19:223:Infinity":71,"s:224:2:236:Infinity":72,"b:238:2:254:Infinity:undefined:undefined:undefined:undefined":25,"s:238:2:254:Infinity":73,"s:239:27:239:Infinity":74,"s:240:4:253:Infinity":75,"f:247:38:247:43":6,"s:247:59:252:8":76,"s:256:21:256:Infinity":77,"s:399:17:418:Infinity":78,"b:408:29:408:42:408:42:408:Infinity":26,"s:420:15:524:Infinity":79,"b:433:93:434:88:434:88:434:Infinity":27,"b:473:47:473:79:473:79:473:117":28,"b:477:42:481:Infinity:481:21:481:Infinity":29,"f:521:11:521:16":7,"s:521:22:524:24":80,"s:528:2:531:Infinity":81}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/url-entry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/url-entry.ts","statementMap":{"0":{"start":{"line":20,"column":17},"end":{"line":20,"column":null}},"1":{"start":{"line":38,"column":12},"end":{"line":43,"column":null}},"2":{"start":{"line":45,"column":2},"end":{"line":48,"column":null}},"3":{"start":{"line":46,"column":4},"end":{"line":47,"column":null}},"4":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"5":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}}},"fnMap":{"0":{"name":"generateUrlEntry","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"loc":{"start":{"line":37,"column":10},"end":{"line":54,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":13},"end":{"line":45,"column":22}},"loc":{"start":{"line":45,"column":30},"end":{"line":48,"column":3}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"type":"default-arg","locations":[{"start":{"line":36,"column":36},"end":{"line":36,"column":null}}],"line":36}},"s":{"0":3,"1":199331,"2":199331,"3":1508977,"4":199331,"5":199331},"f":{"0":199331,"1":1508977},"b":{"0":[199331]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":6,"seen":{"s:20:17:20:Infinity":0,"f:31:16:31:Infinity":0,"b:36:36:36:Infinity":0,"s:38:12:43:Infinity":1,"s:45:2:48:Infinity":2,"f:45:13:45:22":1,"s:46:4:47:Infinity":3,"s:50:2:50:Infinity":4,"s:53:2:53:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/sitemap.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/render/sitemap.ts","statementMap":{"0":{"start":{"line":31,"column":19},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":18},"end":{"line":32,"column":null}},"2":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"3":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"4":{"start":{"line":37,"column":39},"end":{"line":37,"column":null}},"5":{"start":{"line":41,"column":2},"end":{"line":41,"column":null}},"6":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}},"7":{"start":{"line":50,"column":12},"end":{"line":50,"column":null}},"8":{"start":{"line":54,"column":47},"end":{"line":60,"column":null}},"9":{"start":{"line":55,"column":32},"end":{"line":58,"column":6}},"10":{"start":{"line":58,"column":24},"end":{"line":58,"column":46}},"11":{"start":{"line":62,"column":21},"end":{"line":62,"column":null}},"12":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"13":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}},"14":{"start":{"line":65,"column":29},"end":{"line":65,"column":42}},"15":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"17":{"start":{"line":67,"column":28},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":20},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"20":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"21":{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},"22":{"start":{"line":75,"column":37},"end":{"line":75,"column":null}},"23":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"24":{"start":{"line":82,"column":2},"end":{"line":88,"column":null}},"25":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"26":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"27":{"start":{"line":84,"column":28},"end":{"line":84,"column":null}},"28":{"start":{"line":85,"column":21},"end":{"line":85,"column":null}},"29":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"30":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"31":{"start":{"line":90,"column":51},"end":{"line":96,"column":null}},"32":{"start":{"line":91,"column":32},"end":{"line":94,"column":6}},"33":{"start":{"line":94,"column":24},"end":{"line":94,"column":68}},"34":{"start":{"line":98,"column":27},"end":{"line":98,"column":null}},"35":{"start":{"line":99,"column":2},"end":{"line":99,"column":null}},"36":{"start":{"line":101,"column":2},"end":{"line":109,"column":null}},"37":{"start":{"line":101,"column":29},"end":{"line":101,"column":42}},"38":{"start":{"line":102,"column":16},"end":{"line":102,"column":null}},"39":{"start":{"line":103,"column":26},"end":{"line":103,"column":null}},"40":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"41":{"start":{"line":105,"column":22},"end":{"line":105,"column":null}},"42":{"start":{"line":106,"column":23},"end":{"line":106,"column":null}},"43":{"start":{"line":107,"column":6},"end":{"line":107,"column":null}},"44":{"start":{"line":111,"column":33},"end":{"line":121,"column":null}},"45":{"start":{"line":123,"column":2},"end":{"line":148,"column":null}},"46":{"start":{"line":124,"column":19},"end":{"line":124,"column":null}},"47":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"48":{"start":{"line":125,"column":32},"end":{"line":125,"column":null}},"49":{"start":{"line":126,"column":22},"end":{"line":126,"column":null}},"50":{"start":{"line":127,"column":44},"end":{"line":135,"column":null}},"51":{"start":{"line":128,"column":34},"end":{"line":133,"column":8}},"52":{"start":{"line":133,"column":26},"end":{"line":133,"column":70}},"53":{"start":{"line":136,"column":4},"end":{"line":138,"column":null}},"54":{"start":{"line":139,"column":4},"end":{"line":147,"column":null}},"55":{"start":{"line":139,"column":31},"end":{"line":139,"column":44}},"56":{"start":{"line":140,"column":23},"end":{"line":140,"column":null}},"57":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"58":{"start":{"line":141,"column":36},"end":{"line":141,"column":null}},"59":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"60":{"start":{"line":143,"column":23},"end":{"line":143,"column":null}},"61":{"start":{"line":144,"column":6},"end":{"line":146,"column":null}},"62":{"start":{"line":150,"column":49},"end":{"line":156,"column":null}},"63":{"start":{"line":151,"column":32},"end":{"line":154,"column":6}},"64":{"start":{"line":154,"column":24},"end":{"line":154,"column":46}},"65":{"start":{"line":158,"column":25},"end":{"line":158,"column":null}},"66":{"start":{"line":159,"column":2},"end":{"line":159,"column":null}},"67":{"start":{"line":161,"column":2},"end":{"line":167,"column":null}},"68":{"start":{"line":161,"column":29},"end":{"line":161,"column":42}},"69":{"start":{"line":162,"column":17},"end":{"line":162,"column":null}},"70":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"71":{"start":{"line":163,"column":29},"end":{"line":163,"column":null}},"72":{"start":{"line":164,"column":20},"end":{"line":164,"column":null}},"73":{"start":{"line":165,"column":21},"end":{"line":165,"column":null}},"74":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"75":{"start":{"line":169,"column":23},"end":{"line":175,"column":null}},"76":{"start":{"line":170,"column":32},"end":{"line":173,"column":6}},"77":{"start":{"line":173,"column":24},"end":{"line":173,"column":46}},"78":{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},"79":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"80":{"start":{"line":178,"column":4},"end":{"line":178,"column":null}},"81":{"start":{"line":181,"column":2},"end":{"line":187,"column":null}},"82":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"83":{"start":{"line":182,"column":23},"end":{"line":182,"column":null}},"84":{"start":{"line":183,"column":17},"end":{"line":183,"column":null}},"85":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"86":{"start":{"line":184,"column":29},"end":{"line":184,"column":null}},"87":{"start":{"line":185,"column":20},"end":{"line":185,"column":null}},"88":{"start":{"line":186,"column":4},"end":{"line":186,"column":null}},"89":{"start":{"line":189,"column":8},"end":{"line":190,"column":null}},"90":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"91":{"start":{"line":192,"column":24},"end":{"line":194,"column":null}},"92":{"start":{"line":194,"column":22},"end":{"line":194,"column":62}},"93":{"start":{"line":195,"column":26},"end":{"line":201,"column":null}},"94":{"start":{"line":196,"column":4},"end":{"line":200,"column":null}},"95":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"96":{"start":{"line":199,"column":6},"end":{"line":199,"column":null}},"97":{"start":{"line":202,"column":28},"end":{"line":204,"column":null}},"98":{"start":{"line":203,"column":54},"end":{"line":203,"column":65}},"99":{"start":{"line":206,"column":51},"end":{"line":214,"column":null}},"100":{"start":{"line":208,"column":24},"end":{"line":208,"column":82}},"101":{"start":{"line":209,"column":22},"end":{"line":212,"column":8}},"102":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"103":{"start":{"line":217,"column":4},"end":{"line":217,"column":null}},"104":{"start":{"line":220,"column":2},"end":{"line":226,"column":null}},"105":{"start":{"line":220,"column":29},"end":{"line":220,"column":42}},"106":{"start":{"line":221,"column":17},"end":{"line":221,"column":null}},"107":{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},"108":{"start":{"line":222,"column":51},"end":{"line":222,"column":null}},"109":{"start":{"line":223,"column":20},"end":{"line":223,"column":null}},"110":{"start":{"line":224,"column":21},"end":{"line":224,"column":null}},"111":{"start":{"line":225,"column":4},"end":{"line":225,"column":null}},"112":{"start":{"line":228,"column":19},"end":{"line":228,"column":35}},"113":{"start":{"line":229,"column":2},"end":{"line":229,"column":null}},"114":{"start":{"line":231,"column":2},"end":{"line":252,"column":null}},"115":{"start":{"line":232,"column":28},"end":{"line":236,"column":null}},"116":{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},"117":{"start":{"line":233,"column":22},"end":{"line":233,"column":null}},"118":{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},"119":{"start":{"line":234,"column":22},"end":{"line":234,"column":null}},"120":{"start":{"line":235,"column":6},"end":{"line":235,"column":null}},"121":{"start":{"line":238,"column":44},"end":{"line":241,"column":null}},"122":{"start":{"line":238,"column":78},"end":{"line":241,"column":6}},"123":{"start":{"line":243,"column":4},"end":{"line":246,"column":null}},"124":{"start":{"line":248,"column":4},"end":{"line":251,"column":null}},"125":{"start":{"line":249,"column":18},"end":{"line":249,"column":null}},"126":{"start":{"line":250,"column":6},"end":{"line":250,"column":null}},"127":{"start":{"line":254,"column":18},"end":{"line":254,"column":29}},"128":{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},"129":{"start":{"line":256,"column":4},"end":{"line":256,"column":null}},"130":{"start":{"line":258,"column":4},"end":{"line":262,"column":null}},"131":{"start":{"line":259,"column":18},"end":{"line":259,"column":null}},"132":{"start":{"line":260,"column":23},"end":{"line":260,"column":null}},"133":{"start":{"line":261,"column":6},"end":{"line":261,"column":null}},"134":{"start":{"line":265,"column":19},"end":{"line":265,"column":31}},"135":{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},"136":{"start":{"line":267,"column":4},"end":{"line":267,"column":null}},"137":{"start":{"line":269,"column":4},"end":{"line":273,"column":null}},"138":{"start":{"line":270,"column":18},"end":{"line":270,"column":null}},"139":{"start":{"line":271,"column":23},"end":{"line":271,"column":null}},"140":{"start":{"line":272,"column":6},"end":{"line":272,"column":null}},"141":{"start":{"line":276,"column":2},"end":{"line":276,"column":null}},"142":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}}},"fnMap":{"0":{"name":"existsAtRoot","decl":{"start":{"line":40,"column":9},"end":{"line":40,"column":22}},"loc":{"start":{"line":40,"column":48},"end":{"line":42,"column":null}},"line":40},"1":{"name":"generateSitemap","decl":{"start":{"line":47,"column":16},"end":{"line":47,"column":42}},"loc":{"start":{"line":47,"column":42},"end":{"line":281,"column":null}},"line":47},"2":{"name":"(anonymous_2)","decl":{"start":{"line":55,"column":17},"end":{"line":55,"column":22}},"loc":{"start":{"line":55,"column":32},"end":{"line":58,"column":6}},"line":55},"3":{"name":"(anonymous_3)","decl":{"start":{"line":58,"column":8},"end":{"line":58,"column":16}},"loc":{"start":{"line":58,"column":24},"end":{"line":58,"column":46}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":65,"column":12},"end":{"line":65,"column":20}},"loc":{"start":{"line":65,"column":29},"end":{"line":65,"column":42}},"line":65},"5":{"name":"(anonymous_5)","decl":{"start":{"line":65,"column":44},"end":{"line":65,"column":53}},"loc":{"start":{"line":65,"column":62},"end":{"line":72,"column":3}},"line":65},"6":{"name":"(anonymous_6)","decl":{"start":{"line":91,"column":17},"end":{"line":91,"column":22}},"loc":{"start":{"line":91,"column":32},"end":{"line":94,"column":6}},"line":91},"7":{"name":"(anonymous_7)","decl":{"start":{"line":94,"column":8},"end":{"line":94,"column":16}},"loc":{"start":{"line":94,"column":24},"end":{"line":94,"column":68}},"line":94},"8":{"name":"(anonymous_8)","decl":{"start":{"line":101,"column":12},"end":{"line":101,"column":20}},"loc":{"start":{"line":101,"column":29},"end":{"line":101,"column":42}},"line":101},"9":{"name":"(anonymous_9)","decl":{"start":{"line":101,"column":44},"end":{"line":101,"column":53}},"loc":{"start":{"line":101,"column":62},"end":{"line":109,"column":3}},"line":101},"10":{"name":"(anonymous_10)","decl":{"start":{"line":123,"column":25},"end":{"line":123,"column":34}},"loc":{"start":{"line":123,"column":43},"end":{"line":148,"column":3}},"line":123},"11":{"name":"(anonymous_11)","decl":{"start":{"line":128,"column":19},"end":{"line":128,"column":24}},"loc":{"start":{"line":128,"column":34},"end":{"line":133,"column":8}},"line":128},"12":{"name":"(anonymous_12)","decl":{"start":{"line":133,"column":10},"end":{"line":133,"column":18}},"loc":{"start":{"line":133,"column":26},"end":{"line":133,"column":70}},"line":133},"13":{"name":"(anonymous_13)","decl":{"start":{"line":139,"column":14},"end":{"line":139,"column":22}},"loc":{"start":{"line":139,"column":31},"end":{"line":139,"column":44}},"line":139},"14":{"name":"(anonymous_14)","decl":{"start":{"line":139,"column":46},"end":{"line":139,"column":55}},"loc":{"start":{"line":139,"column":64},"end":{"line":147,"column":5}},"line":139},"15":{"name":"(anonymous_15)","decl":{"start":{"line":151,"column":17},"end":{"line":151,"column":22}},"loc":{"start":{"line":151,"column":32},"end":{"line":154,"column":6}},"line":151},"16":{"name":"(anonymous_16)","decl":{"start":{"line":154,"column":8},"end":{"line":154,"column":16}},"loc":{"start":{"line":154,"column":24},"end":{"line":154,"column":46}},"line":154},"17":{"name":"(anonymous_17)","decl":{"start":{"line":161,"column":12},"end":{"line":161,"column":20}},"loc":{"start":{"line":161,"column":29},"end":{"line":161,"column":42}},"line":161},"18":{"name":"(anonymous_18)","decl":{"start":{"line":161,"column":44},"end":{"line":161,"column":53}},"loc":{"start":{"line":161,"column":62},"end":{"line":167,"column":3}},"line":161},"19":{"name":"(anonymous_19)","decl":{"start":{"line":170,"column":17},"end":{"line":170,"column":22}},"loc":{"start":{"line":170,"column":32},"end":{"line":173,"column":6}},"line":170},"20":{"name":"(anonymous_20)","decl":{"start":{"line":173,"column":8},"end":{"line":173,"column":16}},"loc":{"start":{"line":173,"column":24},"end":{"line":173,"column":46}},"line":173},"21":{"name":"(anonymous_21)","decl":{"start":{"line":189,"column":8},"end":{"line":189,"column":28}},"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"line":190},"22":{"name":"(anonymous_22)","decl":{"start":{"line":194,"column":5},"end":{"line":194,"column":13}},"loc":{"start":{"line":194,"column":22},"end":{"line":194,"column":62}},"line":194},"23":{"name":"(anonymous_23)","decl":{"start":{"line":195,"column":40},"end":{"line":195,"column":45}},"loc":{"start":{"line":195,"column":54},"end":{"line":201,"column":3}},"line":195},"24":{"name":"(anonymous_24)","decl":{"start":{"line":203,"column":43},"end":{"line":203,"column":48}},"loc":{"start":{"line":203,"column":54},"end":{"line":203,"column":65}},"line":203},"25":{"name":"(anonymous_25)","decl":{"start":{"line":208,"column":7},"end":{"line":208,"column":15}},"loc":{"start":{"line":208,"column":24},"end":{"line":208,"column":82}},"line":208},"26":{"name":"(anonymous_26)","decl":{"start":{"line":209,"column":7},"end":{"line":209,"column":12}},"loc":{"start":{"line":209,"column":22},"end":{"line":212,"column":8}},"line":209},"27":{"name":"(anonymous_27)","decl":{"start":{"line":220,"column":12},"end":{"line":220,"column":20}},"loc":{"start":{"line":220,"column":29},"end":{"line":220,"column":42}},"line":220},"28":{"name":"(anonymous_28)","decl":{"start":{"line":220,"column":44},"end":{"line":220,"column":53}},"loc":{"start":{"line":220,"column":62},"end":{"line":226,"column":3}},"line":220},"29":{"name":"(anonymous_29)","decl":{"start":{"line":231,"column":11},"end":{"line":231,"column":20}},"loc":{"start":{"line":231,"column":32},"end":{"line":252,"column":3}},"line":231},"30":{"name":"(anonymous_30)","decl":{"start":{"line":232,"column":51},"end":{"line":232,"column":57}},"loc":{"start":{"line":232,"column":66},"end":{"line":236,"column":5}},"line":232},"31":{"name":"(anonymous_31)","decl":{"start":{"line":238,"column":60},"end":{"line":238,"column":65}},"loc":{"start":{"line":238,"column":78},"end":{"line":241,"column":6}},"line":238},"32":{"name":"(anonymous_32)","decl":{"start":{"line":248,"column":20},"end":{"line":248,"column":29}},"loc":{"start":{"line":248,"column":38},"end":{"line":251,"column":5}},"line":248},"33":{"name":"(anonymous_33)","decl":{"start":{"line":258,"column":12},"end":{"line":258,"column":21}},"loc":{"start":{"line":258,"column":29},"end":{"line":262,"column":5}},"line":258},"34":{"name":"(anonymous_34)","decl":{"start":{"line":269,"column":13},"end":{"line":269,"column":22}},"loc":{"start":{"line":269,"column":30},"end":{"line":273,"column":5}},"line":269}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":12},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":28},"end":{"line":57,"column":43}},{"start":{"line":57,"column":43},"end":{"line":57,"column":null}}],"line":57},"1":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"2":{"loc":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":69,"column":37},"end":{"line":69,"column":45}},{"start":{"line":69,"column":45},"end":{"line":69,"column":null}}],"line":69},"3":{"loc":{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":77,"column":null}},{"start":{},"end":{}}],"line":74},"4":{"loc":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"type":"cond-expr","locations":[{"start":{"line":83,"column":32},"end":{"line":83,"column":44}},{"start":{"line":83,"column":44},"end":{"line":83,"column":null}}],"line":83},"5":{"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"6":{"loc":{"start":{"line":86,"column":21},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":37},"end":{"line":86,"column":45}},{"start":{"line":86,"column":45},"end":{"line":86,"column":null}}],"line":86},"7":{"loc":{"start":{"line":93,"column":12},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":28},"end":{"line":93,"column":53}},{"start":{"line":93,"column":53},"end":{"line":93,"column":null}}],"line":93},"8":{"loc":{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":4},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":104},"9":{"loc":{"start":{"line":106,"column":23},"end":{"line":106,"column":null}},"type":"cond-expr","locations":[{"start":{"line":106,"column":39},"end":{"line":106,"column":47}},{"start":{"line":106,"column":47},"end":{"line":106,"column":null}}],"line":106},"10":{"loc":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"type":"if","locations":[{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},{"start":{},"end":{}}],"line":125},"11":{"loc":{"start":{"line":130,"column":14},"end":{"line":132,"column":null}},"type":"cond-expr","locations":[{"start":{"line":131,"column":12},"end":{"line":131,"column":null}},{"start":{"line":132,"column":12},"end":{"line":132,"column":null}}],"line":130},"12":{"loc":{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},"type":"if","locations":[{"start":{"line":141,"column":6},"end":{"line":141,"column":null}},{"start":{},"end":{}}],"line":141},"13":{"loc":{"start":{"line":143,"column":23},"end":{"line":143,"column":null}},"type":"cond-expr","locations":[{"start":{"line":143,"column":39},"end":{"line":143,"column":47}},{"start":{"line":143,"column":47},"end":{"line":143,"column":null}}],"line":143},"14":{"loc":{"start":{"line":153,"column":12},"end":{"line":153,"column":null}},"type":"cond-expr","locations":[{"start":{"line":153,"column":28},"end":{"line":153,"column":45}},{"start":{"line":153,"column":45},"end":{"line":153,"column":null}}],"line":153},"15":{"loc":{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},"type":"if","locations":[{"start":{"line":163,"column":4},"end":{"line":163,"column":null}},{"start":{},"end":{}}],"line":163},"16":{"loc":{"start":{"line":165,"column":21},"end":{"line":165,"column":null}},"type":"cond-expr","locations":[{"start":{"line":165,"column":37},"end":{"line":165,"column":45}},{"start":{"line":165,"column":45},"end":{"line":165,"column":null}}],"line":165},"17":{"loc":{"start":{"line":171,"column":12},"end":{"line":171,"column":null}},"type":"cond-expr","locations":[{"start":{"line":171,"column":28},"end":{"line":171,"column":35}},{"start":{"line":171,"column":35},"end":{"line":171,"column":null}}],"line":171},"18":{"loc":{"start":{"line":172,"column":12},"end":{"line":172,"column":null}},"type":"cond-expr","locations":[{"start":{"line":172,"column":28},"end":{"line":172,"column":60}},{"start":{"line":172,"column":60},"end":{"line":172,"column":null}}],"line":172},"19":{"loc":{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},"type":"if","locations":[{"start":{"line":176,"column":2},"end":{"line":179,"column":null}},{"start":{},"end":{}}],"line":176},"20":{"loc":{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},"type":"if","locations":[{"start":{"line":182,"column":4},"end":{"line":182,"column":null}},{"start":{},"end":{}}],"line":182},"21":{"loc":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},{"start":{},"end":{}}],"line":184},"22":{"loc":{"start":{"line":190,"column":4},"end":{"line":190,"column":null}},"type":"cond-expr","locations":[{"start":{"line":190,"column":20},"end":{"line":190,"column":35}},{"start":{"line":190,"column":35},"end":{"line":190,"column":null}}],"line":190},"23":{"loc":{"start":{"line":202,"column":28},"end":{"line":204,"column":null}},"type":"cond-expr","locations":[{"start":{"line":203,"column":6},"end":{"line":203,"column":null}},{"start":{"line":204,"column":6},"end":{"line":204,"column":null}}],"line":202},"24":{"loc":{"start":{"line":211,"column":14},"end":{"line":211,"column":null}},"type":"cond-expr","locations":[{"start":{"line":211,"column":30},"end":{"line":211,"column":40}},{"start":{"line":211,"column":40},"end":{"line":211,"column":null}}],"line":211},"25":{"loc":{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":2},"end":{"line":218,"column":null}},{"start":{},"end":{}}],"line":216},"26":{"loc":{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},"type":"if","locations":[{"start":{"line":222,"column":4},"end":{"line":222,"column":null}},{"start":{},"end":{}}],"line":222},"27":{"loc":{"start":{"line":224,"column":21},"end":{"line":224,"column":null}},"type":"cond-expr","locations":[{"start":{"line":224,"column":37},"end":{"line":224,"column":45}},{"start":{"line":224,"column":45},"end":{"line":224,"column":null}}],"line":224},"28":{"loc":{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},"type":"if","locations":[{"start":{"line":233,"column":6},"end":{"line":233,"column":null}},{"start":{},"end":{}}],"line":233},"29":{"loc":{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},"type":"if","locations":[{"start":{"line":234,"column":6},"end":{"line":234,"column":null}},{"start":{},"end":{}}],"line":234},"30":{"loc":{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},"type":"if","locations":[{"start":{"line":255,"column":2},"end":{"line":263,"column":null}},{"start":{},"end":{}}],"line":255},"31":{"loc":{"start":{"line":260,"column":23},"end":{"line":260,"column":null}},"type":"cond-expr","locations":[{"start":{"line":260,"column":51},"end":{"line":260,"column":59}},{"start":{"line":260,"column":59},"end":{"line":260,"column":null}}],"line":260},"32":{"loc":{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},"type":"if","locations":[{"start":{"line":266,"column":2},"end":{"line":274,"column":null}},{"start":{},"end":{}}],"line":266},"33":{"loc":{"start":{"line":271,"column":23},"end":{"line":271,"column":null}},"type":"cond-expr","locations":[{"start":{"line":271,"column":87},"end":{"line":271,"column":95}},{"start":{"line":271,"column":95},"end":{"line":271,"column":null}}],"line":271},"34":{"loc":{"start":{"line":271,"column":23},"end":{"line":271,"column":87}},"type":"binary-expr","locations":[{"start":{"line":271,"column":23},"end":{"line":271,"column":52}},{"start":{"line":271,"column":52},"end":{"line":271,"column":87}}],"line":271}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":1649,"6":17,"7":17,"8":17,"9":238,"10":238,"11":17,"12":17,"13":17,"14":238,"15":221,"16":221,"17":0,"18":221,"19":221,"20":221,"21":17,"22":17,"23":17,"24":17,"25":238,"26":238,"27":17,"28":221,"29":221,"30":238,"31":17,"32":238,"33":238,"34":17,"35":17,"36":17,"37":238,"38":221,"39":221,"40":221,"41":221,"42":221,"43":221,"44":17,"45":17,"46":153,"47":153,"48":0,"49":153,"50":153,"51":2142,"52":2142,"53":153,"54":153,"55":2142,"56":1989,"57":1989,"58":0,"59":1989,"60":1989,"61":1989,"62":17,"63":238,"64":238,"65":17,"66":17,"67":17,"68":238,"69":221,"70":221,"71":221,"72":0,"73":0,"74":221,"75":17,"76":238,"77":238,"78":17,"79":17,"80":17,"81":17,"82":238,"83":17,"84":221,"85":221,"86":0,"87":221,"88":221,"89":17,"90":697,"91":17,"92":238,"93":17,"94":224,"95":224,"96":0,"97":17,"98":224,"99":17,"100":238,"101":224,"102":17,"103":16,"104":17,"105":238,"106":221,"107":221,"108":13,"109":208,"110":208,"111":221,"112":17,"113":17,"114":17,"115":8908,"116":229143,"117":21335,"118":207808,"119":1717,"120":206091,"121":8908,"122":103445,"123":8908,"124":8908,"125":103445,"126":103445,"127":17,"128":17,"129":0,"130":0,"131":0,"132":0,"133":0,"134":17,"135":17,"136":17,"137":17,"138":92548,"139":92548,"140":92548,"141":17,"142":17},"f":{"0":1649,"1":17,"2":238,"3":238,"4":238,"5":221,"6":238,"7":238,"8":238,"9":221,"10":153,"11":2142,"12":2142,"13":2142,"14":1989,"15":238,"16":238,"17":238,"18":221,"19":238,"20":238,"21":697,"22":238,"23":224,"24":224,"25":238,"26":224,"27":238,"28":221,"29":8908,"30":229143,"31":103445,"32":103445,"33":0,"34":92548},"b":{"0":[17,221],"1":[0,221],"2":[17,204],"3":[17,0],"4":[17,221],"5":[17,221],"6":[0,221],"7":[17,221],"8":[221,0],"9":[17,204],"10":[0,153],"11":[153,1989],"12":[0,1989],"13":[153,1836],"14":[17,221],"15":[221,0],"16":[0,0],"17":[17,221],"18":[17,221],"19":[17,0],"20":[17,221],"21":[0,221],"22":[34,663],"23":[16,1],"24":[16,208],"25":[16,1],"26":[13,208],"27":[16,192],"28":[21335,207808],"29":[1717,206091],"30":[0,17],"31":[0,0],"32":[17,0],"33":[5593,86955],"34":[92548,92531]},"meta":{"lastBranch":35,"lastFunction":35,"lastStatement":143,"seen":{"s:31:19:31:Infinity":0,"s:32:18:32:Infinity":1,"s:34:17:34:Infinity":2,"s:35:17:35:Infinity":3,"s:37:39:37:Infinity":4,"f:40:9:40:22":0,"s:41:2:41:Infinity":5,"f:47:16:47:42":1,"s:48:2:48:Infinity":6,"s:50:12:50:Infinity":7,"s:54:47:60:Infinity":8,"f:55:17:55:22":2,"s:55:32:58:6":9,"b:57:28:57:43:57:43:57:Infinity":0,"f:58:8:58:16":3,"s:58:24:58:46":10,"s:62:21:62:Infinity":11,"s:63:2:63:Infinity":12,"s:65:2:72:Infinity":13,"f:65:12:65:20":4,"s:65:29:65:42":14,"f:65:44:65:53":5,"s:66:16:66:Infinity":15,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":1,"s:67:4:67:Infinity":16,"s:67:28:67:Infinity":17,"s:68:20:68:Infinity":18,"s:69:21:69:Infinity":19,"b:69:37:69:45:69:45:69:Infinity":2,"s:71:4:71:Infinity":20,"b:74:2:77:Infinity:undefined:undefined:undefined:undefined":3,"s:74:2:77:Infinity":21,"s:75:37:75:Infinity":22,"s:76:4:76:Infinity":23,"s:82:2:88:Infinity":24,"s:83:16:83:Infinity":25,"b:83:32:83:44:83:44:83:Infinity":4,"b:84:4:84:Infinity:undefined:undefined:undefined:undefined":5,"s:84:4:84:Infinity":26,"s:84:28:84:Infinity":27,"s:85:21:85:Infinity":28,"s:86:21:86:Infinity":29,"b:86:37:86:45:86:45:86:Infinity":6,"s:87:4:87:Infinity":30,"s:90:51:96:Infinity":31,"f:91:17:91:22":6,"s:91:32:94:6":32,"b:93:28:93:53:93:53:93:Infinity":7,"f:94:8:94:16":7,"s:94:24:94:68":33,"s:98:27:98:Infinity":34,"s:99:2:99:Infinity":35,"s:101:2:109:Infinity":36,"f:101:12:101:20":8,"s:101:29:101:42":37,"f:101:44:101:53":9,"s:102:16:102:Infinity":38,"s:103:26:103:Infinity":39,"b:104:4:108:Infinity:undefined:undefined:undefined:undefined":8,"s:104:4:108:Infinity":40,"s:105:22:105:Infinity":41,"s:106:23:106:Infinity":42,"b:106:39:106:47:106:47:106:Infinity":9,"s:107:6:107:Infinity":43,"s:111:33:121:Infinity":44,"s:123:2:148:Infinity":45,"f:123:25:123:34":10,"s:124:19:124:Infinity":46,"b:125:4:125:Infinity:undefined:undefined:undefined:undefined":10,"s:125:4:125:Infinity":47,"s:125:32:125:Infinity":48,"s:126:22:126:Infinity":49,"s:127:44:135:Infinity":50,"f:128:19:128:24":11,"s:128:34:133:8":51,"b:131:12:131:Infinity:132:12:132:Infinity":11,"f:133:10:133:18":12,"s:133:26:133:70":52,"s:136:4:138:Infinity":53,"s:139:4:147:Infinity":54,"f:139:14:139:22":13,"s:139:31:139:44":55,"f:139:46:139:55":14,"s:140:23:140:Infinity":56,"b:141:6:141:Infinity:undefined:undefined:undefined:undefined":12,"s:141:6:141:Infinity":57,"s:141:36:141:Infinity":58,"s:142:22:142:Infinity":59,"s:143:23:143:Infinity":60,"b:143:39:143:47:143:47:143:Infinity":13,"s:144:6:146:Infinity":61,"s:150:49:156:Infinity":62,"f:151:17:151:22":15,"s:151:32:154:6":63,"b:153:28:153:45:153:45:153:Infinity":14,"f:154:8:154:16":16,"s:154:24:154:46":64,"s:158:25:158:Infinity":65,"s:159:2:159:Infinity":66,"s:161:2:167:Infinity":67,"f:161:12:161:20":17,"s:161:29:161:42":68,"f:161:44:161:53":18,"s:162:17:162:Infinity":69,"b:163:4:163:Infinity:undefined:undefined:undefined:undefined":15,"s:163:4:163:Infinity":70,"s:163:29:163:Infinity":71,"s:164:20:164:Infinity":72,"s:165:21:165:Infinity":73,"b:165:37:165:45:165:45:165:Infinity":16,"s:166:4:166:Infinity":74,"s:169:23:175:Infinity":75,"f:170:17:170:22":19,"s:170:32:173:6":76,"b:171:28:171:35:171:35:171:Infinity":17,"b:172:28:172:60:172:60:172:Infinity":18,"f:173:8:173:16":20,"s:173:24:173:46":77,"b:176:2:179:Infinity:undefined:undefined:undefined:undefined":19,"s:176:2:179:Infinity":78,"s:177:22:177:Infinity":79,"s:178:4:178:Infinity":80,"s:181:2:187:Infinity":81,"b:182:4:182:Infinity:undefined:undefined:undefined:undefined":20,"s:182:4:182:Infinity":82,"s:182:23:182:Infinity":83,"s:183:17:183:Infinity":84,"b:184:4:184:Infinity:undefined:undefined:undefined:undefined":21,"s:184:4:184:Infinity":85,"s:184:29:184:Infinity":86,"s:185:20:185:Infinity":87,"s:186:4:186:Infinity":88,"s:189:8:190:Infinity":89,"f:189:8:189:28":21,"s:190:4:190:Infinity":90,"b:190:20:190:35:190:35:190:Infinity":22,"s:192:24:194:Infinity":91,"f:194:5:194:13":22,"s:194:22:194:62":92,"s:195:26:201:Infinity":93,"f:195:40:195:45":23,"s:196:4:200:Infinity":94,"s:197:6:197:Infinity":95,"s:199:6:199:Infinity":96,"s:202:28:204:Infinity":97,"b:203:6:203:Infinity:204:6:204:Infinity":23,"f:203:43:203:48":24,"s:203:54:203:65":98,"s:206:51:214:Infinity":99,"f:208:7:208:15":25,"s:208:24:208:82":100,"f:209:7:209:12":26,"s:209:22:212:8":101,"b:211:30:211:40:211:40:211:Infinity":24,"b:216:2:218:Infinity:undefined:undefined:undefined:undefined":25,"s:216:2:218:Infinity":102,"s:217:4:217:Infinity":103,"s:220:2:226:Infinity":104,"f:220:12:220:20":27,"s:220:29:220:42":105,"f:220:44:220:53":28,"s:221:17:221:Infinity":106,"b:222:4:222:Infinity:undefined:undefined:undefined:undefined":26,"s:222:4:222:Infinity":107,"s:222:51:222:Infinity":108,"s:223:20:223:Infinity":109,"s:224:21:224:Infinity":110,"b:224:37:224:45:224:45:224:Infinity":27,"s:225:4:225:Infinity":111,"s:228:19:228:35":112,"s:229:2:229:Infinity":113,"s:231:2:252:Infinity":114,"f:231:11:231:20":29,"s:232:28:236:Infinity":115,"f:232:51:232:57":30,"b:233:6:233:Infinity:undefined:undefined:undefined:undefined":28,"s:233:6:233:Infinity":116,"s:233:22:233:Infinity":117,"b:234:6:234:Infinity:undefined:undefined:undefined:undefined":29,"s:234:6:234:Infinity":118,"s:234:22:234:Infinity":119,"s:235:6:235:Infinity":120,"s:238:44:241:Infinity":121,"f:238:60:238:65":31,"s:238:78:241:6":122,"s:243:4:246:Infinity":123,"s:248:4:251:Infinity":124,"f:248:20:248:29":32,"s:249:18:249:Infinity":125,"s:250:6:250:Infinity":126,"s:254:18:254:29":127,"b:255:2:263:Infinity:undefined:undefined:undefined:undefined":30,"s:255:2:263:Infinity":128,"s:256:4:256:Infinity":129,"s:258:4:262:Infinity":130,"f:258:12:258:21":33,"s:259:18:259:Infinity":131,"s:260:23:260:Infinity":132,"b:260:51:260:59:260:59:260:Infinity":31,"s:261:6:261:Infinity":133,"s:265:19:265:31":134,"b:266:2:274:Infinity:undefined:undefined:undefined:undefined":32,"s:266:2:274:Infinity":135,"s:267:4:267:Infinity":136,"s:269:4:273:Infinity":137,"f:269:13:269:22":34,"s:270:18:270:Infinity":138,"s:271:23:271:Infinity":139,"b:271:87:271:95:271:95:271:Infinity":33,"b:271:23:271:52:271:52:271:87":34,"s:272:6:272:Infinity":140,"s:276:2:276:Infinity":141,"s:280:2:280:Infinity":142}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/docs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/docs.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":17},"end":{"line":27,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":4},"end":{"line":63,"column":null}},"10":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"11":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"12":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":29},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":68,"column":25},"end":{"line":68,"column":53}},"19":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"20":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"getDocFiles","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":41}},"loc":{"start":{"line":39,"column":41},"end":{"line":73,"column":null}},"line":39},"1":{"name":"scanDir","decl":{"start":{"line":49,"column":11},"end":{"line":49,"column":19}},"loc":{"start":{"line":49,"column":38},"end":{"line":64,"column":null}},"line":49},"2":{"name":"(anonymous_2)","decl":{"start":{"line":68,"column":10},"end":{"line":68,"column":16}},"loc":{"start":{"line":68,"column":25},"end":{"line":68,"column":53}},"line":68}},"branchMap":{"0":{"loc":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":42},"1":{"loc":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},{"start":{"line":55,"column":13},"end":{"line":62,"column":null}}],"line":53},"2":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":91}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":33}},{"start":{"line":53,"column":33},"end":{"line":53,"column":60}},{"start":{"line":53,"column":60},"end":{"line":53,"column":91}}],"line":53},"3":{"loc":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":55,"column":17},"end":{"line":55,"column":65}},"type":"binary-expr","locations":[{"start":{"line":55,"column":17},"end":{"line":55,"column":35}},{"start":{"line":55,"column":35},"end":{"line":55,"column":65}}],"line":55}},"s":{"0":2,"1":2,"2":2,"3":17,"4":17,"5":0,"6":0,"7":17,"8":5967,"9":5967,"10":100266,"11":100266,"12":5950,"13":94316,"14":92548,"15":92548,"16":17,"17":17,"18":256887,"19":17,"20":17},"f":{"0":17,"1":5967,"2":256887},"b":{"0":[0,17],"1":[5950,94316],"2":[100266,5984,5950],"3":[92548,1768],"4":[94316,94282]},"meta":{"lastBranch":5,"lastFunction":3,"lastStatement":21,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:17:27:Infinity":2,"f:39:16:39:41":0,"s:40:2:40:Infinity":3,"b:42:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:42:2:45:Infinity":4,"s:43:4:43:Infinity":5,"s:44:4:44:Infinity":6,"s:47:29:47:Infinity":7,"f:49:11:49:19":1,"s:50:20:50:Infinity":8,"s:51:4:63:Infinity":9,"s:52:23:52:Infinity":10,"b:53:6:62:Infinity:55:13:62:Infinity":1,"s:53:6:62:Infinity":11,"b:53:10:53:33:53:33:53:60:53:60:53:91":2,"s:54:8:54:Infinity":12,"b:55:13:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:13:62:Infinity":13,"b:55:17:55:35:55:35:55:65":4,"s:56:29:56:Infinity":14,"s:57:8:61:Infinity":15,"s:66:2:66:Infinity":16,"s:68:2:68:Infinity":17,"f:68:10:68:16":2,"s:68:25:68:53":18,"s:70:2:70:Infinity":19,"s:72:2:72:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/api.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/api.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":18},"end":{"line":25,"column":null}},"2":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"3":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"4":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"5":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":47,"column":28},"end":{"line":47,"column":null}},"8":{"start":{"line":50,"column":20},"end":{"line":50,"column":null}},"9":{"start":{"line":51,"column":4},"end":{"line":63,"column":null}},"10":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"11":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"12":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"14":{"start":{"line":56,"column":29},"end":{"line":56,"column":null}},"15":{"start":{"line":57,"column":8},"end":{"line":61,"column":null}},"16":{"start":{"line":66,"column":2},"end":{"line":66,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}}},"fnMap":{"0":{"name":"getApiDocs","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":39}},"loc":{"start":{"line":39,"column":39},"end":{"line":71,"column":null}},"line":39},"1":{"name":"scanDir","decl":{"start":{"line":49,"column":11},"end":{"line":49,"column":19}},"loc":{"start":{"line":49,"column":38},"end":{"line":64,"column":null}},"line":49}},"branchMap":{"0":{"loc":{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":42},"1":{"loc":{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":6},"end":{"line":62,"column":null}},{"start":{"line":55,"column":13},"end":{"line":62,"column":null}}],"line":53},"2":{"loc":{"start":{"line":53,"column":10},"end":{"line":53,"column":58}},"type":"binary-expr","locations":[{"start":{"line":53,"column":10},"end":{"line":53,"column":33}},{"start":{"line":53,"column":33},"end":{"line":53,"column":58}}],"line":53},"3":{"loc":{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":62,"column":null}},{"start":{},"end":{}}],"line":55},"4":{"loc":{"start":{"line":55,"column":17},"end":{"line":55,"column":65}},"type":"binary-expr","locations":[{"start":{"line":55,"column":17},"end":{"line":55,"column":35}},{"start":{"line":55,"column":35},"end":{"line":55,"column":65}}],"line":55}},"s":{"0":3,"1":3,"2":3,"3":19,"4":19,"5":18,"6":18,"7":1,"8":2,"9":2,"10":4,"11":4,"12":1,"13":3,"14":2,"15":2,"16":1,"17":1,"18":1},"f":{"0":19,"1":2},"b":{"0":[18,1],"1":[1,3],"2":[4,2],"3":[2,1],"4":[3,2]},"meta":{"lastBranch":5,"lastFunction":2,"lastStatement":19,"seen":{"s:24:19:24:Infinity":0,"s:25:18:25:Infinity":1,"s:27:16:27:Infinity":2,"f:39:16:39:39":0,"s:40:2:40:Infinity":3,"b:42:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:42:2:45:Infinity":4,"s:43:4:43:Infinity":5,"s:44:4:44:Infinity":6,"s:47:28:47:Infinity":7,"f:49:11:49:19":1,"s:50:20:50:Infinity":8,"s:51:4:63:Infinity":9,"s:52:23:52:Infinity":10,"b:53:6:62:Infinity:55:13:62:Infinity":1,"s:53:6:62:Infinity":11,"b:53:10:53:33:53:33:53:58":2,"s:54:8:54:Infinity":12,"b:55:13:62:Infinity:undefined:undefined:undefined:undefined":3,"s:55:13:62:Infinity":13,"b:55:17:55:35:55:35:55:65":4,"s:56:29:56:Infinity":14,"s:57:8:61:Infinity":15,"s:66:2:66:Infinity":16,"s:68:2:68:Infinity":17,"s:70:2:70:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/news.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/scanners/news.ts","statementMap":{"0":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":18},"end":{"line":28,"column":null}},"2":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"3":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"4":{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},"5":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"7":{"start":{"line":51,"column":19},"end":{"line":51,"column":null}},"8":{"start":{"line":54,"column":20},"end":{"line":54,"column":null}},"9":{"start":{"line":54,"column":80},"end":{"line":54,"column":108}},"10":{"start":{"line":55,"column":4},"end":{"line":86,"column":null}},"11":{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},"12":{"start":{"line":57,"column":8},"end":{"line":57,"column":null}},"13":{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},"14":{"start":{"line":59,"column":21},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":22},"end":{"line":60,"column":null}},"16":{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},"17":{"start":{"line":62,"column":27},"end":{"line":62,"column":null}},"18":{"start":{"line":63,"column":23},"end":{"line":63,"column":null}},"19":{"start":{"line":64,"column":27},"end":{"line":64,"column":null}},"20":{"start":{"line":65,"column":30},"end":{"line":65,"column":null}},"21":{"start":{"line":67,"column":25},"end":{"line":67,"column":null}},"22":{"start":{"line":68,"column":31},"end":{"line":68,"column":null}},"23":{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},"24":{"start":{"line":71,"column":12},"end":{"line":75,"column":null}},"25":{"start":{"line":77,"column":28},"end":{"line":77,"column":null}},"26":{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},"27":{"start":{"line":79,"column":14},"end":{"line":79,"column":null}},"28":{"start":{"line":83,"column":10},"end":{"line":83,"column":null}},"29":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"30":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"31":{"start":{"line":93,"column":2},"end":{"line":103,"column":null}},"32":{"start":{"line":94,"column":20},"end":{"line":94,"column":null}},"33":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"34":{"start":{"line":95,"column":23},"end":{"line":95,"column":null}},"35":{"start":{"line":96,"column":17},"end":{"line":96,"column":null}},"36":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"37":{"start":{"line":98,"column":19},"end":{"line":98,"column":null}},"38":{"start":{"line":99,"column":19},"end":{"line":99,"column":null}},"39":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"40":{"start":{"line":101,"column":21},"end":{"line":101,"column":null}},"41":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}}},"fnMap":{"0":{"name":"getNewsArticles","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":50}},"loc":{"start":{"line":43,"column":50},"end":{"line":104,"column":null}},"line":43},"1":{"name":"scanDir","decl":{"start":{"line":53,"column":11},"end":{"line":53,"column":19}},"loc":{"start":{"line":53,"column":38},"end":{"line":87,"column":null}},"line":53},"2":{"name":"(anonymous_2)","decl":{"start":{"line":54,"column":65},"end":{"line":54,"column":71}},"loc":{"start":{"line":54,"column":80},"end":{"line":54,"column":108}},"line":54},"3":{"name":"(anonymous_3)","decl":{"start":{"line":93,"column":39},"end":{"line":93,"column":45}},"loc":{"start":{"line":93,"column":54},"end":{"line":103,"column":3}},"line":93}},"branchMap":{"0":{"loc":{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":2},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":46},"1":{"loc":{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":6},"end":{"line":85,"column":null}},{"start":{"line":58,"column":13},"end":{"line":85,"column":null}}],"line":56},"2":{"loc":{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":13},"end":{"line":85,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":132}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":35}},{"start":{"line":58,"column":35},"end":{"line":58,"column":66}},{"start":{"line":58,"column":66},"end":{"line":58,"column":102}},{"start":{"line":58,"column":102},"end":{"line":58,"column":132}}],"line":58},"4":{"loc":{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":8},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":61},"5":{"loc":{"start":{"line":68,"column":31},"end":{"line":68,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":40},"end":{"line":68,"column":66}},{"start":{"line":68,"column":66},"end":{"line":68,"column":null}}],"line":68},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":10},"end":{"line":81,"column":null}},{"start":{"line":76,"column":17},"end":{"line":81,"column":null}}],"line":70},"7":{"loc":{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":12},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"8":{"loc":{"start":{"line":78,"column":16},"end":{"line":78,"column":87}},"type":"binary-expr","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":36}},{"start":{"line":78,"column":36},"end":{"line":78,"column":87}}],"line":78},"9":{"loc":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":95},"10":{"loc":{"start":{"line":96,"column":17},"end":{"line":96,"column":null}},"type":"binary-expr","locations":[{"start":{"line":96,"column":17},"end":{"line":96,"column":68}},{"start":{"line":96,"column":68},"end":{"line":96,"column":null}}],"line":96},"11":{"loc":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"type":"binary-expr","locations":[{"start":{"line":97,"column":17},"end":{"line":97,"column":68}},{"start":{"line":97,"column":68},"end":{"line":97,"column":null}}],"line":97},"12":{"loc":{"start":{"line":100,"column":21},"end":{"line":100,"column":null}},"type":"binary-expr","locations":[{"start":{"line":100,"column":21},"end":{"line":100,"column":44}},{"start":{"line":100,"column":44},"end":{"line":100,"column":null}}],"line":100},"13":{"loc":{"start":{"line":101,"column":21},"end":{"line":101,"column":null}},"type":"binary-expr","locations":[{"start":{"line":101,"column":21},"end":{"line":101,"column":44}},{"start":{"line":101,"column":44},"end":{"line":101,"column":null}}],"line":101}},"s":{"0":2,"1":2,"2":2,"3":17,"4":17,"5":0,"6":0,"7":17,"8":136,"9":106617,"10":136,"11":104519,"12":119,"13":104400,"14":103479,"15":103479,"16":103479,"17":103445,"18":103445,"19":103445,"20":103445,"21":103445,"22":103445,"23":103445,"24":8908,"25":94537,"26":94537,"27":0,"28":103445,"29":17,"30":17,"31":17,"32":33201,"33":33201,"34":0,"35":33201,"36":33201,"37":33201,"38":33201,"39":33201,"40":33201,"41":33201},"f":{"0":17,"1":136,"2":106617,"3":33201},"b":{"0":[0,17],"1":[119,104400],"2":[103479,921],"3":[104400,104400,104367,103938],"4":[103445,34],"5":[0,103445],"6":[8908,94537],"7":[0,94537],"8":[94537,94537],"9":[0,33201],"10":[33201,102],"11":[33201,119],"12":[33201,11815],"13":[33201,15504]},"meta":{"lastBranch":14,"lastFunction":4,"lastStatement":42,"seen":{"s:27:19:27:Infinity":0,"s:28:18:28:Infinity":1,"s:30:17:30:Infinity":2,"f:43:16:43:50":0,"s:44:2:44:Infinity":3,"b:46:2:49:Infinity:undefined:undefined:undefined:undefined":0,"s:46:2:49:Infinity":4,"s:47:4:47:Infinity":5,"s:48:4:48:Infinity":6,"s:51:19:51:Infinity":7,"f:53:11:53:19":1,"s:54:20:54:Infinity":8,"f:54:65:54:71":2,"s:54:80:54:108":9,"s:55:4:86:Infinity":10,"b:56:6:85:Infinity:58:13:85:Infinity":1,"s:56:6:85:Infinity":11,"s:57:8:57:Infinity":12,"b:58:13:85:Infinity:undefined:undefined:undefined:undefined":2,"s:58:13:85:Infinity":13,"b:58:17:58:35:58:35:58:66:58:66:58:102:58:102:58:132":3,"s:59:21:59:Infinity":14,"s:60:22:60:Infinity":15,"b:61:8:84:Infinity:undefined:undefined:undefined:undefined":4,"s:61:8:84:Infinity":16,"s:62:27:62:Infinity":17,"s:63:23:63:Infinity":18,"s:64:27:64:Infinity":19,"s:65:30:65:Infinity":20,"s:67:25:67:Infinity":21,"s:68:31:68:Infinity":22,"b:68:40:68:66:68:66:68:Infinity":5,"b:70:10:81:Infinity:76:17:81:Infinity":6,"s:70:10:81:Infinity":23,"s:71:12:75:Infinity":24,"s:77:28:77:Infinity":25,"b:78:12:80:Infinity:undefined:undefined:undefined:undefined":7,"s:78:12:80:Infinity":26,"b:78:16:78:36:78:36:78:87":8,"s:79:14:79:Infinity":27,"s:83:10:83:Infinity":28,"s:89:2:89:Infinity":29,"s:91:2:91:Infinity":30,"s:93:2:103:Infinity":31,"f:93:39:93:45":3,"s:94:20:94:Infinity":32,"b:95:4:95:Infinity:undefined:undefined:undefined:undefined":9,"s:95:4:95:Infinity":33,"s:95:23:95:Infinity":34,"s:96:17:96:Infinity":35,"b:96:17:96:68:96:68:96:Infinity":10,"s:97:17:97:Infinity":36,"b:97:17:97:68:97:68:97:Infinity":11,"s:98:19:98:Infinity":37,"s:99:19:99:Infinity":38,"s:100:21:100:Infinity":39,"b:100:21:100:44:100:44:100:Infinity":12,"s:101:21:101:Infinity":40,"b:101:21:101:44:101:44:101:Infinity":13,"s:102:4:102:Infinity":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/client.ts","statementMap":{"0":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"1":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":47,"column":19},"end":{"line":47,"column":null}},"5":{"start":{"line":48,"column":20},"end":{"line":48,"column":null}},"6":{"start":{"line":49,"column":17},"end":{"line":49,"column":null}},"7":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"8":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"10":{"start":{"line":59,"column":19},"end":{"line":59,"column":null}},"11":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"12":{"start":{"line":64,"column":21},"end":{"line":64,"column":null}},"13":{"start":{"line":65,"column":4},"end":{"line":65,"column":null}},"14":{"start":{"line":69,"column":21},"end":{"line":69,"column":null}},"15":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"16":{"start":{"line":74,"column":21},"end":{"line":74,"column":null}},"17":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"18":{"start":{"line":76,"column":23},"end":{"line":76,"column":null}},"19":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"20":{"start":{"line":77,"column":39},"end":{"line":77,"column":59}},"21":{"start":{"line":79,"column":4},"end":{"line":96,"column":null}},"22":{"start":{"line":80,"column":6},"end":{"line":86,"column":null}},"23":{"start":{"line":88,"column":21},"end":{"line":88,"column":null}},"24":{"start":{"line":89,"column":6},"end":{"line":93,"column":null}},"25":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"26":{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},"27":{"start":{"line":98,"column":6},"end":{"line":101,"column":null}},"28":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":40,"column":2},"end":{"line":40,"column":14}},"loc":{"start":{"line":40,"column":54},"end":{"line":44,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":46,"column":8},"end":{"line":46,"column":26}},"loc":{"start":{"line":46,"column":99},"end":{"line":51,"column":null}},"line":46},"2":{"name":"(anonymous_2)","decl":{"start":{"line":53,"column":8},"end":{"line":53,"column":22}},"loc":{"start":{"line":53,"column":67},"end":{"line":56,"column":null}},"line":53},"3":{"name":"(anonymous_3)","decl":{"start":{"line":58,"column":8},"end":{"line":58,"column":20}},"loc":{"start":{"line":58,"column":66},"end":{"line":61,"column":null}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":63,"column":8},"end":{"line":63,"column":18}},"loc":{"start":{"line":63,"column":48},"end":{"line":66,"column":null}},"line":63},"5":{"name":"(anonymous_5)","decl":{"start":{"line":68,"column":8},"end":{"line":68,"column":25}},"loc":{"start":{"line":68,"column":60},"end":{"line":71,"column":null}},"line":68},"6":{"name":"(anonymous_6)","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":33}},"loc":{"start":{"line":73,"column":65},"end":{"line":104,"column":null}},"line":73},"7":{"name":"(anonymous_7)","decl":{"start":{"line":77,"column":22},"end":{"line":77,"column":39}},"loc":{"start":{"line":77,"column":39},"end":{"line":77,"column":59}},"line":77}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":14},"end":{"line":40,"column":54}},"type":"default-arg","locations":[{"start":{"line":40,"column":50},"end":{"line":40,"column":54}}],"line":40},"1":{"loc":{"start":{"line":41,"column":37},"end":{"line":41,"column":77}},"type":"binary-expr","locations":[{"start":{"line":41,"column":37},"end":{"line":41,"column":55}},{"start":{"line":41,"column":55},"end":{"line":41,"column":77}}],"line":41},"2":{"loc":{"start":{"line":42,"column":19},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":19},"end":{"line":42,"column":37}},{"start":{"line":42,"column":37},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":19},"end":{"line":43,"column":37}},{"start":{"line":43,"column":37},"end":{"line":43,"column":null}}],"line":43},"4":{"loc":{"start":{"line":88,"column":21},"end":{"line":88,"column":null}},"type":"cond-expr","locations":[{"start":{"line":88,"column":46},"end":{"line":88,"column":62}},{"start":{"line":88,"column":62},"end":{"line":88,"column":null}}],"line":88},"5":{"loc":{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":97}},"s":{"0":4,"1":7,"2":7,"3":7,"4":3,"5":3,"6":3,"7":1,"8":0,"9":0,"10":0,"11":0,"12":7,"13":2,"14":0,"15":0,"16":7,"17":7,"18":7,"19":7,"20":0,"21":7,"22":7,"23":3,"24":3,"25":6,"26":3,"27":1,"28":2},"f":{"0":7,"1":3,"2":0,"3":0,"4":7,"5":0,"6":7,"7":0},"b":{"0":[7],"1":[7,6],"2":[7,7],"3":[7,1],"4":[3,0],"5":[1,2]},"meta":{"lastBranch":6,"lastFunction":8,"lastStatement":29,"seen":{"s:33:24:33:Infinity":0,"f:40:2:40:14":0,"b:40:50:40:54":0,"s:41:4:41:Infinity":1,"b:41:37:41:55:41:55:41:77":1,"s:42:4:42:Infinity":2,"b:42:19:42:37:42:37:42:Infinity":2,"s:43:4:43:Infinity":3,"b:43:19:43:37:43:37:43:Infinity":3,"f:46:8:46:26":1,"s:47:19:47:Infinity":4,"s:48:20:48:Infinity":5,"s:49:17:49:Infinity":6,"s:50:4:50:Infinity":7,"f:53:8:53:22":2,"s:54:19:54:Infinity":8,"s:55:4:55:Infinity":9,"f:58:8:58:20":3,"s:59:19:59:Infinity":10,"s:60:4:60:Infinity":11,"f:63:8:63:18":4,"s:64:21:64:Infinity":12,"s:65:4:65:Infinity":13,"f:68:8:68:25":5,"s:69:21:69:Infinity":14,"s:70:4:70:Infinity":15,"f:73:16:73:33":6,"s:74:21:74:Infinity":16,"s:75:4:75:Infinity":17,"s:76:23:76:Infinity":18,"s:77:22:77:Infinity":19,"f:77:22:77:39":7,"s:77:39:77:59":20,"s:79:4:96:Infinity":21,"s:80:6:86:Infinity":22,"s:88:21:88:Infinity":23,"b:88:46:88:62:88:62:88:Infinity":4,"s:89:6:93:Infinity":24,"s:95:6:95:Infinity":25,"b:97:4:102:Infinity:undefined:undefined:undefined:undefined":5,"s:97:4:102:Infinity":26,"s:98:6:101:Infinity":27,"s:103:4:103:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/static-pages-seo-head.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/static-pages-seo-head.ts","statementMap":{"0":{"start":{"line":63,"column":53},"end":{"line":67,"column":null}},"1":{"start":{"line":75,"column":54},"end":{"line":79,"column":null}},"2":{"start":{"line":81,"column":39},"end":{"line":84,"column":null}},"3":{"start":{"line":97,"column":89},"end":{"line":146,"column":null}},"4":{"start":{"line":158,"column":2},"end":{"line":158,"column":null}},"5":{"start":{"line":172,"column":26},"end":{"line":172,"column":null}},"6":{"start":{"line":173,"column":2},"end":{"line":173,"column":null}},"7":{"start":{"line":174,"column":2},"end":{"line":177,"column":null}},"8":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"9":{"start":{"line":175,"column":24},"end":{"line":175,"column":null}},"10":{"start":{"line":176,"column":4},"end":{"line":176,"column":null}},"11":{"start":{"line":178,"column":2},"end":{"line":178,"column":null}},"12":{"start":{"line":195,"column":43},"end":{"line":195,"column":null}},"13":{"start":{"line":196,"column":23},"end":{"line":196,"column":null}},"14":{"start":{"line":197,"column":29},"end":{"line":197,"column":null}},"15":{"start":{"line":198,"column":23},"end":{"line":198,"column":null}},"16":{"start":{"line":199,"column":2},"end":{"line":208,"column":null}},"17":{"start":{"line":227,"column":61},"end":{"line":227,"column":null}},"18":{"start":{"line":228,"column":21},"end":{"line":228,"column":null}},"19":{"start":{"line":229,"column":19},"end":{"line":231,"column":null}},"20":{"start":{"line":232,"column":20},"end":{"line":232,"column":null}},"21":{"start":{"line":233,"column":20},"end":{"line":233,"column":null}},"22":{"start":{"line":245,"column":7},"end":{"line":250,"column":null}},"23":{"start":{"line":251,"column":17},"end":{"line":293,"column":null}},"24":{"start":{"line":294,"column":2},"end":{"line":294,"column":null}},"25":{"start":{"line":304,"column":100},"end":{"line":327,"column":null}},"26":{"start":{"line":328,"column":2},"end":{"line":328,"column":null}},"27":{"start":{"line":337,"column":93},"end":{"line":386,"column":null}},"28":{"start":{"line":387,"column":2},"end":{"line":387,"column":null}},"29":{"start":{"line":396,"column":2},"end":{"line":401,"column":null}},"30":{"start":{"line":430,"column":33},"end":{"line":430,"column":null}},"31":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"32":{"start":{"line":433,"column":52},"end":{"line":433,"column":null}},"33":{"start":{"line":437,"column":21},"end":{"line":437,"column":null}},"34":{"start":{"line":438,"column":27},"end":{"line":438,"column":null}},"35":{"start":{"line":439,"column":25},"end":{"line":439,"column":null}},"36":{"start":{"line":440,"column":23},"end":{"line":440,"column":null}},"37":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"38":{"start":{"line":443,"column":8},"end":{"line":443,"column":null}},"39":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"40":{"start":{"line":445,"column":8},"end":{"line":445,"column":null}},"41":{"start":{"line":447,"column":13},"end":{"line":447,"column":null}},"42":{"start":{"line":450,"column":28},"end":{"line":450,"column":null}},"43":{"start":{"line":451,"column":22},"end":{"line":451,"column":null}},"44":{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},"45":{"start":{"line":453,"column":4},"end":{"line":453,"column":null}},"46":{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},"47":{"start":{"line":455,"column":4},"end":{"line":455,"column":null}},"48":{"start":{"line":462,"column":24},"end":{"line":462,"column":null}},"49":{"start":{"line":463,"column":2},"end":{"line":463,"column":null}},"50":{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},"51":{"start":{"line":466,"column":4},"end":{"line":466,"column":null}},"52":{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},"53":{"start":{"line":468,"column":4},"end":{"line":468,"column":null}},"54":{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},"55":{"start":{"line":473,"column":25},"end":{"line":478,"column":null}},"56":{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},"57":{"start":{"line":480,"column":6},"end":{"line":480,"column":null}},"58":{"start":{"line":505,"column":24},"end":{"line":505,"column":null}},"59":{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},"60":{"start":{"line":507,"column":25},"end":{"line":507,"column":null}},"61":{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},"62":{"start":{"line":512,"column":6},"end":{"line":515,"column":null}},"63":{"start":{"line":517,"column":24},"end":{"line":523,"column":null}},"64":{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},"65":{"start":{"line":525,"column":6},"end":{"line":525,"column":null}},"66":{"start":{"line":529,"column":2},"end":{"line":529,"column":null}}},"fnMap":{"0":{"name":"buildStaticPageKeywords","decl":{"start":{"line":157,"column":16},"end":{"line":157,"column":40}},"loc":{"start":{"line":157,"column":90},"end":{"line":159,"column":null}},"line":157},"1":{"name":"buildStaticPageOgLocaleBlock","decl":{"start":{"line":171,"column":16},"end":{"line":171,"column":45}},"loc":{"start":{"line":171,"column":69},"end":{"line":179,"column":null}},"line":171},"2":{"name":"buildStaticPageTwitterCardBlock","decl":{"start":{"line":189,"column":16},"end":{"line":189,"column":48}},"loc":{"start":{"line":194,"column":11},"end":{"line":209,"column":null}},"line":194},"3":{"name":"buildStaticPageJsonLd","decl":{"start":{"line":220,"column":16},"end":{"line":220,"column":38}},"loc":{"start":{"line":226,"column":11},"end":{"line":295,"column":null}},"line":226},"4":{"name":"breadcrumbLabel","decl":{"start":{"line":303,"column":9},"end":{"line":303,"column":25}},"loc":{"start":{"line":303,"column":75},"end":{"line":329,"column":null}},"line":303},"5":{"name":"pageAbout","decl":{"start":{"line":336,"column":9},"end":{"line":336,"column":19}},"loc":{"start":{"line":336,"column":69},"end":{"line":388,"column":null}},"line":336},"6":{"name":"escapeHtmlAttribute","decl":{"start":{"line":395,"column":9},"end":{"line":395,"column":29}},"loc":{"start":{"line":395,"column":51},"end":{"line":402,"column":null}},"line":395},"7":{"name":"enhanceStaticPageHead","decl":{"start":{"line":425,"column":16},"end":{"line":425,"column":38}},"loc":{"start":{"line":429,"column":11},"end":{"line":530,"column":null}},"line":429}},"branchMap":{"0":{"loc":{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":175,"column":null}},{"start":{},"end":{}}],"line":175},"1":{"loc":{"start":{"line":229,"column":19},"end":{"line":231,"column":null}},"type":"cond-expr","locations":[{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},{"start":{"line":231,"column":6},"end":{"line":231,"column":null}}],"line":229},"2":{"loc":{"start":{"line":245,"column":7},"end":{"line":250,"column":null}},"type":"cond-expr","locations":[{"start":{"line":246,"column":6},"end":{"line":246,"column":null}},{"start":{"line":247,"column":6},"end":{"line":250,"column":null}}],"line":245},"3":{"loc":{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},"type":"if","locations":[{"start":{"line":433,"column":2},"end":{"line":433,"column":null}},{"start":{},"end":{}}],"line":433},"4":{"loc":{"start":{"line":442,"column":17},"end":{"line":442,"column":38}},"type":"binary-expr","locations":[{"start":{"line":442,"column":17},"end":{"line":442,"column":36}},{"start":{"line":442,"column":36},"end":{"line":442,"column":38}}],"line":442},"5":{"loc":{"start":{"line":443,"column":23},"end":{"line":443,"column":50}},"type":"binary-expr","locations":[{"start":{"line":443,"column":23},"end":{"line":443,"column":48}},{"start":{"line":443,"column":48},"end":{"line":443,"column":50}}],"line":443},"6":{"loc":{"start":{"line":444,"column":24},"end":{"line":444,"column":49}},"type":"binary-expr","locations":[{"start":{"line":444,"column":24},"end":{"line":444,"column":47}},{"start":{"line":444,"column":47},"end":{"line":444,"column":49}}],"line":444},"7":{"loc":{"start":{"line":445,"column":20},"end":{"line":445,"column":91}},"type":"binary-expr","locations":[{"start":{"line":445,"column":20},"end":{"line":445,"column":41}},{"start":{"line":445,"column":41},"end":{"line":445,"column":91}}],"line":445},"8":{"loc":{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},"type":"if","locations":[{"start":{"line":452,"column":2},"end":{"line":456,"column":null}},{"start":{"line":454,"column":9},"end":{"line":456,"column":null}}],"line":452},"9":{"loc":{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},"type":"if","locations":[{"start":{"line":454,"column":9},"end":{"line":456,"column":null}},{"start":{},"end":{}}],"line":454},"10":{"loc":{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":465,"column":2},"end":{"line":469,"column":null}},{"start":{"line":467,"column":9},"end":{"line":469,"column":null}}],"line":465},"11":{"loc":{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},"type":"if","locations":[{"start":{"line":467,"column":9},"end":{"line":469,"column":null}},{"start":{},"end":{}}],"line":467},"12":{"loc":{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},"type":"if","locations":[{"start":{"line":472,"column":2},"end":{"line":482,"column":null}},{"start":{},"end":{}}],"line":472},"13":{"loc":{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},"type":"if","locations":[{"start":{"line":479,"column":4},"end":{"line":481,"column":null}},{"start":{},"end":{}}],"line":479},"14":{"loc":{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},"type":"if","locations":[{"start":{"line":506,"column":2},"end":{"line":527,"column":null}},{"start":{},"end":{}}],"line":506},"15":{"loc":{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},"type":"if","locations":[{"start":{"line":508,"column":4},"end":{"line":516,"column":null}},{"start":{},"end":{}}],"line":508},"16":{"loc":{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},"type":"if","locations":[{"start":{"line":524,"column":4},"end":{"line":526,"column":null}},{"start":{},"end":{}}],"line":524}},"s":{"0":1,"1":1,"2":1,"3":1,"4":203,"5":53,"6":53,"7":53,"8":742,"9":53,"10":689,"11":53,"12":46,"13":46,"14":46,"15":46,"16":46,"17":51,"18":51,"19":51,"20":51,"21":51,"22":51,"23":51,"24":51,"25":102,"26":102,"27":51,"28":51,"29":183,"30":45,"31":45,"32":0,"33":45,"34":45,"35":45,"36":45,"37":45,"38":45,"39":45,"40":45,"41":45,"42":45,"43":45,"44":45,"45":45,"46":0,"47":0,"48":45,"49":45,"50":45,"51":3,"52":42,"53":42,"54":45,"55":44,"56":44,"57":44,"58":45,"59":45,"60":44,"61":44,"62":0,"63":44,"64":44,"65":44,"66":45},"f":{"0":203,"1":53,"2":46,"3":51,"4":102,"5":51,"6":183,"7":45},"b":{"0":[53,689],"1":[4,47],"2":[16,35],"3":[0,45],"4":[45,0],"5":[45,0],"6":[45,0],"7":[45,0],"8":[45,0],"9":[0,0],"10":[3,42],"11":[42,0],"12":[44,1],"13":[44,0],"14":[44,1],"15":[0,44],"16":[44,0]},"meta":{"lastBranch":17,"lastFunction":8,"lastStatement":67,"seen":{"s:63:53:67:Infinity":0,"s:75:54:79:Infinity":1,"s:81:39:84:Infinity":2,"s:97:89:146:Infinity":3,"f:157:16:157:40":0,"s:158:2:158:Infinity":4,"f:171:16:171:45":1,"s:172:26:172:Infinity":5,"s:173:2:173:Infinity":6,"s:174:2:177:Infinity":7,"b:175:4:175:Infinity:undefined:undefined:undefined:undefined":0,"s:175:4:175:Infinity":8,"s:175:24:175:Infinity":9,"s:176:4:176:Infinity":10,"s:178:2:178:Infinity":11,"f:189:16:189:48":2,"s:195:43:195:Infinity":12,"s:196:23:196:Infinity":13,"s:197:29:197:Infinity":14,"s:198:23:198:Infinity":15,"s:199:2:208:Infinity":16,"f:220:16:220:38":3,"s:227:61:227:Infinity":17,"s:228:21:228:Infinity":18,"s:229:19:231:Infinity":19,"b:230:6:230:Infinity:231:6:231:Infinity":1,"s:232:20:232:Infinity":20,"s:233:20:233:Infinity":21,"s:245:7:250:Infinity":22,"b:246:6:246:Infinity:247:6:250:Infinity":2,"s:251:17:293:Infinity":23,"s:294:2:294:Infinity":24,"f:303:9:303:25":4,"s:304:100:327:Infinity":25,"s:328:2:328:Infinity":26,"f:336:9:336:19":5,"s:337:93:386:Infinity":27,"s:387:2:387:Infinity":28,"f:395:9:395:29":6,"s:396:2:401:Infinity":29,"f:425:16:425:38":7,"s:430:33:430:Infinity":30,"b:433:2:433:Infinity:undefined:undefined:undefined:undefined":3,"s:433:2:433:Infinity":31,"s:433:52:433:Infinity":32,"s:437:21:437:Infinity":33,"s:438:27:438:Infinity":34,"s:439:25:439:Infinity":35,"s:440:23:440:Infinity":36,"s:442:8:442:Infinity":37,"b:442:17:442:36:442:36:442:38":4,"s:443:8:443:Infinity":38,"b:443:23:443:48:443:48:443:50":5,"s:444:8:444:Infinity":39,"b:444:24:444:47:444:47:444:49":6,"s:445:8:445:Infinity":40,"b:445:20:445:41:445:41:445:91":7,"s:447:13:447:Infinity":41,"s:450:28:450:Infinity":42,"s:451:22:451:Infinity":43,"b:452:2:456:Infinity:454:9:456:Infinity":8,"s:452:2:456:Infinity":44,"s:453:4:453:Infinity":45,"b:454:9:456:Infinity:undefined:undefined:undefined:undefined":9,"s:454:9:456:Infinity":46,"s:455:4:455:Infinity":47,"s:462:24:462:Infinity":48,"s:463:2:463:Infinity":49,"b:465:2:469:Infinity:467:9:469:Infinity":10,"s:465:2:469:Infinity":50,"s:466:4:466:Infinity":51,"b:467:9:469:Infinity:undefined:undefined:undefined:undefined":11,"s:467:9:469:Infinity":52,"s:468:4:468:Infinity":53,"b:472:2:482:Infinity:undefined:undefined:undefined:undefined":12,"s:472:2:482:Infinity":54,"s:473:25:478:Infinity":55,"b:479:4:481:Infinity:undefined:undefined:undefined:undefined":13,"s:479:4:481:Infinity":56,"s:480:6:480:Infinity":57,"s:505:24:505:Infinity":58,"b:506:2:527:Infinity:undefined:undefined:undefined:undefined":14,"s:506:2:527:Infinity":59,"s:507:25:507:Infinity":60,"b:508:4:516:Infinity:undefined:undefined:undefined:undefined":15,"s:508:4:516:Infinity":61,"s:512:6:515:Infinity":62,"s:517:24:523:Infinity":63,"b:524:4:526:Infinity:undefined:undefined:undefined:undefined":16,"s:524:4:526:Infinity":64,"s:525:6:525:Infinity":65,"s:529:2:529:Infinity":66}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/sitemap-xml/validator.ts","statementMap":{"0":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"1":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},"3":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":null}},"5":{"start":{"line":34,"column":8},"end":{"line":34,"column":null}},"6":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"7":{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},"8":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"9":{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},"10":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"11":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}}},"fnMap":{"0":{"name":"validateSitemap","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":32}},"loc":{"start":{"line":23,"column":54},"end":{"line":47,"column":null}},"line":23}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},"type":"if","locations":[{"start":{"line":26,"column":2},"end":{"line":28,"column":null}},{"start":{},"end":{}}],"line":26},"1":{"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":30},"2":{"loc":{"start":{"line":34,"column":20},"end":{"line":34,"column":45}},"type":"binary-expr","locations":[{"start":{"line":34,"column":20},"end":{"line":34,"column":43}},{"start":{"line":34,"column":43},"end":{"line":34,"column":45}}],"line":34},"3":{"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"4":{"loc":{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":2},"end":{"line":43,"column":null}},{"start":{},"end":{}}],"line":41}},"s":{"0":11,"1":11,"2":2,"3":9,"4":2,"5":7,"6":11,"7":11,"8":2,"9":5,"10":2,"11":3,"12":3},"f":{"0":11},"b":{"0":[2,9],"1":[2,7],"2":[7,2],"3":[2,9],"4":[2,3]},"meta":{"lastBranch":5,"lastFunction":1,"lastStatement":13,"seen":{"f:23:16:23:32":0,"s:24:2:24:Infinity":0,"b:26:2:28:Infinity:undefined:undefined:undefined:undefined":0,"s:26:2:28:Infinity":1,"s:27:4:27:Infinity":2,"b:30:2:32:Infinity:undefined:undefined:undefined:undefined":1,"s:30:2:32:Infinity":3,"s:31:4:31:Infinity":4,"s:34:8:34:Infinity":5,"b:34:20:34:43:34:43:34:45":2,"s:35:2:35:Infinity":6,"b:37:2:39:Infinity:undefined:undefined:undefined:undefined":3,"s:37:2:39:Infinity":7,"s:38:4:38:Infinity":8,"b:41:2:43:Infinity:undefined:undefined:undefined:undefined":4,"s:41:2:43:Infinity":9,"s:42:4:42:Infinity":10,"s:45:2:45:Infinity":11,"s:46:2:46:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/budget.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/budget.ts","statementMap":{"0":{"start":{"line":39,"column":41},"end":{"line":39,"column":null}},"1":{"start":{"line":40,"column":2},"end":{"line":117,"column":null}},"2":{"start":{"line":41,"column":19},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":20},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":15},"end":{"line":44,"column":null}},"7":{"start":{"line":46,"column":21},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"9":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"10":{"start":{"line":55,"column":6},"end":{"line":65,"column":null}},"11":{"start":{"line":67,"column":17},"end":{"line":78,"column":null}},"12":{"start":{"line":80,"column":23},"end":{"line":88,"column":null}},"13":{"start":{"line":89,"column":20},"end":{"line":89,"column":null}},"14":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"15":{"start":{"line":90,"column":31},"end":{"line":90,"column":null}},"16":{"start":{"line":92,"column":22},"end":{"line":100,"column":null}},"17":{"start":{"line":101,"column":19},"end":{"line":101,"column":null}},"18":{"start":{"line":103,"column":19},"end":{"line":103,"column":null}},"19":{"start":{"line":104,"column":19},"end":{"line":104,"column":null}},"20":{"start":{"line":106,"column":4},"end":{"line":116,"column":null}},"21":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"22":{"start":{"line":132,"column":41},"end":{"line":132,"column":null}},"23":{"start":{"line":133,"column":2},"end":{"line":140,"column":null}},"24":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"25":{"start":{"line":135,"column":53},"end":{"line":138,"column":null}},"26":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"27":{"start":{"line":141,"column":2},"end":{"line":146,"column":null}},"28":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"29":{"start":{"line":160,"column":17},"end":{"line":170,"column":null}},"30":{"start":{"line":172,"column":2},"end":{"line":193,"column":null}},"31":{"start":{"line":173,"column":16},"end":{"line":173,"column":null}},"32":{"start":{"line":174,"column":21},"end":{"line":174,"column":null}},"33":{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},"34":{"start":{"line":176,"column":6},"end":{"line":176,"column":null}},"35":{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},"36":{"start":{"line":178,"column":8},"end":{"line":178,"column":null}},"37":{"start":{"line":180,"column":8},"end":{"line":180,"column":null}},"38":{"start":{"line":182,"column":6},"end":{"line":182,"column":null}},"39":{"start":{"line":184,"column":6},"end":{"line":191,"column":null}},"40":{"start":{"line":195,"column":2},"end":{"line":208,"column":null}},"41":{"start":{"line":196,"column":45},"end":{"line":207,"column":6}},"42":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"43":{"start":{"line":213,"column":12},"end":{"line":213,"column":null}},"44":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"45":{"start":{"line":214,"column":29},"end":{"line":214,"column":null}},"46":{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},"47":{"start":{"line":215,"column":52},"end":{"line":215,"column":null}},"48":{"start":{"line":216,"column":2},"end":{"line":216,"column":null}}},"fnMap":{"0":{"name":"parseBudgetRows","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"loc":{"start":{"line":38,"column":28},"end":{"line":119,"column":null}},"line":38},"1":{"name":"buildBudgetTimeSeries","decl":{"start":{"line":128,"column":16},"end":{"line":128,"column":null}},"loc":{"start":{"line":131,"column":28},"end":{"line":147,"column":null}},"line":131},"2":{"name":"(anonymous_2)","decl":{"start":{"line":141,"column":14},"end":{"line":141,"column":null}},"loc":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"line":143},"3":{"name":"summarizeBudgetOutturn","decl":{"start":{"line":157,"column":16},"end":{"line":157,"column":null}},"loc":{"start":{"line":159,"column":32},"end":{"line":209,"column":null}},"line":159},"4":{"name":"(anonymous_4)","decl":{"start":{"line":196,"column":5},"end":{"line":196,"column":10}},"loc":{"start":{"line":196,"column":45},"end":{"line":207,"column":6}},"line":196},"5":{"name":"(anonymous_5)","decl":{"start":{"line":208,"column":5},"end":{"line":208,"column":11}},"loc":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"line":208},"6":{"name":"inferDocTypeFromSheetName","decl":{"start":{"line":212,"column":9},"end":{"line":212,"column":35}},"loc":{"start":{"line":212,"column":69},"end":{"line":217,"column":null}},"line":212}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"type":"default-arg","locations":[{"start":{"line":37,"column":40},"end":{"line":37,"column":null}}],"line":37},"1":{"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":17},"end":{"line":43,"column":65}},{"start":{"line":43,"column":65},"end":{"line":43,"column":null}}],"line":43},"2":{"loc":{"start":{"line":43,"column":47},"end":{"line":43,"column":60}},"type":"binary-expr","locations":[{"start":{"line":43,"column":47},"end":{"line":43,"column":58}},{"start":{"line":43,"column":58},"end":{"line":43,"column":60}}],"line":43},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":18},"end":{"line":47,"column":67}},{"start":{"line":47,"column":67},"end":{"line":47,"column":null}}],"line":47},"5":{"loc":{"start":{"line":47,"column":48},"end":{"line":47,"column":62}},"type":"binary-expr","locations":[{"start":{"line":47,"column":48},"end":{"line":47,"column":60}},{"start":{"line":47,"column":60},"end":{"line":47,"column":62}}],"line":47},"6":{"loc":{"start":{"line":50,"column":6},"end":{"line":52,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}}],"line":50},"7":{"loc":{"start":{"line":55,"column":6},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":65,"column":20}},{"start":{"line":65,"column":20},"end":{"line":65,"column":null}}],"line":55},"8":{"loc":{"start":{"line":89,"column":52},"end":{"line":89,"column":68}},"type":"binary-expr","locations":[{"start":{"line":89,"column":52},"end":{"line":89,"column":66}},{"start":{"line":89,"column":66},"end":{"line":89,"column":68}}],"line":89},"9":{"loc":{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":4},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":90},"10":{"loc":{"start":{"line":101,"column":51},"end":{"line":101,"column":66}},"type":"binary-expr","locations":[{"start":{"line":101,"column":51},"end":{"line":101,"column":64}},{"start":{"line":101,"column":64},"end":{"line":101,"column":66}}],"line":101},"11":{"loc":{"start":{"line":108,"column":10},"end":{"line":108,"column":null}},"type":"cond-expr","locations":[{"start":{"line":108,"column":32},"end":{"line":108,"column":44}},{"start":{"line":108,"column":44},"end":{"line":108,"column":null}}],"line":108},"12":{"loc":{"start":{"line":111,"column":10},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":17},"end":{"line":111,"column":28}},{"start":{"line":111,"column":28},"end":{"line":111,"column":null}}],"line":111},"13":{"loc":{"start":{"line":113,"column":10},"end":{"line":113,"column":null}},"type":"cond-expr","locations":[{"start":{"line":113,"column":33},"end":{"line":113,"column":71}},{"start":{"line":113,"column":71},"end":{"line":113,"column":null}}],"line":113},"14":{"loc":{"start":{"line":114,"column":10},"end":{"line":114,"column":null}},"type":"cond-expr","locations":[{"start":{"line":114,"column":19},"end":{"line":114,"column":32}},{"start":{"line":114,"column":32},"end":{"line":114,"column":null}}],"line":114},"15":{"loc":{"start":{"line":115,"column":10},"end":{"line":115,"column":null}},"type":"cond-expr","locations":[{"start":{"line":115,"column":19},"end":{"line":115,"column":32}},{"start":{"line":115,"column":32},"end":{"line":115,"column":null}}],"line":115},"16":{"loc":{"start":{"line":130,"column":2},"end":{"line":130,"column":null}},"type":"default-arg","locations":[{"start":{"line":130,"column":40},"end":{"line":130,"column":null}}],"line":130},"17":{"loc":{"start":{"line":134,"column":25},"end":{"line":134,"column":null}},"type":"binary-expr","locations":[{"start":{"line":134,"column":25},"end":{"line":134,"column":49}},{"start":{"line":134,"column":49},"end":{"line":134,"column":null}}],"line":134},"18":{"loc":{"start":{"line":137,"column":10},"end":{"line":137,"column":null}},"type":"cond-expr","locations":[{"start":{"line":137,"column":25},"end":{"line":137,"column":58}},{"start":{"line":137,"column":58},"end":{"line":137,"column":null}}],"line":137},"19":{"loc":{"start":{"line":143,"column":6},"end":{"line":145,"column":null}},"type":"binary-expr","locations":[{"start":{"line":143,"column":6},"end":{"line":143,"column":null}},{"start":{"line":143,"column":17},"end":{"line":144,"column":null}},{"start":{"line":145,"column":6},"end":{"line":145,"column":null}}],"line":143},"20":{"loc":{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":192,"column":null}},{"start":{"line":183,"column":11},"end":{"line":192,"column":null}}],"line":175},"21":{"loc":{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},"type":"if","locations":[{"start":{"line":177,"column":6},"end":{"line":181,"column":null}},{"start":{"line":179,"column":13},"end":{"line":181,"column":null}}],"line":177},"22":{"loc":{"start":{"line":188,"column":21},"end":{"line":188,"column":null}},"type":"binary-expr","locations":[{"start":{"line":188,"column":21},"end":{"line":188,"column":35}},{"start":{"line":188,"column":35},"end":{"line":188,"column":null}}],"line":188},"23":{"loc":{"start":{"line":200,"column":10},"end":{"line":205,"column":null}},"type":"cond-expr","locations":[{"start":{"line":201,"column":10},"end":{"line":204,"column":null}},{"start":{"line":205,"column":10},"end":{"line":205,"column":null}}],"line":200},"24":{"loc":{"start":{"line":208,"column":20},"end":{"line":208,"column":89}},"type":"binary-expr","locations":[{"start":{"line":208,"column":20},"end":{"line":208,"column":39}},{"start":{"line":208,"column":39},"end":{"line":208,"column":89}}],"line":208},"25":{"loc":{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},"type":"if","locations":[{"start":{"line":214,"column":2},"end":{"line":214,"column":null}},{"start":{},"end":{}}],"line":214},"26":{"loc":{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},"type":"if","locations":[{"start":{"line":215,"column":2},"end":{"line":215,"column":null}},{"start":{},"end":{}}],"line":215},"27":{"loc":{"start":{"line":215,"column":6},"end":{"line":215,"column":52}},"type":"binary-expr","locations":[{"start":{"line":215,"column":6},"end":{"line":215,"column":30}},{"start":{"line":215,"column":30},"end":{"line":215,"column":52}}],"line":215}},"s":{"0":15,"1":15,"2":24,"3":24,"4":24,"5":24,"6":1,"7":23,"8":23,"9":24,"10":24,"11":24,"12":24,"13":24,"14":24,"15":1,"16":22,"17":22,"18":24,"19":24,"20":24,"21":15,"22":1,"23":1,"24":2,"25":2,"26":2,"27":1,"28":1,"29":4,"30":4,"31":8,"32":8,"33":8,"34":2,"35":2,"36":1,"37":1,"38":2,"39":6,"40":4,"41":6,"42":4,"43":2,"44":2,"45":1,"46":1,"47":1,"48":0},"f":{"0":15,"1":1,"2":1,"3":4,"4":6,"5":4,"6":2},"b":{"0":[15],"1":[24,4],"2":[24,4],"3":[1,23],"4":[23,20],"5":[23,20],"6":[24,16,4],"7":[24,0],"8":[24,0],"9":[1,23],"10":[22,15],"11":[4,18],"12":[18,4],"13":[7,15],"14":[22,0],"15":[0,22],"16":[1],"17":[2,2],"18":[2,0],"19":[1,1,1],"20":[2,6],"21":[1,1],"22":[6,3],"23":[2,4],"24":[4,2],"25":[1,1],"26":[1,0],"27":[1,0]},"meta":{"lastBranch":28,"lastFunction":7,"lastStatement":49,"seen":{"f:35:16:35:Infinity":0,"b:37:40:37:Infinity":0,"s:39:41:39:Infinity":0,"s:40:2:117:Infinity":1,"s:41:19:41:Infinity":2,"s:42:20:42:Infinity":3,"s:43:17:43:Infinity":4,"b:43:17:43:65:43:65:43:Infinity":1,"b:43:47:43:58:43:58:43:60":2,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:44:Infinity":5,"s:44:15:44:Infinity":6,"s:46:21:46:Infinity":7,"s:47:18:47:Infinity":8,"b:47:18:47:67:47:67:47:Infinity":4,"b:47:48:47:60:47:60:47:62":5,"s:50:6:52:Infinity":9,"b:50:6:50:Infinity:51:6:51:Infinity:52:6:52:Infinity":6,"s:55:6:65:Infinity":10,"b:55:6:65:20:65:20:65:Infinity":7,"s:67:17:78:Infinity":11,"s:80:23:88:Infinity":12,"s:89:20:89:Infinity":13,"b:89:52:89:66:89:66:89:68":8,"b:90:4:90:Infinity:undefined:undefined:undefined:undefined":9,"s:90:4:90:Infinity":14,"s:90:31:90:Infinity":15,"s:92:22:100:Infinity":16,"s:101:19:101:Infinity":17,"b:101:51:101:64:101:64:101:66":10,"s:103:19:103:Infinity":18,"s:104:19:104:Infinity":19,"s:106:4:116:Infinity":20,"b:108:32:108:44:108:44:108:Infinity":11,"b:111:17:111:28:111:28:111:Infinity":12,"b:113:33:113:71:113:71:113:Infinity":13,"b:114:19:114:32:114:32:114:Infinity":14,"b:115:19:115:32:115:32:115:Infinity":15,"s:118:2:118:Infinity":21,"f:128:16:128:Infinity":1,"b:130:40:130:Infinity":16,"s:132:41:132:Infinity":22,"s:133:2:140:Infinity":23,"s:134:25:134:Infinity":24,"b:134:25:134:49:134:49:134:Infinity":17,"s:135:53:138:Infinity":25,"b:137:25:137:58:137:58:137:Infinity":18,"s:139:4:139:Infinity":26,"s:141:2:146:Infinity":27,"f:141:14:141:Infinity":2,"s:143:6:145:Infinity":28,"b:143:6:143:Infinity:143:17:144:Infinity:145:6:145:Infinity":19,"f:157:16:157:Infinity":3,"s:160:17:170:Infinity":29,"s:172:2:193:Infinity":30,"s:173:16:173:Infinity":31,"s:174:21:174:Infinity":32,"b:175:4:192:Infinity:183:11:192:Infinity":20,"s:175:4:192:Infinity":33,"s:176:6:176:Infinity":34,"b:177:6:181:Infinity:179:13:181:Infinity":21,"s:177:6:181:Infinity":35,"s:178:8:178:Infinity":36,"s:180:8:180:Infinity":37,"s:182:6:182:Infinity":38,"s:184:6:191:Infinity":39,"b:188:21:188:35:188:35:188:Infinity":22,"s:195:2:208:Infinity":40,"f:196:5:196:10":4,"s:196:45:207:6":41,"b:201:10:204:Infinity:205:10:205:Infinity":23,"f:208:5:208:11":5,"s:208:20:208:89":42,"b:208:20:208:39:208:39:208:89":24,"f:212:9:212:35":6,"s:213:12:213:Infinity":43,"b:214:2:214:Infinity:undefined:undefined:undefined:undefined":25,"s:214:2:214:Infinity":44,"s:214:29:214:Infinity":45,"b:215:2:215:Infinity:undefined:undefined:undefined:undefined":26,"s:215:2:215:Infinity":46,"b:215:6:215:30:215:30:215:52":27,"s:215:52:215:Infinity":47,"s:216:2:216:Infinity":48}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/errors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/errors.ts","statementMap":{"0":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"1":{"start":{"line":24,"column":4},"end":{"line":24,"column":null}},"2":{"start":{"line":25,"column":4},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}},"loc":{"start":{"line":22,"column":4},"end":{"line":26,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"type":"default-arg","locations":[{"start":{"line":20,"column":39},"end":{"line":20,"column":null}}],"line":20}},"s":{"0":14,"1":14,"2":14},"f":{"0":14},"b":{"0":[14]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":3,"seen":{"f:18:2:18:Infinity":0,"b:20:39:20:Infinity":0,"s:23:4:23:Infinity":0,"s:24:4:24:Infinity":1,"s:25:4:25:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/headcount.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/domain/headcount.ts","statementMap":{"0":{"start":{"line":31,"column":20},"end":{"line":31,"column":null}},"1":{"start":{"line":32,"column":2},"end":{"line":51,"column":null}},"2":{"start":{"line":33,"column":19},"end":{"line":33,"column":null}},"3":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"4":{"start":{"line":36,"column":23},"end":{"line":40,"column":null}},"5":{"start":{"line":41,"column":27},"end":{"line":43,"column":null}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"7":{"start":{"line":44,"column":62},"end":{"line":44,"column":null}},"8":{"start":{"line":45,"column":22},"end":{"line":45,"column":null}},"9":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"10":{"start":{"line":47,"column":20},"end":{"line":47,"column":null}},"11":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"12":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"13":{"start":{"line":49,"column":19},"end":{"line":49,"column":null}},"14":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"15":{"start":{"line":53,"column":2},"end":{"line":63,"column":null}},"16":{"start":{"line":55,"column":36},"end":{"line":55,"column":null}},"17":{"start":{"line":56,"column":6},"end":{"line":61,"column":null}},"18":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"19":{"start":{"line":70,"column":16},"end":{"line":73,"column":null}},"20":{"start":{"line":71,"column":42},"end":{"line":71,"column":88}},"21":{"start":{"line":72,"column":42},"end":{"line":72,"column":89}},"22":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"23":{"start":{"line":74,"column":14},"end":{"line":74,"column":null}},"24":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}}},"fnMap":{"0":{"name":"aggregateHeadcountByDepartment","decl":{"start":{"line":27,"column":16},"end":{"line":27,"column":null}},"loc":{"start":{"line":30,"column":31},"end":{"line":64,"column":null}},"line":30},"1":{"name":"(anonymous_1)","decl":{"start":{"line":54,"column":5},"end":{"line":54,"column":10}},"loc":{"start":{"line":54,"column":27},"end":{"line":62,"column":5}},"line":54},"2":{"name":"(anonymous_2)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":11}},"loc":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"line":63},"3":{"name":"buildHeadcountTimeSeries","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"loc":{"start":{"line":69,"column":31},"end":{"line":76,"column":null}},"line":69},"4":{"name":"(anonymous_4)","decl":{"start":{"line":71,"column":22},"end":{"line":71,"column":28}},"loc":{"start":{"line":71,"column":42},"end":{"line":71,"column":88}},"line":71},"5":{"name":"(anonymous_5)","decl":{"start":{"line":72,"column":22},"end":{"line":72,"column":28}},"loc":{"start":{"line":72,"column":42},"end":{"line":72,"column":89}},"line":72}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":6},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":6},"end":{"line":35,"column":86}},{"start":{"line":35,"column":86},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":35,"column":36},"end":{"line":35,"column":81}},"type":"binary-expr","locations":[{"start":{"line":35,"column":36},"end":{"line":35,"column":79}},{"start":{"line":35,"column":79},"end":{"line":35,"column":81}}],"line":35},"2":{"loc":{"start":{"line":42,"column":6},"end":{"line":42,"column":null}},"type":"binary-expr","locations":[{"start":{"line":42,"column":6},"end":{"line":42,"column":81}},{"start":{"line":42,"column":81},"end":{"line":42,"column":null}}],"line":42},"3":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"4":{"loc":{"start":{"line":44,"column":8},"end":{"line":44,"column":62}},"type":"binary-expr","locations":[{"start":{"line":44,"column":8},"end":{"line":44,"column":17}},{"start":{"line":44,"column":17},"end":{"line":44,"column":32}},{"start":{"line":44,"column":32},"end":{"line":44,"column":62}}],"line":44},"5":{"loc":{"start":{"line":45,"column":22},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":22},"end":{"line":45,"column":92}},{"start":{"line":45,"column":92},"end":{"line":45,"column":null}}],"line":45},"6":{"loc":{"start":{"line":47,"column":20},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":20},"end":{"line":47,"column":42}},{"start":{"line":47,"column":42},"end":{"line":47,"column":null}}],"line":47},"7":{"loc":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"8":{"loc":{"start":{"line":63,"column":20},"end":{"line":63,"column":85}},"type":"binary-expr","locations":[{"start":{"line":63,"column":20},"end":{"line":63,"column":39}},{"start":{"line":63,"column":39},"end":{"line":63,"column":85}}],"line":63},"9":{"loc":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"type":"default-arg","locations":[{"start":{"line":68,"column":43},"end":{"line":68,"column":null}}],"line":68},"10":{"loc":{"start":{"line":70,"column":16},"end":{"line":73,"column":null}},"type":"cond-expr","locations":[{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},{"start":{"line":72,"column":6},"end":{"line":73,"column":null}}],"line":70},"11":{"loc":{"start":{"line":72,"column":6},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":6},"end":{"line":72,"column":null}},{"start":{"line":73,"column":6},"end":{"line":73,"column":null}}],"line":72},"12":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74}},"s":{"0":3,"1":3,"2":10,"3":10,"4":10,"5":10,"6":10,"7":0,"8":10,"9":10,"10":10,"11":10,"12":10,"13":10,"14":10,"15":3,"16":7,"17":7,"18":6,"19":4,"20":2,"21":1,"22":4,"23":2,"24":2},"f":{"0":3,"1":7,"2":6,"3":4,"4":2,"5":1},"b":{"0":[10,0],"1":[10,0],"2":[10,0],"3":[0,10],"4":[10,10,10],"5":[10,0],"6":[10,7],"7":[10,0],"8":[6,2],"9":[4],"10":[2,2],"11":[2,1],"12":[2,2]},"meta":{"lastBranch":13,"lastFunction":6,"lastStatement":25,"seen":{"f:27:16:27:Infinity":0,"s:31:20:31:Infinity":0,"s:32:2:51:Infinity":1,"s:33:19:33:Infinity":2,"s:35:6:35:Infinity":3,"b:35:6:35:86:35:86:35:Infinity":0,"b:35:36:35:79:35:79:35:81":1,"s:36:23:40:Infinity":4,"s:41:27:43:Infinity":5,"b:42:6:42:81:42:81:42:Infinity":2,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":3,"s:44:4:44:Infinity":6,"b:44:8:44:17:44:17:44:32:44:32:44:62":4,"s:44:62:44:Infinity":7,"s:45:22:45:Infinity":8,"b:45:22:45:92:45:92:45:Infinity":5,"s:46:16:46:Infinity":9,"s:47:20:47:Infinity":10,"b:47:20:47:42:47:42:47:Infinity":6,"s:48:4:48:Infinity":11,"b:49:4:49:Infinity:undefined:undefined:undefined:undefined":7,"s:49:4:49:Infinity":12,"s:49:19:49:Infinity":13,"s:50:4:50:Infinity":14,"s:53:2:63:Infinity":15,"f:54:5:54:10":1,"s:55:36:55:Infinity":16,"s:56:6:61:Infinity":17,"f:63:5:63:11":2,"s:63:20:63:85":18,"b:63:20:63:39:63:39:63:85":8,"f:66:16:66:Infinity":3,"b:68:43:68:Infinity":9,"s:70:16:73:Infinity":19,"b:71:6:71:Infinity:72:6:73:Infinity":10,"f:71:22:71:28":4,"s:71:42:71:88":20,"b:72:6:72:Infinity:73:6:73:Infinity":11,"f:72:22:72:28":5,"s:72:42:72:89":21,"b:74:2:74:Infinity:undefined:undefined:undefined:undefined":12,"s:74:2:74:Infinity":22,"s:74:14:74:Infinity":23,"s:75:2:75:Infinity":24}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/download-links.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/download-links.ts","statementMap":{"0":{"start":{"line":27,"column":33},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":22},"end":{"line":29,"column":null}},"3":{"start":{"line":37,"column":45},"end":{"line":37,"column":null}},"4":{"start":{"line":38,"column":24},"end":{"line":38,"column":null}},"5":{"start":{"line":39,"column":2},"end":{"line":72,"column":null}},"6":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"7":{"start":{"line":41,"column":17},"end":{"line":41,"column":null}},"8":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"9":{"start":{"line":42,"column":15},"end":{"line":42,"column":null}},"10":{"start":{"line":43,"column":25},"end":{"line":43,"column":null}},"11":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"12":{"start":{"line":44,"column":36},"end":{"line":44,"column":null}},"13":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"14":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"15":{"start":{"line":47,"column":17},"end":{"line":47,"column":null}},"16":{"start":{"line":48,"column":18},"end":{"line":48,"column":null}},"17":{"start":{"line":49,"column":4},"end":{"line":71,"column":null}},"18":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"19":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"20":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"21":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"22":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"23":{"start":{"line":88,"column":66},"end":{"line":88,"column":null}},"24":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"25":{"start":{"line":89,"column":37},"end":{"line":89,"column":null}},"26":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"27":{"start":{"line":90,"column":63},"end":{"line":90,"column":null}},"28":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"29":{"start":{"line":91,"column":44},"end":{"line":91,"column":null}},"30":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"31":{"start":{"line":92,"column":64},"end":{"line":92,"column":null}},"32":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"33":{"start":{"line":99,"column":15},"end":{"line":99,"column":null}},"34":{"start":{"line":100,"column":43},"end":{"line":100,"column":null}},"35":{"start":{"line":101,"column":2},"end":{"line":105,"column":null}},"36":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"37":{"start":{"line":102,"column":28},"end":{"line":102,"column":null}},"38":{"start":{"line":103,"column":4},"end":{"line":103,"column":null}},"39":{"start":{"line":104,"column":4},"end":{"line":104,"column":null}},"40":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"41":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"42":{"start":{"line":111,"column":2},"end":{"line":111,"column":null}}},"fnMap":{"0":{"name":"extractStatskontoretDownloadLinks","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":null}},"loc":{"start":{"line":36,"column":31},"end":{"line":74,"column":null}},"line":36},"1":{"name":"classifyStatskontoretResource","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":null}},"loc":{"start":{"line":79,"column":29},"end":{"line":94,"column":null}},"line":79},"2":{"name":"deduplicateLinks","decl":{"start":{"line":96,"column":9},"end":{"line":96,"column":null}},"loc":{"start":{"line":98,"column":31},"end":{"line":107,"column":null}},"line":98},"3":{"name":"extractPageLastModified","decl":{"start":{"line":109,"column":9},"end":{"line":109,"column":33}},"loc":{"start":{"line":109,"column":67},"end":{"line":112,"column":null}},"line":109}},"branchMap":{"0":{"loc":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"type":"default-arg","locations":[{"start":{"line":35,"column":20},"end":{"line":35,"column":null}}],"line":35},"1":{"loc":{"start":{"line":40,"column":28},"end":{"line":40,"column":42}},"type":"binary-expr","locations":[{"start":{"line":40,"column":28},"end":{"line":40,"column":40}},{"start":{"line":40,"column":40},"end":{"line":40,"column":42}}],"line":40},"2":{"loc":{"start":{"line":41,"column":49},"end":{"line":41,"column":63}},"type":"binary-expr","locations":[{"start":{"line":41,"column":49},"end":{"line":41,"column":61}},{"start":{"line":41,"column":61},"end":{"line":41,"column":63}}],"line":41},"3":{"loc":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":42},"4":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"5":{"loc":{"start":{"line":56,"column":10},"end":{"line":58,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":null}},{"start":{"line":58,"column":10},"end":{"line":58,"column":null}}],"line":56},"6":{"loc":{"start":{"line":57,"column":26},"end":{"line":57,"column":79}},"type":"binary-expr","locations":[{"start":{"line":57,"column":26},"end":{"line":57,"column":69}},{"start":{"line":57,"column":69},"end":{"line":57,"column":79}}],"line":57},"7":{"loc":{"start":{"line":59,"column":10},"end":{"line":61,"column":null}},"type":"cond-expr","locations":[{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},{"start":{"line":61,"column":10},"end":{"line":61,"column":null}}],"line":59},"8":{"loc":{"start":{"line":60,"column":22},"end":{"line":60,"column":71}},"type":"binary-expr","locations":[{"start":{"line":60,"column":22},"end":{"line":60,"column":61}},{"start":{"line":60,"column":61},"end":{"line":60,"column":71}}],"line":60},"9":{"loc":{"start":{"line":62,"column":10},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},{"start":{"line":64,"column":10},"end":{"line":64,"column":null}}],"line":62},"10":{"loc":{"start":{"line":63,"column":22},"end":{"line":63,"column":71}},"type":"binary-expr","locations":[{"start":{"line":63,"column":22},"end":{"line":63,"column":61}},{"start":{"line":63,"column":61},"end":{"line":63,"column":71}}],"line":63},"11":{"loc":{"start":{"line":65,"column":10},"end":{"line":65,"column":null}},"type":"cond-expr","locations":[{"start":{"line":65,"column":31},"end":{"line":65,"column":42}},{"start":{"line":65,"column":42},"end":{"line":65,"column":null}}],"line":65},"12":{"loc":{"start":{"line":66,"column":10},"end":{"line":66,"column":null}},"type":"cond-expr","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":44}},{"start":{"line":66,"column":44},"end":{"line":66,"column":null}}],"line":66},"13":{"loc":{"start":{"line":67,"column":10},"end":{"line":69,"column":null}},"type":"cond-expr","locations":[{"start":{"line":68,"column":10},"end":{"line":68,"column":null}},{"start":{"line":69,"column":10},"end":{"line":69,"column":null}}],"line":67},"14":{"loc":{"start":{"line":68,"column":20},"end":{"line":68,"column":67}},"type":"binary-expr","locations":[{"start":{"line":68,"column":20},"end":{"line":68,"column":57}},{"start":{"line":68,"column":57},"end":{"line":68,"column":67}}],"line":68},"15":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":26},"end":{"line":70,"column":57}},{"start":{"line":70,"column":57},"end":{"line":70,"column":null}}],"line":70},"16":{"loc":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":81},"17":{"loc":{"start":{"line":82,"column":4},"end":{"line":84,"column":null}},"type":"binary-expr","locations":[{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},{"start":{"line":84,"column":4},"end":{"line":84,"column":null}}],"line":82},"18":{"loc":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":2},"end":{"line":88,"column":null}},{"start":{},"end":{}}],"line":88},"19":{"loc":{"start":{"line":88,"column":6},"end":{"line":88,"column":66}},"type":"binary-expr","locations":[{"start":{"line":88,"column":6},"end":{"line":88,"column":43}},{"start":{"line":88,"column":43},"end":{"line":88,"column":66}}],"line":88},"20":{"loc":{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":2},"end":{"line":89,"column":null}},{"start":{},"end":{}}],"line":89},"21":{"loc":{"start":{"line":89,"column":44},"end":{"line":89,"column":null}},"type":"cond-expr","locations":[{"start":{"line":89,"column":68},"end":{"line":89,"column":80}},{"start":{"line":89,"column":80},"end":{"line":89,"column":null}}],"line":89},"22":{"loc":{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":2},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":90},"23":{"loc":{"start":{"line":90,"column":6},"end":{"line":90,"column":63}},"type":"binary-expr","locations":[{"start":{"line":90,"column":6},"end":{"line":90,"column":37}},{"start":{"line":90,"column":37},"end":{"line":90,"column":63}}],"line":90},"24":{"loc":{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":91},"25":{"loc":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":92},"26":{"loc":{"start":{"line":92,"column":6},"end":{"line":92,"column":64}},"type":"binary-expr","locations":[{"start":{"line":92,"column":6},"end":{"line":92,"column":38}},{"start":{"line":92,"column":38},"end":{"line":92,"column":64}}],"line":92},"27":{"loc":{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":102,"column":4},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":102},"28":{"loc":{"start":{"line":111,"column":9},"end":{"line":111,"column":null}},"type":"cond-expr","locations":[{"start":{"line":111,"column":17},"end":{"line":111,"column":46}},{"start":{"line":111,"column":46},"end":{"line":111,"column":null}}],"line":111},"29":{"loc":{"start":{"line":111,"column":28},"end":{"line":111,"column":42}},"type":"binary-expr","locations":[{"start":{"line":111,"column":28},"end":{"line":111,"column":40}},{"start":{"line":111,"column":40},"end":{"line":111,"column":42}}],"line":111}},"s":{"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":7,"7":7,"8":7,"9":0,"10":7,"11":7,"12":0,"13":7,"14":7,"15":7,"16":7,"17":7,"18":4,"19":11,"20":11,"21":7,"22":4,"23":2,"24":2,"25":2,"26":2,"27":0,"28":2,"29":2,"30":1,"31":0,"32":1,"33":4,"34":4,"35":4,"36":7,"37":1,"38":6,"39":6,"40":4,"41":4,"42":4},"f":{"0":4,"1":11,"2":4,"3":4},"b":{"0":[4],"1":[7,0],"2":[7,0],"3":[0,7],"4":[0,7],"5":[2,5],"6":[2,0],"7":[6,1],"8":[6,0],"9":[2,5],"10":[2,0],"11":[4,3],"12":[2,5],"13":[2,5],"14":[2,0],"15":[2,5],"16":[7,4],"17":[11,5,4],"18":[2,2],"19":[4,2],"20":[0,2],"21":[0,0],"22":[0,2],"23":[2,0],"24":[1,1],"25":[0,1],"26":[1,1],"27":[1,6],"28":[1,3],"29":[1,0]},"meta":{"lastBranch":30,"lastFunction":4,"lastStatement":43,"seen":{"s:27:33:27:Infinity":0,"s:28:23:28:Infinity":1,"s:29:22:29:Infinity":2,"f:31:16:31:Infinity":0,"b:35:20:35:Infinity":0,"s:37:45:37:Infinity":3,"s:38:24:38:Infinity":4,"s:39:2:72:Infinity":5,"s:40:17:40:Infinity":6,"b:40:28:40:40:40:40:40:42":1,"s:41:17:41:Infinity":7,"b:41:49:41:61:41:61:41:63":2,"b:42:4:42:Infinity:undefined:undefined:undefined:undefined":3,"s:42:4:42:Infinity":8,"s:42:15:42:Infinity":9,"s:43:25:43:Infinity":10,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":4,"s:44:4:44:Infinity":11,"s:44:36:44:Infinity":12,"s:45:16:45:Infinity":13,"s:46:19:46:Infinity":14,"s:47:17:47:Infinity":15,"s:48:18:48:Infinity":16,"s:49:4:71:Infinity":17,"b:57:10:57:Infinity:58:10:58:Infinity":5,"b:57:26:57:69:57:69:57:79":6,"b:60:10:60:Infinity:61:10:61:Infinity":7,"b:60:22:60:61:60:61:60:71":8,"b:63:10:63:Infinity:64:10:64:Infinity":9,"b:63:22:63:61:63:61:63:71":10,"b:65:31:65:42:65:42:65:Infinity":11,"b:66:32:66:44:66:44:66:Infinity":12,"b:68:10:68:Infinity:69:10:69:Infinity":13,"b:68:20:68:57:68:57:68:67":14,"b:70:26:70:57:70:57:70:Infinity":15,"s:73:2:73:Infinity":18,"f:76:16:76:Infinity":1,"s:80:19:80:Infinity":19,"b:81:2:87:Infinity:undefined:undefined:undefined:undefined":16,"s:81:2:87:Infinity":20,"b:82:4:82:Infinity:83:4:83:Infinity:84:4:84:Infinity":17,"s:86:4:86:Infinity":21,"b:88:2:88:Infinity:undefined:undefined:undefined:undefined":18,"s:88:2:88:Infinity":22,"b:88:6:88:43:88:43:88:66":19,"s:88:66:88:Infinity":23,"b:89:2:89:Infinity:undefined:undefined:undefined:undefined":20,"s:89:2:89:Infinity":24,"s:89:37:89:Infinity":25,"b:89:68:89:80:89:80:89:Infinity":21,"b:90:2:90:Infinity:undefined:undefined:undefined:undefined":22,"s:90:2:90:Infinity":26,"b:90:6:90:37:90:37:90:63":23,"s:90:63:90:Infinity":27,"b:91:2:91:Infinity:undefined:undefined:undefined:undefined":24,"s:91:2:91:Infinity":28,"s:91:44:91:Infinity":29,"b:92:2:92:Infinity:undefined:undefined:undefined:undefined":25,"s:92:2:92:Infinity":30,"b:92:6:92:38:92:38:92:64":26,"s:92:64:92:Infinity":31,"s:93:2:93:Infinity":32,"f:96:9:96:Infinity":2,"s:99:15:99:Infinity":33,"s:100:43:100:Infinity":34,"s:101:2:105:Infinity":35,"b:102:4:102:Infinity:undefined:undefined:undefined:undefined":27,"s:102:4:102:Infinity":36,"s:102:28:102:Infinity":37,"s:103:4:103:Infinity":38,"s:104:4:104:Infinity":39,"s:106:2:106:Infinity":40,"f:109:9:109:33":3,"s:110:16:110:Infinity":41,"s:111:2:111:Infinity":42,"b:111:17:111:46:111:46:111:Infinity":28,"b:111:28:111:40:111:40:111:42":29}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/rows-to-records.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/extractors/rows-to-records.ts","statementMap":{"0":{"start":{"line":19,"column":30},"end":{"line":19,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":18},"end":{"line":23,"column":null}},"4":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"5":{"start":{"line":24,"column":44},"end":{"line":24,"column":null}},"6":{"start":{"line":25,"column":2},"end":{"line":34,"column":null}},"7":{"start":{"line":26,"column":43},"end":{"line":26,"column":null}},"8":{"start":{"line":27,"column":19},"end":{"line":27,"column":null}},"9":{"start":{"line":28,"column":4},"end":{"line":32,"column":null}},"10":{"start":{"line":28,"column":17},"end":{"line":28,"column":20}},"11":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"12":{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},"13":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"14":{"start":{"line":31,"column":6},"end":{"line":31,"column":null}},"15":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"16":{"start":{"line":33,"column":18},"end":{"line":33,"column":null}},"17":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"18":{"start":{"line":39,"column":2},"end":{"line":58,"column":null}},"19":{"start":{"line":39,"column":15},"end":{"line":39,"column":18}},"20":{"start":{"line":40,"column":23},"end":{"line":40,"column":null}},"21":{"start":{"line":41,"column":27},"end":{"line":46,"column":null}},"22":{"start":{"line":42,"column":32},"end":{"line":42,"column":58}},"23":{"start":{"line":43,"column":32},"end":{"line":43,"column":60}},"24":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"25":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"26":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"27":{"start":{"line":47,"column":29},"end":{"line":47,"column":null}},"28":{"start":{"line":48,"column":24},"end":{"line":56,"column":null}},"29":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"30":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"31":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"32":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"33":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"34":{"start":{"line":57,"column":26},"end":{"line":57,"column":null}},"35":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"36":{"start":{"line":59,"column":33},"end":{"line":59,"column":78}},"37":{"start":{"line":59,"column":54},"end":{"line":59,"column":65}}},"fnMap":{"0":{"name":"rowsToRecords","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":null}},"loc":{"start":{"line":18,"column":28},"end":{"line":36,"column":null}},"line":18},"1":{"name":"(anonymous_1)","decl":{"start":{"line":21,"column":44},"end":{"line":21,"column":null}},"loc":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"line":22},"2":{"name":"findLikelyHeaderRow","decl":{"start":{"line":38,"column":16},"end":{"line":38,"column":36}},"loc":{"start":{"line":38,"column":82},"end":{"line":60,"column":null}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":42,"column":17},"end":{"line":42,"column":23}},"loc":{"start":{"line":42,"column":32},"end":{"line":42,"column":58}},"line":42},"4":{"name":"(anonymous_4)","decl":{"start":{"line":43,"column":17},"end":{"line":43,"column":23}},"loc":{"start":{"line":43,"column":32},"end":{"line":43,"column":60}},"line":43},"5":{"name":"(anonymous_5)","decl":{"start":{"line":44,"column":17},"end":{"line":44,"column":23}},"loc":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"line":44},"6":{"name":"(anonymous_6)","decl":{"start":{"line":45,"column":17},"end":{"line":45,"column":23}},"loc":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"line":45},"7":{"name":"(anonymous_7)","decl":{"start":{"line":49,"column":17},"end":{"line":49,"column":23}},"loc":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"line":49},"8":{"name":"(anonymous_8)","decl":{"start":{"line":50,"column":17},"end":{"line":50,"column":null}},"loc":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"line":52},"9":{"name":"(anonymous_9)","decl":{"start":{"line":54,"column":17},"end":{"line":54,"column":23}},"loc":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"line":54},"10":{"name":"(anonymous_10)","decl":{"start":{"line":55,"column":17},"end":{"line":55,"column":23}},"loc":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"line":55},"11":{"name":"(anonymous_11)","decl":{"start":{"line":59,"column":14},"end":{"line":59,"column":25}},"loc":{"start":{"line":59,"column":33},"end":{"line":59,"column":78}},"line":59},"12":{"name":"(anonymous_12)","decl":{"start":{"line":59,"column":37},"end":{"line":59,"column":45}},"loc":{"start":{"line":59,"column":54},"end":{"line":59,"column":65}},"line":59}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":30},"end":{"line":19,"column":null}},"type":"binary-expr","locations":[{"start":{"line":19,"column":30},"end":{"line":19,"column":48}},{"start":{"line":19,"column":48},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"2":{"loc":{"start":{"line":22,"column":23},"end":{"line":22,"column":null}},"type":"binary-expr","locations":[{"start":{"line":22,"column":23},"end":{"line":22,"column":40}},{"start":{"line":22,"column":40},"end":{"line":22,"column":null}}],"line":22},"3":{"loc":{"start":{"line":29,"column":20},"end":{"line":29,"column":null}},"type":"binary-expr","locations":[{"start":{"line":29,"column":20},"end":{"line":29,"column":38}},{"start":{"line":29,"column":38},"end":{"line":29,"column":null}}],"line":29},"4":{"loc":{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":6},"end":{"line":30,"column":null}},{"start":{},"end":{}}],"line":30},"5":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"6":{"loc":{"start":{"line":44,"column":32},"end":{"line":44,"column":82}},"type":"binary-expr","locations":[{"start":{"line":44,"column":32},"end":{"line":44,"column":69}},{"start":{"line":44,"column":69},"end":{"line":44,"column":82}}],"line":44},"7":{"loc":{"start":{"line":45,"column":32},"end":{"line":45,"column":64}},"type":"binary-expr","locations":[{"start":{"line":45,"column":32},"end":{"line":45,"column":49}},{"start":{"line":45,"column":49},"end":{"line":45,"column":64}}],"line":45},"8":{"loc":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":47},"9":{"loc":{"start":{"line":49,"column":32},"end":{"line":49,"column":83}},"type":"binary-expr","locations":[{"start":{"line":49,"column":32},"end":{"line":49,"column":59}},{"start":{"line":49,"column":59},"end":{"line":49,"column":83}}],"line":49},"10":{"loc":{"start":{"line":52,"column":10},"end":{"line":52,"column":null}},"type":"binary-expr","locations":[{"start":{"line":52,"column":10},"end":{"line":52,"column":38}},{"start":{"line":52,"column":38},"end":{"line":52,"column":65}},{"start":{"line":52,"column":65},"end":{"line":52,"column":null}}],"line":52},"11":{"loc":{"start":{"line":54,"column":32},"end":{"line":54,"column":95}},"type":"binary-expr","locations":[{"start":{"line":54,"column":32},"end":{"line":54,"column":49}},{"start":{"line":54,"column":49},"end":{"line":54,"column":80}},{"start":{"line":54,"column":80},"end":{"line":54,"column":95}}],"line":54},"12":{"loc":{"start":{"line":55,"column":32},"end":{"line":55,"column":82}},"type":"binary-expr","locations":[{"start":{"line":55,"column":32},"end":{"line":55,"column":59}},{"start":{"line":55,"column":59},"end":{"line":55,"column":82}}],"line":55},"13":{"loc":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57}},"s":{"0":8,"1":8,"2":1,"3":7,"4":20,"5":7,"6":7,"7":16,"8":16,"9":16,"10":16,"11":56,"12":56,"13":56,"14":56,"15":16,"16":16,"17":7,"18":6,"19":6,"20":5,"21":5,"22":10,"23":13,"24":16,"25":7,"26":5,"27":3,"28":2,"29":4,"30":2,"31":4,"32":4,"33":2,"34":2,"35":0,"36":0,"37":0},"f":{"0":8,"1":20,"2":6,"3":10,"4":13,"5":16,"6":7,"7":4,"8":2,"9":4,"10":4,"11":0,"12":0},"b":{"0":[8,6],"1":[1,7],"2":[20,1],"3":[56,0],"4":[56,0],"5":[16,0],"6":[16,13],"7":[7,4],"8":[3,2],"9":[4,2],"10":[2,1,1],"11":[4,4,4],"12":[4,4],"13":[2,0]},"meta":{"lastBranch":14,"lastFunction":13,"lastStatement":38,"seen":{"f:15:16:15:Infinity":0,"s:19:30:19:Infinity":0,"b:19:30:19:48:19:48:19:Infinity":0,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":1,"s:20:2:20:Infinity":1,"s:20:31:20:Infinity":2,"s:21:18:23:Infinity":3,"f:21:44:21:Infinity":1,"s:22:23:22:Infinity":4,"b:22:23:22:40:22:40:22:Infinity":2,"s:24:44:24:Infinity":5,"s:25:2:34:Infinity":6,"s:26:43:26:Infinity":7,"s:27:19:27:Infinity":8,"s:28:4:32:Infinity":9,"s:28:17:28:20":10,"s:29:20:29:Infinity":11,"b:29:20:29:38:29:38:29:Infinity":3,"b:30:6:30:Infinity:undefined:undefined:undefined:undefined":4,"s:30:6:30:Infinity":12,"s:30:17:30:Infinity":13,"s:31:6:31:Infinity":14,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":5,"s:33:4:33:Infinity":15,"s:33:18:33:Infinity":16,"s:35:2:35:Infinity":17,"f:38:16:38:36":2,"s:39:2:58:Infinity":18,"s:39:15:39:18":19,"s:40:23:40:Infinity":20,"s:41:27:46:Infinity":21,"f:42:17:42:23":3,"s:42:32:42:58":22,"f:43:17:43:23":4,"s:43:32:43:60":23,"f:44:17:44:23":5,"s:44:32:44:82":24,"b:44:32:44:69:44:69:44:82":6,"f:45:17:45:23":6,"s:45:32:45:64":25,"b:45:32:45:49:45:49:45:64":7,"b:47:4:47:Infinity:undefined:undefined:undefined:undefined":8,"s:47:4:47:Infinity":26,"s:47:29:47:Infinity":27,"s:48:24:56:Infinity":28,"f:49:17:49:23":7,"s:49:32:49:83":29,"b:49:32:49:59:49:59:49:83":9,"f:50:17:50:Infinity":8,"s:52:10:52:Infinity":30,"b:52:10:52:38:52:38:52:65:52:65:52:Infinity":10,"f:54:17:54:23":9,"s:54:32:54:95":31,"b:54:32:54:49:54:49:54:80:54:80:54:95":11,"f:55:17:55:23":10,"s:55:32:55:82":32,"b:55:32:55:59:55:59:55:82":12,"b:57:4:57:Infinity:undefined:undefined:undefined:undefined":13,"s:57:4:57:Infinity":33,"s:57:26:57:Infinity":34,"s:59:2:59:Infinity":35,"f:59:14:59:25":11,"s:59:33:59:78":36,"f:59:37:59:45":12,"s:59:54:59:65":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/url-guard.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/url-guard.ts","statementMap":{"0":{"start":{"line":19,"column":2},"end":{"line":19,"column":null}},"1":{"start":{"line":33,"column":2},"end":{"line":37,"column":null}},"2":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"3":{"start":{"line":36,"column":4},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"5":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"6":{"start":{"line":41,"column":22},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},"8":{"start":{"line":43,"column":4},"end":{"line":46,"column":null}},"9":{"start":{"line":48,"column":2},"end":{"line":48,"column":null}}},"fnMap":{"0":{"name":"resolveStatskontoretUrl","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":40}},"loc":{"start":{"line":18,"column":78},"end":{"line":20,"column":null}},"line":18},"1":{"name":"assertStatskontoretFetchTarget","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":null}},"loc":{"start":{"line":31,"column":7},"end":{"line":49,"column":null}},"line":31}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"type":"default-arg","locations":[{"start":{"line":30,"column":20},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":38},"2":{"loc":{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":2},"end":{"line":47,"column":null}},{"start":{},"end":{}}],"line":42}},"s":{"0":17,"1":11,"2":11,"3":1,"4":10,"5":1,"6":9,"7":9,"8":2,"9":7},"f":{"0":17,"1":11},"b":{"0":[11],"1":[1,9],"2":[2,7]},"meta":{"lastBranch":3,"lastFunction":2,"lastStatement":10,"seen":{"f:18:16:18:40":0,"s:19:2:19:Infinity":0,"f:28:16:28:Infinity":1,"b:30:20:30:Infinity":0,"s:33:2:37:Infinity":1,"s:34:4:34:Infinity":2,"s:36:4:36:Infinity":3,"b:38:2:40:Infinity:undefined:undefined:undefined:undefined":1,"s:38:2:40:Infinity":4,"s:39:4:39:Infinity":5,"s:41:22:41:Infinity":6,"b:42:2:47:Infinity:undefined:undefined:undefined:undefined":2,"s:42:2:47:Infinity":7,"s:43:4:46:Infinity":8,"s:48:2:48:Infinity":9}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/csv-zip.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/csv-zip.ts","statementMap":{"0":{"start":{"line":18,"column":14},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":38},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"4":{"start":{"line":21,"column":19},"end":{"line":21,"column":null}},"5":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"6":{"start":{"line":22,"column":31},"end":{"line":22,"column":null}},"7":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"8":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"parseStatskontoretCsvZip","decl":{"start":{"line":15,"column":22},"end":{"line":15,"column":null}},"loc":{"start":{"line":17,"column":35},"end":{"line":26,"column":null}},"line":17}},"branchMap":{"0":{"loc":{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":null}},{"start":{},"end":{}}],"line":21},"1":{"loc":{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":22,"column":null}},{"start":{},"end":{}}],"line":22}},"s":{"0":1,"1":1,"2":1,"3":2,"4":0,"5":2,"6":1,"7":1,"8":1},"f":{"0":1},"b":{"0":[0,2],"1":[1,1]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":9,"seen":{"f:15:22:15:Infinity":0,"s:18:14:18:Infinity":0,"s:19:38:19:Infinity":1,"s:20:2:24:Infinity":2,"b:21:4:21:Infinity:undefined:undefined:undefined:undefined":0,"s:21:4:21:Infinity":3,"s:21:19:21:Infinity":4,"b:22:4:22:Infinity:undefined:undefined:undefined:undefined":1,"s:22:4:22:Infinity":5,"s:22:31:22:Infinity":6,"s:23:4:23:Infinity":7,"s:25:2:25:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/text.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/internal/text.ts","statementMap":{"0":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"4":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"5":{"start":{"line":40,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"7":{"start":{"line":45,"column":21},"end":{"line":47,"column":null}},"8":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"9":{"start":{"line":49,"column":2},"end":{"line":49,"column":null}},"10":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"11":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"12":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"13":{"start":{"line":55,"column":2},"end":{"line":55,"column":null}},"14":{"start":{"line":59,"column":17},"end":{"line":59,"column":null}},"15":{"start":{"line":60,"column":2},"end":{"line":62,"column":null}},"16":{"start":{"line":61,"column":4},"end":{"line":61,"column":null}},"17":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"18":{"start":{"line":70,"column":31},"end":{"line":70,"column":null}},"19":{"start":{"line":71,"column":2},"end":{"line":74,"column":null}},"20":{"start":{"line":72,"column":18},"end":{"line":72,"column":null}},"21":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"22":{"start":{"line":73,"column":29},"end":{"line":73,"column":null}},"23":{"start":{"line":75,"column":2},"end":{"line":77,"column":null}},"24":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"25":{"start":{"line":76,"column":49},"end":{"line":76,"column":72}},"26":{"start":{"line":76,"column":75},"end":{"line":76,"column":null}},"27":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"28":{"start":{"line":82,"column":16},"end":{"line":82,"column":null}},"29":{"start":{"line":83,"column":17},"end":{"line":83,"column":null}},"30":{"start":{"line":84,"column":2},"end":{"line":86,"column":null}},"31":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"32":{"start":{"line":87,"column":2},"end":{"line":87,"column":null}},"33":{"start":{"line":91,"column":16},"end":{"line":91,"column":null}},"34":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"35":{"start":{"line":96,"column":26},"end":{"line":96,"column":null}},"36":{"start":{"line":97,"column":17},"end":{"line":97,"column":null}},"37":{"start":{"line":98,"column":2},"end":{"line":100,"column":null}},"38":{"start":{"line":99,"column":4},"end":{"line":99,"column":null}},"39":{"start":{"line":101,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"trimTrailingSlash","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":34}},"loc":{"start":{"line":15,"column":57},"end":{"line":17,"column":null}},"line":15},"1":{"name":"normalizeWhitespace","decl":{"start":{"line":19,"column":16},"end":{"line":19,"column":36}},"loc":{"start":{"line":19,"column":59},"end":{"line":21,"column":null}},"line":19},"2":{"name":"normalizeKey","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":29}},"loc":{"start":{"line":23,"column":52},"end":{"line":29,"column":null}},"line":23},"3":{"name":"roundOneDecimal","decl":{"start":{"line":31,"column":16},"end":{"line":31,"column":32}},"loc":{"start":{"line":31,"column":55},"end":{"line":33,"column":null}},"line":31},"4":{"name":"decodeHtml","decl":{"start":{"line":35,"column":16},"end":{"line":35,"column":27}},"loc":{"start":{"line":35,"column":50},"end":{"line":37,"column":null}},"line":35},"5":{"name":"decodeXml","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":26}},"loc":{"start":{"line":39,"column":49},"end":{"line":41,"column":null}},"line":39},"6":{"name":"parseStatskontoretSwedishNumber","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":48}},"loc":{"start":{"line":43,"column":83},"end":{"line":50,"column":null}},"line":43},"7":{"name":"parseStatskontoretOptionalInt","decl":{"start":{"line":52,"column":16},"end":{"line":52,"column":46}},"loc":{"start":{"line":52,"column":88},"end":{"line":56,"column":null}},"line":52},"8":{"name":"buildRecordLookup","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":34}},"loc":{"start":{"line":58,"column":87},"end":{"line":64,"column":null}},"line":58},"9":{"name":"findField","decl":{"start":{"line":66,"column":16},"end":{"line":66,"column":null}},"loc":{"start":{"line":69,"column":22},"end":{"line":79,"column":null}},"line":69},"10":{"name":"(anonymous_10)","decl":{"start":{"line":76,"column":29},"end":{"line":76,"column":35}},"loc":{"start":{"line":76,"column":49},"end":{"line":76,"column":72}},"line":76},"11":{"name":"parseXmlAttributes","decl":{"start":{"line":81,"column":16},"end":{"line":81,"column":35}},"loc":{"start":{"line":81,"column":71},"end":{"line":88,"column":null}},"line":81},"12":{"name":"firstXmlTagValue","decl":{"start":{"line":90,"column":16},"end":{"line":90,"column":33}},"loc":{"start":{"line":90,"column":79},"end":{"line":93,"column":null}},"line":90},"13":{"name":"extractTextNodes","decl":{"start":{"line":95,"column":16},"end":{"line":95,"column":33}},"loc":{"start":{"line":95,"column":54},"end":{"line":102,"column":null}},"line":95}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":21},"end":{"line":47,"column":null}},"type":"cond-expr","locations":[{"start":{"line":46,"column":6},"end":{"line":46,"column":null}},{"start":{"line":47,"column":6},"end":{"line":47,"column":null}}],"line":45},"1":{"loc":{"start":{"line":49,"column":9},"end":{"line":49,"column":null}},"type":"cond-expr","locations":[{"start":{"line":49,"column":35},"end":{"line":49,"column":44}},{"start":{"line":49,"column":44},"end":{"line":49,"column":null}}],"line":49},"2":{"loc":{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"3":{"loc":{"start":{"line":55,"column":9},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":35},"end":{"line":55,"column":44}},{"start":{"line":55,"column":44},"end":{"line":55,"column":null}}],"line":55},"4":{"loc":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"5":{"loc":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":76},"6":{"loc":{"start":{"line":85,"column":34},"end":{"line":85,"column":48}},"type":"binary-expr","locations":[{"start":{"line":85,"column":34},"end":{"line":85,"column":46}},{"start":{"line":85,"column":46},"end":{"line":85,"column":48}}],"line":85},"7":{"loc":{"start":{"line":92,"column":9},"end":{"line":92,"column":null}},"type":"cond-expr","locations":[{"start":{"line":92,"column":17},"end":{"line":92,"column":45}},{"start":{"line":92,"column":45},"end":{"line":92,"column":null}}],"line":92},"8":{"loc":{"start":{"line":92,"column":27},"end":{"line":92,"column":41}},"type":"binary-expr","locations":[{"start":{"line":92,"column":27},"end":{"line":92,"column":39}},{"start":{"line":92,"column":39},"end":{"line":92,"column":41}}],"line":92},"9":{"loc":{"start":{"line":99,"column":25},"end":{"line":99,"column":39}},"type":"binary-expr","locations":[{"start":{"line":99,"column":25},"end":{"line":99,"column":37}},{"start":{"line":99,"column":37},"end":{"line":99,"column":39}}],"line":99}},"s":{"0":24,"1":7,"2":1500,"3":41,"4":317,"5":285,"6":57,"7":57,"8":57,"9":57,"10":73,"11":33,"12":40,"13":40,"14":34,"15":34,"16":134,"17":34,"18":238,"19":238,"20":768,"21":768,"22":132,"23":106,"24":330,"25":1616,"26":37,"27":69,"28":82,"29":82,"30":82,"31":148,"32":82,"33":70,"34":70,"35":33,"36":33,"37":33,"38":33,"39":33},"f":{"0":24,"1":7,"2":1500,"3":41,"4":317,"5":285,"6":57,"7":73,"8":34,"9":238,"10":1616,"11":82,"12":70,"13":33},"b":{"0":[4,53],"1":[40,17],"2":[33,40],"3":[40,0],"4":[132,636],"5":[37,293],"6":[148,0],"7":[70,0],"8":[70,0],"9":[33,0]},"meta":{"lastBranch":10,"lastFunction":14,"lastStatement":40,"seen":{"f:15:16:15:34":0,"s:16:2:16:Infinity":0,"f:19:16:19:36":1,"s:20:2:20:Infinity":1,"f:23:16:23:29":2,"s:24:2:28:Infinity":2,"f:31:16:31:32":3,"s:32:2:32:Infinity":3,"f:35:16:35:27":4,"s:36:2:36:Infinity":4,"f:39:16:39:26":5,"s:40:2:40:Infinity":5,"f:43:16:43:48":6,"s:44:18:44:Infinity":6,"s:45:21:47:Infinity":7,"b:46:6:46:Infinity:47:6:47:Infinity":0,"s:48:17:48:Infinity":8,"s:49:2:49:Infinity":9,"b:49:35:49:44:49:44:49:Infinity":1,"f:52:16:52:46":7,"b:53:2:53:Infinity:undefined:undefined:undefined:undefined":2,"s:53:2:53:Infinity":10,"s:53:14:53:Infinity":11,"s:54:17:54:Infinity":12,"s:55:2:55:Infinity":13,"b:55:35:55:44:55:44:55:Infinity":3,"f:58:16:58:34":8,"s:59:17:59:Infinity":14,"s:60:2:62:Infinity":15,"s:61:4:61:Infinity":16,"s:63:2:63:Infinity":17,"f:66:16:66:Infinity":9,"s:70:31:70:Infinity":18,"s:71:2:74:Infinity":19,"s:72:18:72:Infinity":20,"b:73:4:73:Infinity:undefined:undefined:undefined:undefined":4,"s:73:4:73:Infinity":21,"s:73:29:73:Infinity":22,"s:75:2:77:Infinity":23,"b:76:4:76:Infinity:undefined:undefined:undefined:undefined":5,"s:76:4:76:Infinity":24,"f:76:29:76:35":10,"s:76:49:76:72":25,"s:76:75:76:Infinity":26,"s:78:2:78:Infinity":27,"f:81:16:81:35":11,"s:82:16:82:Infinity":28,"s:83:17:83:Infinity":29,"s:84:2:86:Infinity":30,"s:85:4:85:Infinity":31,"b:85:34:85:46:85:46:85:48":6,"s:87:2:87:Infinity":32,"f:90:16:90:33":12,"s:91:16:91:Infinity":33,"s:92:2:92:Infinity":34,"b:92:17:92:45:92:45:92:Infinity":7,"b:92:27:92:39:92:39:92:41":8,"f:95:16:95:33":13,"s:96:26:96:Infinity":35,"s:97:17:97:Infinity":36,"s:98:2:100:Infinity":37,"s:99:4:99:Infinity":38,"b:99:25:99:37:99:37:99:39":9,"s:101:2:101:Infinity":39}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/source-registry.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/source-registry.ts","statementMap":{"0":{"start":{"line":18,"column":38},"end":{"line":18,"column":null}},"1":{"start":{"line":20,"column":79},"end":{"line":53,"column":null}},"2":{"start":{"line":56,"column":17},"end":{"line":56,"column":null}},"3":{"start":{"line":56,"column":59},"end":{"line":56,"column":80}},"4":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"5":{"start":{"line":57,"column":15},"end":{"line":57,"column":null}},"6":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"getStatskontoretSource","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":39}},"loc":{"start":{"line":55,"column":99},"end":{"line":59,"column":null}},"line":55},"1":{"name":"(anonymous_1)","decl":{"start":{"line":56,"column":39},"end":{"line":56,"column":45}},"loc":{"start":{"line":56,"column":59},"end":{"line":56,"column":80}},"line":56}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":57}},"s":{"0":4,"1":4,"2":9,"3":26,"4":9,"5":2,"6":7},"f":{"0":9,"1":26},"b":{"0":[2,7]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":7,"seen":{"s:18:38:18:Infinity":0,"s:20:79:53:Infinity":1,"f:55:16:55:39":0,"s:56:17:56:Infinity":2,"f:56:39:56:45":1,"s:56:59:56:80":3,"b:57:2:57:Infinity:undefined:undefined:undefined:undefined":0,"s:57:2:57:Infinity":4,"s:57:15:57:Infinity":5,"s:58:2:58:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/xlsx.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/statskontoret/parsers/xlsx.ts","statementMap":{"0":{"start":{"line":27,"column":14},"end":{"line":27,"column":null}},"1":{"start":{"line":28,"column":22},"end":{"line":28,"column":null}},"2":{"start":{"line":29,"column":26},"end":{"line":29,"column":null}},"3":{"start":{"line":30,"column":27},"end":{"line":32,"column":null}},"4":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"5":{"start":{"line":34,"column":15},"end":{"line":34,"column":null}},"6":{"start":{"line":35,"column":39},"end":{"line":35,"column":null}},"7":{"start":{"line":37,"column":2},"end":{"line":43,"column":null}},"8":{"start":{"line":38,"column":19},"end":{"line":38,"column":null}},"9":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"10":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"11":{"start":{"line":40,"column":22},"end":{"line":40,"column":null}},"12":{"start":{"line":41,"column":21},"end":{"line":41,"column":null}},"13":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"14":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"15":{"start":{"line":49,"column":66},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":18},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":2},"end":{"line":56,"column":null}},"18":{"start":{"line":52,"column":18},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":17},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"21":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"22":{"start":{"line":55,"column":32},"end":{"line":55,"column":null}},"23":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"24":{"start":{"line":61,"column":15},"end":{"line":61,"column":null}},"25":{"start":{"line":62,"column":16},"end":{"line":62,"column":null}},"26":{"start":{"line":63,"column":2},"end":{"line":68,"column":null}},"27":{"start":{"line":64,"column":18},"end":{"line":64,"column":null}},"28":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"29":{"start":{"line":66,"column":19},"end":{"line":66,"column":null}},"30":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"31":{"start":{"line":67,"column":22},"end":{"line":67,"column":null}},"32":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"33":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"34":{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},"35":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"36":{"start":{"line":75,"column":15},"end":{"line":75,"column":null}},"37":{"start":{"line":76,"column":2},"end":{"line":78,"column":null}},"38":{"start":{"line":77,"column":4},"end":{"line":77,"column":null}},"39":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}},"40":{"start":{"line":83,"column":27},"end":{"line":83,"column":null}},"41":{"start":{"line":84,"column":16},"end":{"line":84,"column":null}},"42":{"start":{"line":85,"column":2},"end":{"line":95,"column":null}},"43":{"start":{"line":86,"column":26},"end":{"line":86,"column":null}},"44":{"start":{"line":87,"column":19},"end":{"line":87,"column":null}},"45":{"start":{"line":88,"column":4},"end":{"line":93,"column":null}},"46":{"start":{"line":89,"column":20},"end":{"line":89,"column":null}},"47":{"start":{"line":90,"column":18},"end":{"line":90,"column":null}},"48":{"start":{"line":91,"column":24},"end":{"line":91,"column":null}},"49":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"50":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"51":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"52":{"start":{"line":96,"column":2},"end":{"line":96,"column":null}},"53":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"54":{"start":{"line":104,"column":28},"end":{"line":104,"column":null}},"55":{"start":{"line":105,"column":16},"end":{"line":105,"column":null}},"56":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"57":{"start":{"line":106,"column":27},"end":{"line":106,"column":null}},"58":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"59":{"start":{"line":107,"column":20},"end":{"line":107,"column":null}},"60":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}},"61":{"start":{"line":112,"column":18},"end":{"line":112,"column":null}},"62":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"63":{"start":{"line":113,"column":16},"end":{"line":113,"column":null}},"64":{"start":{"line":114,"column":14},"end":{"line":114,"column":null}},"65":{"start":{"line":115,"column":2},"end":{"line":117,"column":null}},"66":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"67":{"start":{"line":118,"column":2},"end":{"line":118,"column":null}},"68":{"start":{"line":122,"column":15},"end":{"line":122,"column":null}},"69":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"70":{"start":{"line":123,"column":13},"end":{"line":123,"column":null}},"71":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}}},"fnMap":{"0":{"name":"parseStatskontoretXlsx","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":null}},"loc":{"start":{"line":26,"column":34},"end":{"line":46,"column":null}},"line":26},"1":{"name":"parseWorkbookSheets","decl":{"start":{"line":48,"column":9},"end":{"line":48,"column":29}},"loc":{"start":{"line":48,"column":91},"end":{"line":58,"column":null}},"line":48},"2":{"name":"parseWorkbookRelationships","decl":{"start":{"line":60,"column":9},"end":{"line":60,"column":36}},"loc":{"start":{"line":60,"column":70},"end":{"line":70,"column":null}},"line":60},"3":{"name":"parseSharedStrings","decl":{"start":{"line":72,"column":9},"end":{"line":72,"column":28}},"loc":{"start":{"line":72,"column":51},"end":{"line":80,"column":null}},"line":72},"4":{"name":"parseWorksheetRows","decl":{"start":{"line":82,"column":9},"end":{"line":82,"column":28}},"loc":{"start":{"line":82,"column":87},"end":{"line":97,"column":null}},"line":82},"5":{"name":"(anonymous_5)","decl":{"start":{"line":94,"column":46},"end":{"line":94,"column":50}},"loc":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"line":94},"6":{"name":"parseCellValue","decl":{"start":{"line":99,"column":9},"end":{"line":99,"column":null}},"loc":{"start":{"line":103,"column":10},"end":{"line":109,"column":null}},"line":103},"7":{"name":"cellRefToColumnIndex","decl":{"start":{"line":111,"column":9},"end":{"line":111,"column":30}},"loc":{"start":{"line":111,"column":63},"end":{"line":119,"column":null}},"line":111},"8":{"name":"readZipText","decl":{"start":{"line":121,"column":15},"end":{"line":121,"column":27}},"loc":{"start":{"line":121,"column":70},"end":{"line":125,"column":null}},"line":121}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":27},"end":{"line":32,"column":null}},"type":"cond-expr","locations":[{"start":{"line":31,"column":6},"end":{"line":31,"column":null}},{"start":{"line":32,"column":6},"end":{"line":32,"column":null}}],"line":30},"1":{"loc":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"2":{"loc":{"start":{"line":40,"column":22},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":47},"end":{"line":40,"column":65}},{"start":{"line":40,"column":65},"end":{"line":40,"column":null}}],"line":40},"3":{"loc":{"start":{"line":52,"column":37},"end":{"line":52,"column":51}},"type":"binary-expr","locations":[{"start":{"line":52,"column":37},"end":{"line":52,"column":49}},{"start":{"line":52,"column":49},"end":{"line":52,"column":51}}],"line":52},"4":{"loc":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"type":"binary-expr","locations":[{"start":{"line":54,"column":27},"end":{"line":54,"column":48}},{"start":{"line":54,"column":48},"end":{"line":54,"column":null}}],"line":54},"5":{"loc":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":55},"6":{"loc":{"start":{"line":55,"column":8},"end":{"line":55,"column":32}},"type":"binary-expr","locations":[{"start":{"line":55,"column":8},"end":{"line":55,"column":16}},{"start":{"line":55,"column":16},"end":{"line":55,"column":32}}],"line":55},"7":{"loc":{"start":{"line":64,"column":37},"end":{"line":64,"column":51}},"type":"binary-expr","locations":[{"start":{"line":64,"column":37},"end":{"line":64,"column":49}},{"start":{"line":64,"column":49},"end":{"line":64,"column":51}}],"line":64},"8":{"loc":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},{"start":{},"end":{}}],"line":67},"9":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":22}},"type":"binary-expr","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":14}},{"start":{"line":67,"column":14},"end":{"line":67,"column":22}}],"line":67},"10":{"loc":{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"11":{"loc":{"start":{"line":77,"column":34},"end":{"line":77,"column":48}},"type":"binary-expr","locations":[{"start":{"line":77,"column":34},"end":{"line":77,"column":46}},{"start":{"line":77,"column":46},"end":{"line":77,"column":48}}],"line":77},"12":{"loc":{"start":{"line":88,"column":29},"end":{"line":88,"column":46}},"type":"binary-expr","locations":[{"start":{"line":88,"column":29},"end":{"line":88,"column":44}},{"start":{"line":88,"column":44},"end":{"line":88,"column":46}}],"line":88},"13":{"loc":{"start":{"line":89,"column":39},"end":{"line":89,"column":57}},"type":"binary-expr","locations":[{"start":{"line":89,"column":39},"end":{"line":89,"column":55}},{"start":{"line":89,"column":55},"end":{"line":89,"column":57}}],"line":89},"14":{"loc":{"start":{"line":90,"column":18},"end":{"line":90,"column":null}},"type":"binary-expr","locations":[{"start":{"line":90,"column":18},"end":{"line":90,"column":36}},{"start":{"line":90,"column":36},"end":{"line":90,"column":null}}],"line":90},"15":{"loc":{"start":{"line":91,"column":24},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":91,"column":24},"end":{"line":91,"column":53}},{"start":{"line":91,"column":53},"end":{"line":91,"column":null}}],"line":91},"16":{"loc":{"start":{"line":92,"column":38},"end":{"line":92,"column":58}},"type":"binary-expr","locations":[{"start":{"line":92,"column":38},"end":{"line":92,"column":54}},{"start":{"line":92,"column":54},"end":{"line":92,"column":58}}],"line":92},"17":{"loc":{"start":{"line":94,"column":59},"end":{"line":94,"column":71}},"type":"binary-expr","locations":[{"start":{"line":94,"column":59},"end":{"line":94,"column":69}},{"start":{"line":94,"column":69},"end":{"line":94,"column":71}}],"line":94},"18":{"loc":{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":2},"end":{"line":104,"column":null}},{"start":{},"end":{}}],"line":104},"19":{"loc":{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":106},"20":{"loc":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":2},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":107},"21":{"loc":{"start":{"line":107,"column":27},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":107,"column":27},"end":{"line":107,"column":72}},{"start":{"line":107,"column":72},"end":{"line":107,"column":null}}],"line":107},"22":{"loc":{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":2},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":113},"23":{"loc":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":123}},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":5,"6":5,"7":5,"8":6,"9":6,"10":0,"11":6,"12":6,"13":6,"14":5,"15":5,"16":5,"17":5,"18":6,"19":6,"20":6,"21":6,"22":6,"23":5,"24":5,"25":5,"26":5,"27":6,"28":6,"29":6,"30":6,"31":6,"32":5,"33":5,"34":1,"35":4,"36":4,"37":4,"38":33,"39":4,"40":6,"41":6,"42":6,"43":20,"44":20,"45":20,"46":70,"47":70,"48":70,"49":70,"50":20,"51":71,"52":6,"53":70,"54":0,"55":70,"56":70,"57":0,"58":70,"59":42,"60":28,"61":70,"62":70,"63":0,"64":70,"65":70,"66":70,"67":70,"68":20,"69":20,"70":0,"71":20},"f":{"0":5,"1":5,"2":5,"3":5,"4":6,"5":71,"6":70,"7":70,"8":20},"b":{"0":[4,1],"1":[0,6],"2":[0,6],"3":[6,0],"4":[6,0],"5":[6,0],"6":[6,6],"7":[6,0],"8":[6,0],"9":[6,6],"10":[1,4],"11":[33,0],"12":[20,0],"13":[70,0],"14":[70,0],"15":[70,0],"16":[70,0],"17":[71,1],"18":[0,70],"19":[0,70],"20":[42,28],"21":[42,0],"22":[0,70],"23":[0,20]},"meta":{"lastBranch":24,"lastFunction":9,"lastStatement":72,"seen":{"f:24:22:24:Infinity":0,"s:27:14:27:Infinity":0,"s:28:22:28:Infinity":1,"s:29:26:29:Infinity":2,"s:30:27:32:Infinity":3,"b:31:6:31:Infinity:32:6:32:Infinity":0,"s:33:24:33:Infinity":4,"s:34:15:34:Infinity":5,"s:35:39:35:Infinity":6,"s:37:2:43:Infinity":7,"s:38:19:38:Infinity":8,"b:39:4:39:Infinity:undefined:undefined:undefined:undefined":1,"s:39:4:39:Infinity":9,"s:39:17:39:Infinity":10,"s:40:22:40:Infinity":11,"b:40:47:40:65:40:65:40:Infinity":2,"s:41:21:41:Infinity":12,"s:42:4:42:Infinity":13,"s:45:2:45:Infinity":14,"f:48:9:48:29":1,"s:49:66:49:Infinity":15,"s:50:18:50:Infinity":16,"s:51:2:56:Infinity":17,"s:52:18:52:Infinity":18,"b:52:37:52:49:52:49:52:51":3,"s:53:17:53:Infinity":19,"s:54:27:54:Infinity":20,"b:54:27:54:48:54:48:54:Infinity":4,"b:55:4:55:Infinity:undefined:undefined:undefined:undefined":5,"s:55:4:55:Infinity":21,"b:55:8:55:16:55:16:55:32":6,"s:55:32:55:Infinity":22,"s:57:2:57:Infinity":23,"f:60:9:60:36":2,"s:61:15:61:Infinity":24,"s:62:16:62:Infinity":25,"s:63:2:68:Infinity":26,"s:64:18:64:Infinity":27,"b:64:37:64:49:64:49:64:51":7,"s:65:15:65:Infinity":28,"s:66:19:66:Infinity":29,"b:67:4:67:Infinity:undefined:undefined:undefined:undefined":8,"s:67:4:67:Infinity":30,"b:67:8:67:14:67:14:67:22":9,"s:67:22:67:Infinity":31,"s:69:2:69:Infinity":32,"f:72:9:72:28":3,"b:73:2:73:Infinity:undefined:undefined:undefined:undefined":10,"s:73:2:73:Infinity":33,"s:73:12:73:Infinity":34,"s:74:28:74:Infinity":35,"s:75:15:75:Infinity":36,"s:76:2:78:Infinity":37,"s:77:4:77:Infinity":38,"b:77:34:77:46:77:46:77:48":11,"s:79:2:79:Infinity":39,"f:82:9:82:28":4,"s:83:27:83:Infinity":40,"s:84:16:84:Infinity":41,"s:85:2:95:Infinity":42,"s:86:26:86:Infinity":43,"s:87:19:87:Infinity":44,"s:88:4:93:Infinity":45,"b:88:29:88:44:88:44:88:46":12,"s:89:20:89:Infinity":46,"b:89:39:89:55:89:55:89:57":13,"s:90:18:90:Infinity":47,"b:90:18:90:36:90:36:90:Infinity":14,"s:91:24:91:Infinity":48,"b:91:24:91:53:91:53:91:Infinity":15,"s:92:6:92:Infinity":49,"b:92:38:92:54:92:54:92:58":16,"s:94:4:94:Infinity":50,"f:94:46:94:50":5,"s:94:59:94:71":51,"b:94:59:94:69:94:69:94:71":17,"s:96:2:96:Infinity":52,"f:99:9:99:Infinity":6,"b:104:2:104:Infinity:undefined:undefined:undefined:undefined":18,"s:104:2:104:Infinity":53,"s:104:28:104:Infinity":54,"s:105:16:105:Infinity":55,"b:106:2:106:Infinity:undefined:undefined:undefined:undefined":19,"s:106:2:106:Infinity":56,"s:106:27:106:Infinity":57,"b:107:2:107:Infinity:undefined:undefined:undefined:undefined":20,"s:107:2:107:Infinity":58,"s:107:20:107:Infinity":59,"b:107:27:107:72:107:72:107:Infinity":21,"s:108:2:108:Infinity":60,"f:111:9:111:30":7,"s:112:18:112:Infinity":61,"b:113:2:113:Infinity:undefined:undefined:undefined:undefined":22,"s:113:2:113:Infinity":62,"s:113:16:113:Infinity":63,"s:114:14:114:Infinity":64,"s:115:2:117:Infinity":65,"s:116:4:116:Infinity":66,"s:118:2:118:Infinity":67,"f:121:15:121:27":8,"s:122:15:122:Infinity":68,"b:123:2:123:Infinity:undefined:undefined:undefined:undefined":23,"s:123:2:123:Infinity":69,"s:123:13:123:Infinity":70,"s:124:2:124:Infinity":71}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/banned-phrases.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/banned-phrases.ts","statementMap":{"0":{"start":{"line":24,"column":43},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":32},"end":{"line":25,"column":null}},"2":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"3":{"start":{"line":34,"column":33},"end":{"line":34,"column":null}},"4":{"start":{"line":35,"column":19},"end":{"line":35,"column":null}},"5":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"6":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":4},"end":{"line":38,"column":null}},"8":{"start":{"line":39,"column":4},"end":{"line":39,"column":null}},"9":{"start":{"line":41,"column":2},"end":{"line":61,"column":null}},"10":{"start":{"line":42,"column":17},"end":{"line":42,"column":null}},"11":{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},"12":{"start":{"line":44,"column":6},"end":{"line":44,"column":null}},"13":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"14":{"start":{"line":47,"column":32},"end":{"line":47,"column":null}},"15":{"start":{"line":48,"column":6},"end":{"line":56,"column":null}},"16":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"17":{"start":{"line":49,"column":38},"end":{"line":49,"column":null}},"18":{"start":{"line":50,"column":24},"end":{"line":50,"column":null}},"19":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"20":{"start":{"line":51,"column":34},"end":{"line":51,"column":null}},"21":{"start":{"line":52,"column":20},"end":{"line":52,"column":null}},"22":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"23":{"start":{"line":53,"column":27},"end":{"line":53,"column":null}},"24":{"start":{"line":54,"column":8},"end":{"line":54,"column":null}},"25":{"start":{"line":55,"column":8},"end":{"line":55,"column":null}},"26":{"start":{"line":57,"column":6},"end":{"line":57,"column":null}},"27":{"start":{"line":60,"column":4},"end":{"line":60,"column":null}},"28":{"start":{"line":62,"column":2},"end":{"line":62,"column":null}},"29":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"30":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"31":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"32":{"start":{"line":80,"column":59},"end":{"line":80,"column":null}},"33":{"start":{"line":81,"column":16},"end":{"line":81,"column":null}},"34":{"start":{"line":82,"column":2},"end":{"line":94,"column":null}},"35":{"start":{"line":83,"column":20},"end":{"line":83,"column":null}},"36":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"37":{"start":{"line":84,"column":30},"end":{"line":84,"column":null}},"38":{"start":{"line":85,"column":19},"end":{"line":85,"column":null}},"39":{"start":{"line":86,"column":14},"end":{"line":86,"column":null}},"40":{"start":{"line":87,"column":4},"end":{"line":93,"column":null}},"41":{"start":{"line":88,"column":20},"end":{"line":88,"column":null}},"42":{"start":{"line":89,"column":18},"end":{"line":89,"column":null}},"43":{"start":{"line":90,"column":22},"end":{"line":90,"column":null}},"44":{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},"45":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"46":{"start":{"line":95,"column":2},"end":{"line":95,"column":null}},"47":{"start":{"line":102,"column":34},"end":{"line":102,"column":null}},"48":{"start":{"line":103,"column":24},"end":{"line":103,"column":null}},"49":{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},"50":{"start":{"line":105,"column":4},"end":{"line":109,"column":null}},"51":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"52":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"53":{"start":{"line":112,"column":34},"end":{"line":112,"column":null}},"54":{"start":{"line":113,"column":15},"end":{"line":113,"column":null}},"55":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},"56":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"57":{"start":{"line":115,"column":47},"end":{"line":115,"column":62}},"58":{"start":{"line":116,"column":4},"end":{"line":120,"column":null}},"59":{"start":{"line":122,"column":2},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"loadBannedPhrases","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":34}},"loc":{"start":{"line":33,"column":81},"end":{"line":64,"column":null}},"line":33},"1":{"name":"resetBannedPhrasesCache","decl":{"start":{"line":67,"column":16},"end":{"line":67,"column":48}},"loc":{"start":{"line":67,"column":48},"end":{"line":70,"column":null}},"line":67},"2":{"name":"scanBannedPhrases","decl":{"start":{"line":76,"column":16},"end":{"line":76,"column":null}},"loc":{"start":{"line":79,"column":46},"end":{"line":96,"column":null}},"line":79},"3":{"name":"checkBannedPhrases","decl":{"start":{"line":101,"column":16},"end":{"line":101,"column":35}},"loc":{"start":{"line":101,"column":82},"end":{"line":123,"column":null}},"line":101},"4":{"name":"(anonymous_4)","decl":{"start":{"line":115,"column":36},"end":{"line":115,"column":41}},"loc":{"start":{"line":115,"column":47},"end":{"line":115,"column":62}},"line":115}},"branchMap":{"0":{"loc":{"start":{"line":33,"column":34},"end":{"line":33,"column":81}},"type":"default-arg","locations":[{"start":{"line":33,"column":53},"end":{"line":33,"column":81}}],"line":33},"1":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34},"2":{"loc":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},{"start":{},"end":{}}],"line":36},"3":{"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},"type":"if","locations":[{"start":{"line":43,"column":4},"end":{"line":58,"column":null}},{"start":{"line":45,"column":11},"end":{"line":58,"column":null}}],"line":43},"4":{"loc":{"start":{"line":43,"column":8},"end":{"line":43,"column":73}},"type":"binary-expr","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":43}},{"start":{"line":43,"column":43},"end":{"line":43,"column":73}}],"line":43},"5":{"loc":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"6":{"loc":{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":null}},{"start":{},"end":{}}],"line":51},"7":{"loc":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"8":{"loc":{"start":{"line":57,"column":28},"end":{"line":57,"column":null}},"type":"cond-expr","locations":[{"start":{"line":57,"column":49},"end":{"line":57,"column":59}},{"start":{"line":57,"column":59},"end":{"line":57,"column":null}}],"line":57},"9":{"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"10":{"loc":{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},"type":"if","locations":[{"start":{"line":104,"column":2},"end":{"line":111,"column":null}},{"start":{},"end":{}}],"line":104},"11":{"loc":{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},"type":"if","locations":[{"start":{"line":112,"column":2},"end":{"line":112,"column":null}},{"start":{},"end":{}}],"line":112},"12":{"loc":{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":114,"column":2},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":114},"13":{"loc":{"start":{"line":119,"column":77},"end":{"line":119,"column":106}},"type":"cond-expr","locations":[{"start":{"line":119,"column":95},"end":{"line":119,"column":103}},{"start":{"line":119,"column":103},"end":{"line":119,"column":106}}],"line":119}},"s":{"0":2,"1":2,"2":10,"3":1,"4":9,"5":9,"6":2,"7":2,"8":2,"9":7,"10":7,"11":7,"12":1,"13":5,"14":5,"15":5,"16":242,"17":1,"18":241,"19":241,"20":1,"21":240,"22":240,"23":2,"24":238,"25":238,"26":5,"27":1,"28":7,"29":7,"30":16,"31":16,"32":7,"33":7,"34":7,"35":133,"36":133,"37":2,"38":131,"39":131,"40":131,"41":6,"42":6,"43":6,"44":6,"45":6,"46":7,"47":2,"48":2,"49":2,"50":0,"51":0,"52":2,"53":0,"54":2,"55":2,"56":1,"57":1,"58":1,"59":2},"f":{"0":10,"1":16,"2":7,"3":2,"4":1},"b":{"0":[10],"1":[1,9],"2":[2,7],"3":[1,5],"4":[7,5],"5":[1,241],"6":[1,240],"7":[2,238],"8":[5,0],"9":[2,131],"10":[0,2],"11":[0,2],"12":[1,1],"13":[0,1]},"meta":{"lastBranch":14,"lastFunction":5,"lastStatement":60,"seen":{"s:24:43:24:Infinity":0,"s:25:32:25:Infinity":1,"f:33:16:33:34":0,"b:33:53:33:81":0,"b:34:2:34:Infinity:undefined:undefined:undefined:undefined":1,"s:34:2:34:Infinity":2,"s:34:33:34:Infinity":3,"s:35:19:35:Infinity":4,"b:36:2:40:Infinity:undefined:undefined:undefined:undefined":2,"s:36:2:40:Infinity":5,"s:37:4:37:Infinity":6,"s:38:4:38:Infinity":7,"s:39:4:39:Infinity":8,"s:41:2:61:Infinity":9,"s:42:17:42:Infinity":10,"b:43:4:58:Infinity:45:11:58:Infinity":3,"s:43:4:58:Infinity":11,"b:43:8:43:43:43:43:43:73":4,"s:44:6:44:Infinity":12,"s:46:19:46:Infinity":13,"s:47:32:47:Infinity":14,"s:48:6:56:Infinity":15,"b:49:8:49:Infinity:undefined:undefined:undefined:undefined":5,"s:49:8:49:Infinity":16,"s:49:38:49:Infinity":17,"s:50:24:50:Infinity":18,"b:51:8:51:Infinity:undefined:undefined:undefined:undefined":6,"s:51:8:51:Infinity":19,"s:51:34:51:Infinity":20,"s:52:20:52:Infinity":21,"b:53:8:53:Infinity:undefined:undefined:undefined:undefined":7,"s:53:8:53:Infinity":22,"s:53:27:53:Infinity":23,"s:54:8:54:Infinity":24,"s:55:8:55:Infinity":25,"s:57:6:57:Infinity":26,"b:57:49:57:59:57:59:57:Infinity":8,"s:60:4:60:Infinity":27,"s:62:2:62:Infinity":28,"s:63:2:63:Infinity":29,"f:67:16:67:48":1,"s:68:2:68:Infinity":30,"s:69:2:69:Infinity":31,"f:76:16:76:Infinity":2,"s:80:59:80:Infinity":32,"s:81:16:81:Infinity":33,"s:82:2:94:Infinity":34,"s:83:20:83:Infinity":35,"b:84:4:84:Infinity:undefined:undefined:undefined:undefined":9,"s:84:4:84:Infinity":36,"s:84:30:84:Infinity":37,"s:85:19:85:Infinity":38,"s:86:14:86:Infinity":39,"s:87:4:93:Infinity":40,"s:88:20:88:Infinity":41,"s:89:18:89:Infinity":42,"s:90:22:90:Infinity":43,"s:91:6:91:Infinity":44,"s:92:6:92:Infinity":45,"s:95:2:95:Infinity":46,"f:101:16:101:35":3,"s:102:34:102:Infinity":47,"s:103:24:103:Infinity":48,"b:104:2:111:Infinity:undefined:undefined:undefined:undefined":10,"s:104:2:111:Infinity":49,"s:105:4:109:Infinity":50,"s:110:4:110:Infinity":51,"b:112:2:112:Infinity:undefined:undefined:undefined:undefined":11,"s:112:2:112:Infinity":52,"s:112:34:112:Infinity":53,"s:113:15:113:Infinity":54,"b:114:2:121:Infinity:undefined:undefined:undefined:undefined":12,"s:114:2:121:Infinity":55,"s:115:19:115:Infinity":56,"f:115:36:115:41":4,"s:115:47:115:62":57,"s:116:4:120:Infinity":58,"b:119:95:119:103:119:103:119:106":13,"s:122:2:122:Infinity":59}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/bluf.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/bluf.ts","statementMap":{"0":{"start":{"line":16,"column":36},"end":{"line":16,"column":null}},"1":{"start":{"line":17,"column":36},"end":{"line":17,"column":null}},"2":{"start":{"line":33,"column":41},"end":{"line":33,"column":null}},"3":{"start":{"line":43,"column":12},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"5":{"start":{"line":44,"column":10},"end":{"line":44,"column":null}},"6":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"7":{"start":{"line":45,"column":52},"end":{"line":45,"column":60}},"8":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"9":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"10":{"start":{"line":62,"column":29},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":14},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":2},"end":{"line":74,"column":null}},"13":{"start":{"line":72,"column":20},"end":{"line":72,"column":null}},"14":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"15":{"start":{"line":73,"column":17},"end":{"line":73,"column":null}},"16":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"17":{"start":{"line":82,"column":15},"end":{"line":82,"column":null}},"18":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"19":{"start":{"line":83,"column":21},"end":{"line":83,"column":null}},"20":{"start":{"line":84,"column":34},"end":{"line":84,"column":null}},"21":{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},"22":{"start":{"line":86,"column":4},"end":{"line":90,"column":null}},"23":{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},"24":{"start":{"line":93,"column":4},"end":{"line":97,"column":null}},"25":{"start":{"line":99,"column":18},"end":{"line":99,"column":null}},"26":{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},"27":{"start":{"line":101,"column":4},"end":{"line":105,"column":null}},"28":{"start":{"line":107,"column":2},"end":{"line":107,"column":null}}},"fnMap":{"0":{"name":"extractBluf","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":28}},"loc":{"start":{"line":42,"column":60},"end":{"line":47,"column":null}},"line":42},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":41},"end":{"line":45,"column":46}},"loc":{"start":{"line":45,"column":52},"end":{"line":45,"column":60}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":45,"column":62},"end":{"line":45,"column":68}},"loc":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"line":45},"3":{"name":"countBlufEvidenceAnchors","decl":{"start":{"line":61,"column":16},"end":{"line":61,"column":41}},"loc":{"start":{"line":61,"column":63},"end":{"line":76,"column":null}},"line":61},"4":{"name":"checkBluf","decl":{"start":{"line":81,"column":16},"end":{"line":81,"column":26}},"loc":{"start":{"line":81,"column":73},"end":{"line":108,"column":null}},"line":81}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":2},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":45,"column":74},"end":{"line":45,"column":109}},"type":"binary-expr","locations":[{"start":{"line":45,"column":74},"end":{"line":45,"column":90}},{"start":{"line":45,"column":90},"end":{"line":45,"column":109}}],"line":45},"2":{"loc":{"start":{"line":46,"column":9},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":9},"end":{"line":46,"column":22}},{"start":{"line":46,"column":22},"end":{"line":46,"column":null}}],"line":46},"3":{"loc":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":73},"4":{"loc":{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":2},"end":{"line":83,"column":null}},{"start":{},"end":{}}],"line":83},"5":{"loc":{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":85,"column":2},"end":{"line":91,"column":null}},{"start":{},"end":{}}],"line":85},"6":{"loc":{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":92,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":92},"7":{"loc":{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":2},"end":{"line":106,"column":null}},{"start":{},"end":{}}],"line":100}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":2,"6":10,"7":10,"8":10,"9":10,"10":14,"11":14,"12":14,"13":84,"14":84,"15":15,"16":14,"17":5,"18":5,"19":1,"20":4,"21":4,"22":1,"23":4,"24":1,"25":4,"26":4,"27":1,"28":4},"f":{"0":12,"1":10,"2":10,"3":14,"4":5},"b":{"0":[2,10],"1":[10,10],"2":[10,3],"3":[15,69],"4":[1,4],"5":[1,3],"6":[1,3],"7":[1,3]},"meta":{"lastBranch":8,"lastFunction":5,"lastStatement":29,"seen":{"s:16:36:16:Infinity":0,"s:17:36:17:Infinity":1,"s:33:41:33:Infinity":2,"f:42:16:42:28":0,"s:43:12:43:Infinity":3,"b:44:2:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:2:44:Infinity":4,"s:44:10:44:Infinity":5,"s:45:20:45:Infinity":6,"f:45:41:45:46":1,"s:45:52:45:60":7,"f:45:62:45:68":2,"s:45:74:45:109":8,"b:45:74:45:90:45:90:45:109":1,"s:46:2:46:Infinity":9,"b:46:9:46:22:46:22:46:Infinity":2,"f:61:16:61:41":3,"s:62:29:69:Infinity":10,"s:70:14:70:Infinity":11,"s:71:2:74:Infinity":12,"s:72:20:72:Infinity":13,"b:73:4:73:Infinity:undefined:undefined:undefined:undefined":3,"s:73:4:73:Infinity":14,"s:73:17:73:Infinity":15,"s:75:2:75:Infinity":16,"f:81:16:81:26":4,"s:82:15:82:Infinity":17,"b:83:2:83:Infinity:undefined:undefined:undefined:undefined":4,"s:83:2:83:Infinity":18,"s:83:21:83:Infinity":19,"s:84:34:84:Infinity":20,"b:85:2:91:Infinity:undefined:undefined:undefined:undefined":5,"s:85:2:91:Infinity":21,"s:86:4:90:Infinity":22,"b:92:2:98:Infinity:undefined:undefined:undefined:undefined":6,"s:92:2:98:Infinity":23,"s:93:4:97:Infinity":24,"s:99:18:99:Infinity":25,"b:100:2:106:Infinity:undefined:undefined:undefined:undefined":7,"s:100:2:106:Infinity":26,"s:101:4:105:Infinity":27,"s:107:2:107:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/citation-density.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/citation-density.ts","statementMap":{"0":{"start":{"line":22,"column":16},"end":{"line":22,"column":null}},"1":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":24,"column":null}},"3":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"4":{"start":{"line":26,"column":13},"end":{"line":26,"column":null}},"5":{"start":{"line":27,"column":2},"end":{"line":30,"column":null}},"6":{"start":{"line":28,"column":4},"end":{"line":28,"column":null}},"7":{"start":{"line":29,"column":4},"end":{"line":29,"column":null}},"8":{"start":{"line":31,"column":2},"end":{"line":31,"column":null}},"9":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"10":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"11":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"12":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"13":{"start":{"line":35,"column":51},"end":{"line":35,"column":63}},"14":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}},"15":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"16":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"17":{"start":{"line":45,"column":21},"end":{"line":45,"column":null}},"18":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"19":{"start":{"line":47,"column":2},"end":{"line":47,"column":null}},"20":{"start":{"line":61,"column":20},"end":{"line":61,"column":null}},"21":{"start":{"line":62,"column":18},"end":{"line":62,"column":null}},"22":{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},"23":{"start":{"line":64,"column":4},"end":{"line":70,"column":null}},"24":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"25":{"start":{"line":72,"column":21},"end":{"line":72,"column":null}},"26":{"start":{"line":73,"column":18},"end":{"line":73,"column":null}},"27":{"start":{"line":74,"column":18},"end":{"line":74,"column":null}},"28":{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},"29":{"start":{"line":76,"column":4},"end":{"line":97,"column":null}},"30":{"start":{"line":77,"column":29},"end":{"line":82,"column":null}},"31":{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},"32":{"start":{"line":84,"column":27},"end":{"line":84,"column":null}},"33":{"start":{"line":87,"column":27},"end":{"line":87,"column":null}},"34":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"35":{"start":{"line":89,"column":32},"end":{"line":89,"column":null}},"36":{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},"37":{"start":{"line":91,"column":12},"end":{"line":91,"column":null}},"38":{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},"39":{"start":{"line":100,"column":4},"end":{"line":106,"column":null}},"40":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}}},"fnMap":{"0":{"name":"countWords","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":27}},"loc":{"start":{"line":21,"column":49},"end":{"line":37,"column":null}},"line":21},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":37},"end":{"line":35,"column":45}},"loc":{"start":{"line":35,"column":51},"end":{"line":35,"column":63}},"line":35},"2":{"name":"computeCitationDensity","decl":{"start":{"line":43,"column":16},"end":{"line":43,"column":39}},"loc":{"start":{"line":43,"column":61},"end":{"line":48,"column":null}},"line":43},"3":{"name":"checkCitationDensity","decl":{"start":{"line":56,"column":16},"end":{"line":56,"column":null}},"loc":{"start":{"line":60,"column":22},"end":{"line":109,"column":null}},"line":60}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},{"start":{},"end":{}}],"line":45},"1":{"loc":{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":63,"column":6},"end":{"line":63,"column":38}},"type":"binary-expr","locations":[{"start":{"line":63,"column":6},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":38}}],"line":63},"3":{"loc":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":72},"4":{"loc":{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":75},"5":{"loc":{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":6},"end":{"line":94,"column":null}},{"start":{},"end":{}}],"line":83},"6":{"loc":{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":88},"7":{"loc":{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},"type":"if","locations":[{"start":{"line":90,"column":10},"end":{"line":92,"column":null}},{"start":{},"end":{}}],"line":90},"8":{"loc":{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":99,"column":2},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":99}},"s":{"0":14,"1":14,"2":14,"3":14,"4":14,"5":14,"6":13,"7":13,"8":14,"9":14,"10":14,"11":14,"12":14,"13":846,"14":14,"15":3,"16":3,"17":2,"18":1,"19":1,"20":7,"21":7,"22":7,"23":1,"24":6,"25":1,"26":5,"27":5,"28":5,"29":3,"30":3,"31":3,"32":3,"33":3,"34":3,"35":3,"36":3,"37":2,"38":5,"39":2,"40":3},"f":{"0":14,"1":846,"2":3,"3":7},"b":{"0":[2,1],"1":[1,6],"2":[7,6],"3":[1,5],"4":[3,2],"5":[3,0],"6":[3,0],"7":[2,1],"8":[2,3]},"meta":{"lastBranch":9,"lastFunction":4,"lastStatement":41,"seen":{"f:21:16:21:27":0,"s:22:16:22:Infinity":0,"s:23:2:23:Infinity":1,"s:24:2:24:Infinity":2,"s:25:2:25:Infinity":3,"s:26:13:26:Infinity":4,"s:27:2:30:Infinity":5,"s:28:4:28:Infinity":6,"s:29:4:29:Infinity":7,"s:31:2:31:Infinity":8,"s:32:2:32:Infinity":9,"s:33:2:33:Infinity":10,"s:34:2:34:Infinity":11,"s:35:16:35:Infinity":12,"f:35:37:35:45":1,"s:35:51:35:63":13,"s:36:2:36:Infinity":14,"f:43:16:43:39":2,"s:44:18:44:Infinity":15,"b:45:2:45:Infinity:undefined:undefined:undefined:undefined":0,"s:45:2:45:Infinity":16,"s:45:21:45:Infinity":17,"s:46:16:46:Infinity":18,"s:47:2:47:Infinity":19,"f:56:16:56:Infinity":3,"s:61:20:61:Infinity":20,"s:62:18:62:Infinity":21,"b:63:2:71:Infinity:undefined:undefined:undefined:undefined":1,"s:63:2:71:Infinity":22,"b:63:6:63:23:63:23:63:38":2,"s:64:4:70:Infinity":23,"b:72:2:72:Infinity:undefined:undefined:undefined:undefined":3,"s:72:2:72:Infinity":24,"s:72:21:72:Infinity":25,"s:73:18:73:Infinity":26,"s:74:18:74:Infinity":27,"b:75:2:98:Infinity:undefined:undefined:undefined:undefined":4,"s:75:2:98:Infinity":28,"s:76:4:97:Infinity":29,"s:77:29:82:Infinity":30,"b:83:6:94:Infinity:undefined:undefined:undefined:undefined":5,"s:83:6:94:Infinity":31,"s:84:27:84:Infinity":32,"s:87:27:87:Infinity":33,"b:88:8:93:Infinity:undefined:undefined:undefined:undefined":6,"s:88:8:93:Infinity":34,"s:89:32:89:Infinity":35,"b:90:10:92:Infinity:undefined:undefined:undefined:undefined":7,"s:90:10:92:Infinity":36,"s:91:12:91:Infinity":37,"b:99:2:107:Infinity:undefined:undefined:undefined:undefined":8,"s:99:2:107:Infinity":38,"s:100:4:106:Infinity":39,"s:108:2:108:Infinity":40}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/evidence-anchors.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/evidence-anchors.ts","statementMap":{"0":{"start":{"line":23,"column":29},"end":{"line":30,"column":null}},"1":{"start":{"line":31,"column":14},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":33,"column":20},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"5":{"start":{"line":34,"column":17},"end":{"line":34,"column":null}},"6":{"start":{"line":36,"column":2},"end":{"line":36,"column":null}}},"fnMap":{"0":{"name":"countArticleEvidenceAnchors","decl":{"start":{"line":22,"column":16},"end":{"line":22,"column":44}},"loc":{"start":{"line":22,"column":66},"end":{"line":37,"column":null}},"line":22}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":34}},"s":{"0":12,"1":12,"2":12,"3":60,"4":60,"5":9,"6":12},"f":{"0":12},"b":{"0":[9,51]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":7,"seen":{"f:22:16:22:44":0,"s:23:29:30:Infinity":0,"s:31:14:31:Infinity":1,"s:32:2:35:Infinity":2,"s:33:20:33:Infinity":3,"b:34:4:34:Infinity:undefined:undefined:undefined:undefined":0,"s:34:4:34:Infinity":4,"s:34:17:34:Infinity":5,"s:36:2:36:Infinity":6}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/footer.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/footer.ts","statementMap":{"0":{"start":{"line":30,"column":89},"end":{"line":37,"column":null}},"1":{"start":{"line":43,"column":34},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":56,"column":null}},"3":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"4":{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},"5":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"6":{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},"7":{"start":{"line":49,"column":8},"end":{"line":53,"column":null}},"8":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"checkFooterMarkers","decl":{"start":{"line":42,"column":16},"end":{"line":42,"column":35}},"loc":{"start":{"line":42,"column":82},"end":{"line":58,"column":null}},"line":42}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":20},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":20},"end":{"line":45,"column":50}},{"start":{"line":45,"column":50},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":46,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":46},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":48}},"s":{"0":2,"1":2,"2":2,"3":12,"4":12,"5":2,"6":2,"7":1,"8":2},"f":{"0":2},"b":{"0":[12,10],"1":[2,10],"2":[1,1]},"meta":{"lastBranch":3,"lastFunction":1,"lastStatement":9,"seen":{"s:30:89:37:Infinity":0,"f:42:16:42:35":0,"s:43:34:43:Infinity":1,"s:44:2:56:Infinity":2,"s:45:20:45:Infinity":3,"b:45:20:45:50:45:50:45:Infinity":0,"b:46:4:55:Infinity:undefined:undefined:undefined:undefined":1,"s:46:4:55:Infinity":4,"s:47:21:47:Infinity":5,"b:48:6:54:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:54:Infinity":6,"s:49:8:53:Infinity":7,"s:57:2:57:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/landmarks.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/landmarks.ts","statementMap":{"0":{"start":{"line":28,"column":5},"end":{"line":49,"column":null}},"1":{"start":{"line":55,"column":34},"end":{"line":55,"column":null}},"2":{"start":{"line":56,"column":2},"end":{"line":64,"column":null}},"3":{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},"4":{"start":{"line":58,"column":6},"end":{"line":62,"column":null}},"5":{"start":{"line":65,"column":23},"end":{"line":65,"column":null}},"6":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"7":{"start":{"line":67,"column":4},"end":{"line":71,"column":null}},"8":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"9":{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},"10":{"start":{"line":76,"column":18},"end":{"line":76,"column":null}},"11":{"start":{"line":77,"column":17},"end":{"line":77,"column":null}},"12":{"start":{"line":78,"column":19},"end":{"line":78,"column":null}},"13":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"14":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"15":{"start":{"line":81,"column":6},"end":{"line":85,"column":null}},"16":{"start":{"line":88,"column":2},"end":{"line":88,"column":null}}},"fnMap":{"0":{"name":"checkLandmarks","decl":{"start":{"line":54,"column":16},"end":{"line":54,"column":31}},"loc":{"start":{"line":54,"column":78},"end":{"line":89,"column":null}},"line":54}},"branchMap":{"0":{"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":57},"1":{"loc":{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":66},"2":{"loc":{"start":{"line":66,"column":6},"end":{"line":66,"column":47}},"type":"binary-expr","locations":[{"start":{"line":66,"column":6},"end":{"line":66,"column":22}},{"start":{"line":66,"column":22},"end":{"line":66,"column":47}}],"line":66},"3":{"loc":{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":87,"column":null}},{"start":{},"end":{}}],"line":75},"4":{"loc":{"start":{"line":75,"column":6},"end":{"line":75,"column":66}},"type":"binary-expr","locations":[{"start":{"line":75,"column":6},"end":{"line":75,"column":27}},{"start":{"line":75,"column":27},"end":{"line":75,"column":66}}],"line":75},"5":{"loc":{"start":{"line":78,"column":19},"end":{"line":78,"column":null}},"type":"cond-expr","locations":[{"start":{"line":78,"column":33},"end":{"line":78,"column":41}},{"start":{"line":78,"column":41},"end":{"line":78,"column":null}}],"line":78},"6":{"loc":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":21},"end":{"line":79,"column":68}},{"start":{"line":79,"column":68},"end":{"line":79,"column":null}}],"line":79},"7":{"loc":{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":4},"end":{"line":86,"column":null}},{"start":{},"end":{}}],"line":80}},"s":{"0":2,"1":4,"2":4,"3":16,"4":4,"5":4,"6":4,"7":1,"8":4,"9":4,"10":3,"11":3,"12":3,"13":3,"14":3,"15":2,"16":4},"f":{"0":4},"b":{"0":[4,12],"1":[1,3],"2":[4,3],"3":[3,1],"4":[4,3],"5":[0,3],"6":[3,2],"7":[2,1]},"meta":{"lastBranch":8,"lastFunction":1,"lastStatement":17,"seen":{"s:28:5:49:Infinity":0,"f:54:16:54:31":0,"s:55:34:55:Infinity":1,"s:56:2:64:Infinity":2,"b:57:4:63:Infinity:undefined:undefined:undefined:undefined":0,"s:57:4:63:Infinity":3,"s:58:6:62:Infinity":4,"s:65:23:65:Infinity":5,"b:66:2:72:Infinity:undefined:undefined:undefined:undefined":1,"s:66:2:72:Infinity":6,"b:66:6:66:22:66:22:66:47":2,"s:67:4:71:Infinity":7,"s:74:28:74:Infinity":8,"b:75:2:87:Infinity:undefined:undefined:undefined:undefined":3,"s:75:2:87:Infinity":9,"b:75:6:75:27:75:27:75:66":4,"s:76:18:76:Infinity":10,"s:77:17:77:Infinity":11,"s:78:19:78:Infinity":12,"b:78:33:78:41:78:41:78:Infinity":5,"s:79:21:79:Infinity":13,"b:79:21:79:68:79:68:79:Infinity":6,"b:80:4:86:Infinity:undefined:undefined:undefined:undefined":7,"s:80:4:86:Infinity":14,"s:81:6:85:Infinity":15,"s:88:2:88:Infinity":16}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/mermaid-fences.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/mermaid-fences.ts","statementMap":{"0":{"start":{"line":46,"column":16},"end":{"line":46,"column":null}},"1":{"start":{"line":47,"column":38},"end":{"line":47,"column":null}},"2":{"start":{"line":48,"column":10},"end":{"line":48,"column":null}},"3":{"start":{"line":49,"column":2},"end":{"line":74,"column":null}},"4":{"start":{"line":50,"column":17},"end":{"line":50,"column":null}},"5":{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},"6":{"start":{"line":52,"column":23},"end":{"line":52,"column":null}},"7":{"start":{"line":53,"column":14},"end":{"line":53,"column":null}},"8":{"start":{"line":54,"column":19},"end":{"line":54,"column":null}},"9":{"start":{"line":55,"column":33},"end":{"line":55,"column":null}},"10":{"start":{"line":56,"column":6},"end":{"line":66,"column":null}},"11":{"start":{"line":57,"column":20},"end":{"line":57,"column":null}},"12":{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},"13":{"start":{"line":59,"column":10},"end":{"line":59,"column":null}},"14":{"start":{"line":60,"column":10},"end":{"line":60,"column":null}},"15":{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},"16":{"start":{"line":63,"column":10},"end":{"line":63,"column":null}},"17":{"start":{"line":64,"column":10},"end":{"line":64,"column":null}},"18":{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},"19":{"start":{"line":68,"column":8},"end":{"line":68,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"21":{"start":{"line":71,"column":6},"end":{"line":71,"column":null}},"22":{"start":{"line":73,"column":4},"end":{"line":73,"column":null}},"23":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"24":{"start":{"line":84,"column":18},"end":{"line":84,"column":null}},"25":{"start":{"line":85,"column":2},"end":{"line":85,"column":null}},"26":{"start":{"line":92,"column":19},"end":{"line":92,"column":null}},"27":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"28":{"start":{"line":93,"column":29},"end":{"line":93,"column":null}},"29":{"start":{"line":94,"column":17},"end":{"line":94,"column":null}},"30":{"start":{"line":94,"column":49},"end":{"line":94,"column":71}},"31":{"start":{"line":95,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"findUnclosedMermaidFences","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":42}},"loc":{"start":{"line":45,"column":89},"end":{"line":76,"column":null}},"line":45},"1":{"name":"countMermaidOpenings","decl":{"start":{"line":83,"column":16},"end":{"line":83,"column":37}},"loc":{"start":{"line":83,"column":59},"end":{"line":86,"column":null}},"line":83},"2":{"name":"checkUnclosedMermaidFences","decl":{"start":{"line":91,"column":16},"end":{"line":91,"column":43}},"loc":{"start":{"line":91,"column":90},"end":{"line":102,"column":null}},"line":91},"3":{"name":"(anonymous_3)","decl":{"start":{"line":94,"column":38},"end":{"line":94,"column":43}},"loc":{"start":{"line":94,"column":49},"end":{"line":94,"column":71}},"line":94}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":4},"end":{"line":72,"column":null}},{"start":{},"end":{}}],"line":51},"1":{"loc":{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":58},"2":{"loc":{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":62,"column":8},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":62},"3":{"loc":{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},"type":"if","locations":[{"start":{"line":67,"column":6},"end":{"line":69,"column":null}},{"start":{},"end":{}}],"line":67},"4":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":33},"end":{"line":70,"column":37}},{"start":{"line":70,"column":37},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":85,"column":9},"end":{"line":85,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":19},"end":{"line":85,"column":36}},{"start":{"line":85,"column":36},"end":{"line":85,"column":null}}],"line":85},"6":{"loc":{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":2},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":93},"7":{"loc":{"start":{"line":99,"column":88},"end":{"line":99,"column":121}},"type":"cond-expr","locations":[{"start":{"line":99,"column":110},"end":{"line":99,"column":118}},{"start":{"line":99,"column":118},"end":{"line":99,"column":121}}],"line":99}},"s":{"0":6,"1":6,"2":6,"3":6,"4":13,"5":13,"6":10,"7":10,"8":10,"9":10,"10":10,"11":32,"12":32,"13":5,"14":5,"15":27,"16":3,"17":3,"18":10,"19":5,"20":10,"21":10,"22":3,"23":6,"24":4,"25":4,"26":2,"27":2,"28":1,"29":1,"30":1,"31":1},"f":{"0":6,"1":4,"2":2,"3":1},"b":{"0":[10,3],"1":[5,27],"2":[3,24],"3":[5,5],"4":[3,7],"5":[2,2],"6":[1,1],"7":[0,1]},"meta":{"lastBranch":8,"lastFunction":4,"lastStatement":32,"seen":{"f:45:16:45:42":0,"s:46:16:46:Infinity":0,"s:47:38:47:Infinity":1,"s:48:10:48:Infinity":2,"s:49:2:74:Infinity":3,"s:50:17:50:Infinity":4,"b:51:4:72:Infinity:undefined:undefined:undefined:undefined":0,"s:51:4:72:Infinity":5,"s:52:23:52:Infinity":6,"s:53:14:53:Infinity":7,"s:54:19:54:Infinity":8,"s:55:33:55:Infinity":9,"s:56:6:66:Infinity":10,"s:57:20:57:Infinity":11,"b:58:8:61:Infinity:undefined:undefined:undefined:undefined":1,"s:58:8:61:Infinity":12,"s:59:10:59:Infinity":13,"s:60:10:60:Infinity":14,"b:62:8:65:Infinity:undefined:undefined:undefined:undefined":2,"s:62:8:65:Infinity":15,"s:63:10:63:Infinity":16,"s:64:10:64:Infinity":17,"b:67:6:69:Infinity:undefined:undefined:undefined:undefined":3,"s:67:6:69:Infinity":18,"s:68:8:68:Infinity":19,"s:70:6:70:Infinity":20,"b:70:33:70:37:70:37:70:Infinity":4,"s:71:6:71:Infinity":21,"s:73:4:73:Infinity":22,"s:75:2:75:Infinity":23,"f:83:16:83:37":1,"s:84:18:84:Infinity":24,"s:85:2:85:Infinity":25,"b:85:19:85:36:85:36:85:Infinity":5,"f:91:16:91:43":2,"s:92:19:92:Infinity":26,"b:93:2:93:Infinity:undefined:undefined:undefined:undefined":6,"s:93:2:93:Infinity":27,"s:93:29:93:Infinity":28,"s:94:17:94:Infinity":29,"f:94:38:94:43":3,"s:94:49:94:71":30,"s:95:2:101:Infinity":31,"b:99:110:99:118:99:118:99:121":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/per-document.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/per-document.ts","statementMap":{"0":{"start":{"line":16,"column":39},"end":{"line":16,"column":null}},"1":{"start":{"line":26,"column":16},"end":{"line":26,"column":null}},"2":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"3":{"start":{"line":27,"column":43},"end":{"line":27,"column":null}},"4":{"start":{"line":28,"column":15},"end":{"line":28,"column":null}},"5":{"start":{"line":29,"column":15},"end":{"line":29,"column":null}},"6":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"7":{"start":{"line":31,"column":56},"end":{"line":31,"column":null}},"8":{"start":{"line":33,"column":25},"end":{"line":33,"column":null}},"9":{"start":{"line":34,"column":15},"end":{"line":34,"column":null}},"10":{"start":{"line":35,"column":10},"end":{"line":35,"column":null}},"11":{"start":{"line":36,"column":2},"end":{"line":45,"column":null}},"12":{"start":{"line":37,"column":15},"end":{"line":37,"column":null}},"13":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"14":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"15":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"16":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"17":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"18":{"start":{"line":42,"column":43},"end":{"line":42,"column":null}},"19":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"20":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"21":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"22":{"start":{"line":50,"column":31},"end":{"line":50,"column":null}},"23":{"start":{"line":56,"column":34},"end":{"line":56,"column":null}},"24":{"start":{"line":57,"column":2},"end":{"line":66,"column":null}},"25":{"start":{"line":58,"column":17},"end":{"line":58,"column":null}},"26":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"27":{"start":{"line":60,"column":6},"end":{"line":64,"column":null}},"28":{"start":{"line":67,"column":2},"end":{"line":67,"column":null}}},"fnMap":{"0":{"name":"extractPerDocumentSections","decl":{"start":{"line":25,"column":16},"end":{"line":25,"column":43}},"loc":{"start":{"line":25,"column":97},"end":{"line":47,"column":null}},"line":25},"1":{"name":"checkPerDocument","decl":{"start":{"line":55,"column":16},"end":{"line":55,"column":33}},"loc":{"start":{"line":55,"column":80},"end":{"line":68,"column":null}},"line":55}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"if","locations":[{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},{"start":{},"end":{}}],"line":27},"1":{"loc":{"start":{"line":27,"column":6},"end":{"line":27,"column":43}},"type":"binary-expr","locations":[{"start":{"line":27,"column":6},"end":{"line":27,"column":16}},{"start":{"line":27,"column":16},"end":{"line":27,"column":43}}],"line":27},"2":{"loc":{"start":{"line":30,"column":17},"end":{"line":30,"column":null}},"type":"cond-expr","locations":[{"start":{"line":30,"column":31},"end":{"line":30,"column":38}},{"start":{"line":30,"column":38},"end":{"line":30,"column":null}}],"line":30},"3":{"loc":{"start":{"line":36,"column":9},"end":{"line":36,"column":37}},"type":"binary-expr","locations":[{"start":{"line":36,"column":9},"end":{"line":36,"column":14}},{"start":{"line":36,"column":14},"end":{"line":36,"column":37}}],"line":36},"4":{"loc":{"start":{"line":40,"column":17},"end":{"line":40,"column":null}},"type":"cond-expr","locations":[{"start":{"line":40,"column":52},"end":{"line":40,"column":81}},{"start":{"line":40,"column":81},"end":{"line":40,"column":null}}],"line":40},"5":{"loc":{"start":{"line":40,"column":17},"end":{"line":40,"column":52}},"type":"binary-expr","locations":[{"start":{"line":40,"column":17},"end":{"line":40,"column":25}},{"start":{"line":40,"column":25},"end":{"line":40,"column":52}}],"line":40},"6":{"loc":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},{"start":{},"end":{}}],"line":42},"7":{"loc":{"start":{"line":42,"column":8},"end":{"line":42,"column":43}},"type":"binary-expr","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":17}},{"start":{"line":42,"column":17},"end":{"line":42,"column":43}}],"line":42},"8":{"loc":{"start":{"line":58,"column":17},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":17},"end":{"line":58,"column":80}},{"start":{"line":58,"column":80},"end":{"line":58,"column":null}}],"line":58},"9":{"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":4},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":59}},"s":{"0":2,"1":2,"2":2,"3":0,"4":2,"5":2,"6":2,"7":2,"8":2,"9":2,"10":2,"11":2,"12":3,"13":3,"14":3,"15":3,"16":3,"17":3,"18":2,"19":1,"20":1,"21":2,"22":2,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1},"f":{"0":2,"1":1},"b":{"0":[0,2],"1":[2,2],"2":[1,1],"3":[2,3],"4":[1,2],"5":[3,1],"6":[2,1],"7":[3,1],"8":[1,1],"9":[1,0]},"meta":{"lastBranch":10,"lastFunction":2,"lastStatement":29,"seen":{"s:16:39:16:Infinity":0,"f:25:16:25:43":0,"s:26:16:26:Infinity":1,"b:27:2:27:Infinity:undefined:undefined:undefined:undefined":0,"s:27:2:27:Infinity":2,"b:27:6:27:16:27:16:27:43":1,"s:27:43:27:Infinity":3,"s:28:15:28:Infinity":4,"s:29:15:29:Infinity":5,"s:30:17:30:Infinity":6,"b:30:31:30:38:30:38:30:Infinity":2,"s:31:56:31:Infinity":7,"s:33:25:33:Infinity":8,"s:34:15:34:Infinity":9,"s:35:10:35:Infinity":10,"s:36:2:45:Infinity":11,"b:36:9:36:14:36:14:36:37":3,"s:37:15:37:Infinity":12,"s:38:18:38:Infinity":13,"s:39:17:39:Infinity":14,"s:40:17:40:Infinity":15,"b:40:52:40:81:40:81:40:Infinity":4,"b:40:17:40:25:40:25:40:52":5,"s:41:4:41:Infinity":16,"b:42:4:42:Infinity:undefined:undefined:undefined:undefined":6,"s:42:4:42:Infinity":17,"b:42:8:42:17:42:17:42:43":7,"s:42:43:42:Infinity":18,"s:43:4:43:Infinity":19,"s:44:4:44:Infinity":20,"s:46:2:46:Infinity":21,"s:50:31:50:Infinity":22,"f:55:16:55:33":1,"s:56:34:56:Infinity":23,"s:57:2:66:Infinity":24,"s:58:17:58:Infinity":25,"b:58:17:58:80:58:80:58:Infinity":8,"b:59:4:65:Infinity:undefined:undefined:undefined:undefined":9,"s:59:4:65:Infinity":26,"s:60:6:64:Infinity":27,"s:67:2:67:Infinity":28}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/placeholders.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/placeholders.ts","statementMap":{"0":{"start":{"line":24,"column":55},"end":{"line":30,"column":null}},"1":{"start":{"line":34,"column":25},"end":{"line":34,"column":null}},"2":{"start":{"line":35,"column":2},"end":{"line":38,"column":null}},"3":{"start":{"line":36,"column":14},"end":{"line":36,"column":null}},"4":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"5":{"start":{"line":37,"column":11},"end":{"line":37,"column":null}},"6":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"7":{"start":{"line":46,"column":34},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":2},"end":{"line":56,"column":null}},"9":{"start":{"line":48,"column":14},"end":{"line":48,"column":null}},"10":{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},"11":{"start":{"line":50,"column":6},"end":{"line":54,"column":null}},"12":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"scanPlaceholders","decl":{"start":{"line":33,"column":16},"end":{"line":33,"column":33}},"loc":{"start":{"line":33,"column":57},"end":{"line":40,"column":null}},"line":33},"1":{"name":"checkPlaceholders","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":34}},"loc":{"start":{"line":45,"column":81},"end":{"line":58,"column":null}},"line":45}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":4},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":49}},"s":{"0":2,"1":1,"2":1,"3":5,"4":5,"5":2,"6":1,"7":2,"8":2,"9":10,"10":10,"11":2,"12":2},"f":{"0":1,"1":2},"b":{"0":[2,3],"1":[2,8]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":13,"seen":{"s:24:55:30:Infinity":0,"f:33:16:33:33":0,"s:34:25:34:Infinity":1,"s:35:2:38:Infinity":2,"s:36:14:36:Infinity":3,"b:37:4:37:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:37:Infinity":4,"s:37:11:37:Infinity":5,"s:39:2:39:Infinity":6,"f:45:16:45:34":1,"s:46:34:46:Infinity":7,"s:47:2:56:Infinity":8,"s:48:14:48:Infinity":9,"b:49:4:55:Infinity:undefined:undefined:undefined:undefined":1,"s:49:4:55:Infinity":10,"s:50:6:54:Infinity":11,"s:57:2:57:Infinity":12}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/stale-provenance.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/rules/stale-provenance.ts","statementMap":{"0":{"start":{"line":34,"column":67},"end":{"line":34,"column":null}},"1":{"start":{"line":35,"column":17},"end":{"line":35,"column":null}},"2":{"start":{"line":37,"column":2},"end":{"line":51,"column":null}},"3":{"start":{"line":38,"column":20},"end":{"line":38,"column":null}},"4":{"start":{"line":39,"column":22},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":19},"end":{"line":40,"column":null}},"6":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"7":{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},"8":{"start":{"line":43,"column":24},"end":{"line":43,"column":null}},"9":{"start":{"line":44,"column":26},"end":{"line":44,"column":null}},"10":{"start":{"line":45,"column":28},"end":{"line":45,"column":null}},"11":{"start":{"line":46,"column":23},"end":{"line":46,"column":null}},"12":{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},"13":{"start":{"line":48,"column":8},"end":{"line":48,"column":null}},"14":{"start":{"line":52,"column":2},"end":{"line":52,"column":null}},"15":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"16":{"start":{"line":59,"column":39},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":16},"end":{"line":60,"column":null}},"18":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"19":{"start":{"line":61,"column":26},"end":{"line":61,"column":null}},"20":{"start":{"line":62,"column":17},"end":{"line":62,"column":null}},"21":{"start":{"line":62,"column":46},"end":{"line":62,"column":83}},"22":{"start":{"line":63,"column":2},"end":{"line":69,"column":null}}},"fnMap":{"0":{"name":"scanStaleProvenance","decl":{"start":{"line":30,"column":16},"end":{"line":30,"column":null}},"loc":{"start":{"line":33,"column":53},"end":{"line":53,"column":null}},"line":33},"1":{"name":"checkStaleProvenance","decl":{"start":{"line":58,"column":16},"end":{"line":58,"column":37}},"loc":{"start":{"line":58,"column":84},"end":{"line":70,"column":null}},"line":58},"2":{"name":"(anonymous_2)","decl":{"start":{"line":62,"column":35},"end":{"line":62,"column":40}},"loc":{"start":{"line":62,"column":46},"end":{"line":62,"column":83}},"line":62}},"branchMap":{"0":{"loc":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"type":"default-arg","locations":[{"start":{"line":32,"column":24},"end":{"line":32,"column":null}}],"line":32},"1":{"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":42},"2":{"loc":{"start":{"line":44,"column":26},"end":{"line":44,"column":null}},"type":"cond-expr","locations":[{"start":{"line":44,"column":42},"end":{"line":44,"column":58}},{"start":{"line":44,"column":58},"end":{"line":44,"column":null}}],"line":44},"3":{"loc":{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":47},"4":{"loc":{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":2},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"5":{"loc":{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},"type":"if","locations":[{"start":{"line":61,"column":2},"end":{"line":61,"column":null}},{"start":{},"end":{}}],"line":61}},"s":{"0":8,"1":8,"2":8,"3":10,"4":10,"5":10,"6":10,"7":10,"8":8,"9":8,"10":8,"11":8,"12":8,"13":6,"14":8,"15":5,"16":1,"17":4,"18":4,"19":4,"20":2,"21":3,"22":2},"f":{"0":8,"1":5,"2":3},"b":{"0":[8],"1":[8,2],"2":[7,1],"3":[6,2],"4":[1,4],"5":[2,2]},"meta":{"lastBranch":6,"lastFunction":3,"lastStatement":23,"seen":{"f:30:16:30:Infinity":0,"b:32:24:32:Infinity":0,"s:34:67:34:Infinity":0,"s:35:17:35:Infinity":1,"s:37:2:51:Infinity":2,"s:38:20:38:Infinity":3,"s:39:22:39:Infinity":4,"s:40:19:40:Infinity":5,"s:41:23:41:Infinity":6,"b:42:4:50:Infinity:undefined:undefined:undefined:undefined":1,"s:42:4:50:Infinity":7,"s:43:24:43:Infinity":8,"s:44:26:44:Infinity":9,"b:44:42:44:58:44:58:44:Infinity":2,"s:45:28:45:Infinity":10,"s:46:23:46:Infinity":11,"b:47:6:49:Infinity:undefined:undefined:undefined:undefined":3,"s:47:6:49:Infinity":12,"s:48:8:48:Infinity":13,"s:52:2:52:Infinity":14,"f:58:16:58:37":1,"b:59:2:59:Infinity:undefined:undefined:undefined:undefined":4,"s:59:2:59:Infinity":15,"s:59:39:59:Infinity":16,"s:60:16:60:Infinity":17,"b:61:2:61:Infinity:undefined:undefined:undefined:undefined":5,"s:61:2:61:Infinity":18,"s:61:26:61:Infinity":19,"s:62:17:62:Infinity":20,"f:62:35:62:40":2,"s:62:46:62:83":21,"s:63:2:69:Infinity":22}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/slug.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/slug.ts","statementMap":{"0":{"start":{"line":17,"column":2},"end":{"line":20,"column":null}},"1":{"start":{"line":27,"column":34},"end":{"line":27,"column":null}},"2":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"3":{"start":{"line":29,"column":2},"end":{"line":38,"column":null}},"4":{"start":{"line":30,"column":24},"end":{"line":30,"column":null}},"5":{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},"6":{"start":{"line":32,"column":6},"end":{"line":36,"column":null}},"7":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}}},"fnMap":{"0":{"name":"permissiveSlug","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":31}},"loc":{"start":{"line":16,"column":56},"end":{"line":21,"column":null}},"line":16},"1":{"name":"checkHeadingSlugs","decl":{"start":{"line":26,"column":16},"end":{"line":26,"column":34}},"loc":{"start":{"line":26,"column":81},"end":{"line":40,"column":null}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":23},"end":{"line":28,"column":null}},"type":"binary-expr","locations":[{"start":{"line":28,"column":23},"end":{"line":28,"column":62}},{"start":{"line":28,"column":62},"end":{"line":28,"column":null}}],"line":28},"1":{"loc":{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":37,"column":null}},{"start":{},"end":{}}],"line":31}},"s":{"0":6,"1":2,"2":2,"3":2,"4":2,"5":2,"6":1,"7":2},"f":{"0":6,"1":2},"b":{"0":[2,0],"1":[1,1]},"meta":{"lastBranch":2,"lastFunction":2,"lastStatement":8,"seen":{"f:16:16:16:31":0,"s:17:2:20:Infinity":0,"f:26:16:26:34":1,"s:27:34:27:Infinity":1,"s:28:23:28:Infinity":2,"b:28:23:28:62:28:62:28:Infinity":0,"s:29:2:38:Infinity":3,"s:30:24:30:Infinity":4,"b:31:4:37:Infinity:undefined:undefined:undefined:undefined":1,"s:31:4:37:Infinity":5,"s:32:6:36:Infinity":6,"s:39:2:39:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/article/types.ts","statementMap":{"0":{"start":{"line":18,"column":25},"end":{"line":18,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":2},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:18:25:18:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/headings.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/headings.ts","statementMap":{"0":{"start":{"line":18,"column":19},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":16},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":29},"end":{"line":20,"column":51}}},"fnMap":{"0":{"name":"countHeadings","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":30}},"loc":{"start":{"line":17,"column":50},"end":{"line":21,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":15},"end":{"line":20,"column":23}},"loc":{"start":{"line":20,"column":29},"end":{"line":20,"column":51}},"line":20}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":575},"f":{"0":23,"1":575},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":4,"seen":{"f:17:16:17:30":0,"s:18:19:18:Infinity":0,"s:19:16:19:Infinity":1,"s:20:2:20:Infinity":2,"f:20:15:20:23":1,"s:20:29:20:51":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/code-fences.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/code-fences.ts","statementMap":{"0":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"2":{"start":{"line":16,"column":32},"end":{"line":16,"column":null}},"3":{"start":{"line":18,"column":2},"end":{"line":18,"column":null}}},"fnMap":{"0":{"name":"countCodeFences","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":32}},"loc":{"start":{"line":14,"column":52},"end":{"line":19,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"type":"binary-expr","locations":[{"start":{"line":15,"column":18},"end":{"line":15,"column":40}},{"start":{"line":15,"column":40},"end":{"line":15,"column":null}}],"line":15},"1":{"loc":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"type":"if","locations":[{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},{"start":{},"end":{}}],"line":16}},"s":{"0":24,"1":24,"2":2,"3":22},"f":{"0":24},"b":{"0":[24,0],"1":[2,22]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":4,"seen":{"f:14:16:14:32":0,"s:15:18:15:Infinity":0,"b:15:18:15:40:15:40:15:Infinity":0,"b:16:2:16:Infinity:undefined:undefined:undefined:undefined":1,"s:16:2:16:Infinity":1,"s:16:32:16:Infinity":2,"s:18:2:18:Infinity":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/mermaid-blocks.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/mermaid-blocks.ts","statementMap":{"0":{"start":{"line":15,"column":18},"end":{"line":15,"column":null}},"1":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}}},"fnMap":{"0":{"name":"countMermaidBlocks","decl":{"start":{"line":14,"column":16},"end":{"line":14,"column":35}},"loc":{"start":{"line":14,"column":55},"end":{"line":17,"column":null}},"line":14}},"branchMap":{"0":{"loc":{"start":{"line":16,"column":9},"end":{"line":16,"column":null}},"type":"cond-expr","locations":[{"start":{"line":16,"column":19},"end":{"line":16,"column":36}},{"start":{"line":16,"column":36},"end":{"line":16,"column":null}}],"line":16}},"s":{"0":23,"1":23},"f":{"0":23},"b":{"0":[23,0]},"meta":{"lastBranch":1,"lastFunction":1,"lastStatement":2,"seen":{"f:14:16:14:35":0,"s:15:18:15:Infinity":0,"s:16:2:16:Infinity":1,"b:16:19:16:36:16:36:16:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/table-rows.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/table-rows.ts","statementMap":{"0":{"start":{"line":18,"column":19},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":16},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":29},"end":{"line":20,"column":53}}},"fnMap":{"0":{"name":"countTableRows","decl":{"start":{"line":17,"column":16},"end":{"line":17,"column":31}},"loc":{"start":{"line":17,"column":51},"end":{"line":21,"column":null}},"line":17},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":15},"end":{"line":20,"column":23}},"loc":{"start":{"line":20,"column":29},"end":{"line":20,"column":53}},"line":20}},"branchMap":{},"s":{"0":23,"1":23,"2":23,"3":575},"f":{"0":23,"1":575},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":4,"seen":{"f:17:16:17:31":0,"s:18:19:18:Infinity":0,"s:19:16:19:Infinity":1,"s:20:2:20:Infinity":2,"f:20:15:20:23":1,"s:20:29:20:53":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/words.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/counters/words.ts","statementMap":{"0":{"start":{"line":24,"column":19},"end":{"line":24,"column":null}},"1":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"2":{"start":{"line":25,"column":45},"end":{"line":25,"column":67}}},"fnMap":{"0":{"name":"countWords","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":27}},"loc":{"start":{"line":23,"column":47},"end":{"line":26,"column":null}},"line":23},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":31},"end":{"line":25,"column":39}},"loc":{"start":{"line":25,"column":45},"end":{"line":25,"column":67}},"line":25}},"branchMap":{},"s":{"0":19,"1":19,"2":1143},"f":{"0":19,"1":1143},"b":{},"meta":{"lastBranch":0,"lastFunction":2,"lastStatement":3,"seen":{"f:23:16:23:27":0,"s:24:19:24:Infinity":0,"s:25:2:25:Infinity":1,"f:25:31:25:39":1,"s:25:45:25:67":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/dok-ids.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/dok-ids.ts","statementMap":{"0":{"start":{"line":19,"column":19},"end":{"line":19,"column":null}},"1":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"2":{"start":{"line":26,"column":2},"end":{"line":26,"column":null}},"3":{"start":{"line":26,"column":42},"end":{"line":26,"column":57}}},"fnMap":{"0":{"name":"extractDokIds","decl":{"start":{"line":18,"column":16},"end":{"line":18,"column":30}},"loc":{"start":{"line":18,"column":55},"end":{"line":27,"column":null}},"line":18},"1":{"name":"(anonymous_1)","decl":{"start":{"line":26,"column":28},"end":{"line":26,"column":36}},"loc":{"start":{"line":26,"column":42},"end":{"line":26,"column":57}},"line":26}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":21},"end":{"line":25,"column":null}},"type":"binary-expr","locations":[{"start":{"line":25,"column":21},"end":{"line":25,"column":66}},{"start":{"line":25,"column":66},"end":{"line":25,"column":null}}],"line":25}},"s":{"0":24,"1":24,"2":24,"3":66},"f":{"0":24,"1":66},"b":{"0":[24,3]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":4,"seen":{"f:18:16:18:30":0,"s:19:19:19:Infinity":0,"s:25:21:25:Infinity":1,"b:25:21:25:66:25:66:25:Infinity":0,"s:26:2:26:Infinity":2,"f:26:28:26:36":1,"s:26:42:26:57":3}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/source-sha.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/source-sha.ts","statementMap":{"0":{"start":{"line":16,"column":16},"end":{"line":16,"column":null}},"1":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"2":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}}},"fnMap":{"0":{"name":"extractSourceShaMarker","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":39}},"loc":{"start":{"line":15,"column":66},"end":{"line":18,"column":null}},"line":15},"1":{"name":"hasRtlMarker","decl":{"start":{"line":21,"column":16},"end":{"line":21,"column":29}},"loc":{"start":{"line":21,"column":50},"end":{"line":23,"column":null}},"line":21}},"branchMap":{"0":{"loc":{"start":{"line":17,"column":9},"end":{"line":17,"column":null}},"type":"binary-expr","locations":[{"start":{"line":17,"column":9},"end":{"line":17,"column":23}},{"start":{"line":17,"column":23},"end":{"line":17,"column":null}}],"line":17}},"s":{"0":15,"1":15,"2":4},"f":{"0":15,"1":4},"b":{"0":[15,4]},"meta":{"lastBranch":1,"lastFunction":2,"lastStatement":3,"seen":{"f:15:16:15:39":0,"s:16:16:16:Infinity":0,"s:17:2:17:Infinity":1,"b:17:9:17:23:17:23:17:Infinity":0,"f:21:16:21:29":1,"s:22:2:22:Infinity":2}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/urls.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/extractors/urls.ts","statementMap":{"0":{"start":{"line":18,"column":15},"end":{"line":18,"column":null}},"1":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"2":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"3":{"start":{"line":20,"column":31},"end":{"line":20,"column":null}},"4":{"start":{"line":21,"column":15},"end":{"line":21,"column":null}},"5":{"start":{"line":22,"column":2},"end":{"line":22,"column":null}},"6":{"start":{"line":22,"column":24},"end":{"line":22,"column":null}},"7":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}}},"fnMap":{"0":{"name":"extractUrls","decl":{"start":{"line":16,"column":16},"end":{"line":16,"column":28}},"loc":{"start":{"line":16,"column":53},"end":{"line":24,"column":null}},"line":16}},"branchMap":{"0":{"loc":{"start":{"line":19,"column":22},"end":{"line":19,"column":null}},"type":"binary-expr","locations":[{"start":{"line":19,"column":22},"end":{"line":19,"column":63}},{"start":{"line":19,"column":63},"end":{"line":19,"column":null}}],"line":19},"1":{"loc":{"start":{"line":21,"column":15},"end":{"line":21,"column":null}},"type":"binary-expr","locations":[{"start":{"line":21,"column":15},"end":{"line":21,"column":60}},{"start":{"line":21,"column":60},"end":{"line":21,"column":null}}],"line":21}},"s":{"0":23,"1":23,"2":23,"3":20,"4":23,"5":23,"6":19,"7":23},"f":{"0":23},"b":{"0":[23,3],"1":[23,4]},"meta":{"lastBranch":2,"lastFunction":1,"lastStatement":8,"seen":{"f:16:16:16:28":0,"s:18:15:18:Infinity":0,"s:19:22:19:Infinity":1,"b:19:22:19:63:19:63:19:Infinity":0,"s:20:2:20:Infinity":2,"s:20:31:20:Infinity":3,"s:21:15:21:Infinity":4,"b:21:15:21:60:21:60:21:Infinity":1,"s:22:2:22:Infinity":5,"s:22:24:22:Infinity":6,"s:23:2:23:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/narrative-drift.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/narrative-drift.ts","statementMap":{"0":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"1":{"start":{"line":36,"column":24},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":18},"end":{"line":37,"column":null}},"3":{"start":{"line":38,"column":2},"end":{"line":53,"column":null}},"4":{"start":{"line":39,"column":20},"end":{"line":39,"column":null}},"5":{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},"6":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"7":{"start":{"line":42,"column":8},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":8},"end":{"line":43,"column":null}},"9":{"start":{"line":45,"column":6},"end":{"line":45,"column":null}},"10":{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},"11":{"start":{"line":49,"column":8},"end":{"line":49,"column":null}},"12":{"start":{"line":54,"column":2},"end":{"line":54,"column":null}},"13":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"14":{"start":{"line":65,"column":24},"end":{"line":65,"column":null}},"15":{"start":{"line":66,"column":21},"end":{"line":66,"column":null}},"16":{"start":{"line":67,"column":20},"end":{"line":67,"column":null}},"17":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"18":{"start":{"line":72,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"stripMermaidBlocks","decl":{"start":{"line":34,"column":16},"end":{"line":34,"column":35}},"loc":{"start":{"line":34,"column":55},"end":{"line":55,"column":null}},"line":34},"1":{"name":"isDiffMermaidOnly","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":34}},"loc":{"start":{"line":64,"column":74},"end":{"line":69,"column":null}},"line":64},"2":{"name":"normalise","decl":{"start":{"line":71,"column":9},"end":{"line":71,"column":19}},"loc":{"start":{"line":71,"column":38},"end":{"line":73,"column":null}},"line":71}},"branchMap":{"0":{"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":52,"column":null}},{"start":{"line":46,"column":11},"end":{"line":52,"column":null}}],"line":40},"1":{"loc":{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":41,"column":6},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":41},"2":{"loc":{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":6},"end":{"line":50,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},{"start":{},"end":{}}],"line":65}},"s":{"0":16,"1":16,"2":16,"3":16,"4":115,"5":115,"6":71,"7":15,"8":15,"9":56,"10":44,"11":15,"12":16,"13":7,"14":1,"15":6,"16":6,"17":6,"18":12},"f":{"0":16,"1":7,"2":12},"b":{"0":[71,44],"1":[15,56],"2":[15,29],"3":[1,6]},"meta":{"lastBranch":4,"lastFunction":3,"lastStatement":19,"seen":{"f:34:16:34:35":0,"s:35:16:35:Infinity":0,"s:36:24:36:Infinity":1,"s:37:18:37:Infinity":2,"s:38:2:53:Infinity":3,"s:39:20:39:Infinity":4,"b:40:4:52:Infinity:46:11:52:Infinity":0,"s:40:4:52:Infinity":5,"b:41:6:44:Infinity:undefined:undefined:undefined:undefined":1,"s:41:6:44:Infinity":6,"s:42:8:42:Infinity":7,"s:43:8:43:Infinity":8,"s:45:6:45:Infinity":9,"b:48:6:50:Infinity:undefined:undefined:undefined:undefined":2,"s:48:6:50:Infinity":10,"s:49:8:49:Infinity":11,"s:54:2:54:Infinity":12,"f:64:16:64:34":1,"b:65:2:65:Infinity:undefined:undefined:undefined:undefined":3,"s:65:2:65:Infinity":13,"s:65:24:65:Infinity":14,"s:66:21:66:Infinity":15,"s:67:20:67:Infinity":16,"s:68:2:68:Infinity":17,"f:71:9:71:19":2,"s:72:2:72:Infinity":18}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/rules/banned-english.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/rules/banned-english.ts","statementMap":{"0":{"start":{"line":17,"column":54},"end":{"line":29,"column":null}},"1":{"start":{"line":32,"column":64},"end":{"line":37,"column":null}},"2":{"start":{"line":41,"column":25},"end":{"line":41,"column":null}},"3":{"start":{"line":42,"column":2},"end":{"line":57,"column":null}},"4":{"start":{"line":43,"column":15},"end":{"line":43,"column":null}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"6":{"start":{"line":44,"column":22},"end":{"line":44,"column":null}},"7":{"start":{"line":46,"column":21},"end":{"line":46,"column":null}},"8":{"start":{"line":47,"column":21},"end":{"line":47,"column":null}},"9":{"start":{"line":48,"column":4},"end":{"line":55,"column":null}},"10":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"11":{"start":{"line":49,"column":26},"end":{"line":49,"column":null}},"12":{"start":{"line":50,"column":26},"end":{"line":50,"column":null}},"13":{"start":{"line":50,"column":73},"end":{"line":50,"column":87}},"14":{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},"15":{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},"16":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"17":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"18":{"start":{"line":56,"column":20},"end":{"line":56,"column":null}},"19":{"start":{"line":58,"column":2},"end":{"line":58,"column":null}}},"fnMap":{"0":{"name":"findBannedEnglishPhrases","decl":{"start":{"line":40,"column":16},"end":{"line":40,"column":41}},"loc":{"start":{"line":40,"column":63},"end":{"line":59,"column":null}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":50,"column":59},"end":{"line":50,"column":65}},"loc":{"start":{"line":50,"column":73},"end":{"line":50,"column":87}},"line":50}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},{"start":{},"end":{}}],"line":44},"1":{"loc":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"type":"if","locations":[{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},{"start":{},"end":{}}],"line":49},"2":{"loc":{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":51},"3":{"loc":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},{"start":{},"end":{}}],"line":56}},"s":{"0":1,"1":1,"2":15,"3":15,"4":165,"5":165,"6":163,"7":2,"8":2,"9":2,"10":14,"11":12,"12":2,"13":8,"14":2,"15":2,"16":2,"17":2,"18":2,"19":15},"f":{"0":15,"1":8},"b":{"0":[163,2],"1":[12,2],"2":[2,0],"3":[2,0]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":20,"seen":{"s:17:54:29:Infinity":0,"s:32:64:37:Infinity":1,"f:40:16:40:41":0,"s:41:25:41:Infinity":2,"s:42:2:57:Infinity":3,"s:43:15:43:Infinity":4,"b:44:4:44:Infinity:undefined:undefined:undefined:undefined":0,"s:44:4:44:Infinity":5,"s:44:22:44:Infinity":6,"s:46:21:46:Infinity":7,"s:47:21:47:Infinity":8,"s:48:4:55:Infinity":9,"b:49:6:49:Infinity:undefined:undefined:undefined:undefined":1,"s:49:6:49:Infinity":10,"s:49:26:49:Infinity":11,"s:50:26:50:Infinity":12,"f:50:59:50:65":1,"s:50:73:50:87":13,"b:51:6:54:Infinity:undefined:undefined:undefined:undefined":2,"s:51:6:54:Infinity":14,"s:52:8:52:Infinity":15,"s:53:8:53:Infinity":16,"b:56:4:56:Infinity:undefined:undefined:undefined:undefined":3,"s:56:4:56:Infinity":17,"s:56:20:56:Infinity":18,"s:58:2:58:Infinity":19}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/strippers.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/strippers.ts","statementMap":{"0":{"start":{"line":17,"column":15},"end":{"line":17,"column":null}},"1":{"start":{"line":19,"column":2},"end":{"line":24,"column":null}},"2":{"start":{"line":20,"column":4},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":4},"end":{"line":23,"column":null}},"4":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}}},"fnMap":{"0":{"name":"stripFencesAndComments","decl":{"start":{"line":15,"column":16},"end":{"line":15,"column":39}},"loc":{"start":{"line":15,"column":59},"end":{"line":26,"column":null}},"line":15}},"branchMap":{},"s":{"0":89,"1":89,"2":177,"3":177,"4":89},"f":{"0":89},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":5,"seen":{"f:15:16:15:39":0,"s:17:15:17:Infinity":0,"s:19:2:24:Infinity":1,"s:20:4:20:Infinity":2,"s:21:4:23:Infinity":3,"s:25:2:25:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/types.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/types.ts","statementMap":{"0":{"start":{"line":18,"column":33},"end":{"line":21,"column":null}},"1":{"start":{"line":25,"column":57},"end":{"line":25,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":2,"seen":{"s:18:33:21:Infinity":0,"s:25:57:25:Infinity":1}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/validate-translation-content.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/validators/executive-brief-translations/validate-translation-content.ts","statementMap":{"0":{"start":{"line":42,"column":65},"end":{"line":42,"column":null}},"1":{"start":{"line":43,"column":32},"end":{"line":43,"column":null}},"2":{"start":{"line":46,"column":22},"end":{"line":46,"column":null}},"3":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"4":{"start":{"line":48,"column":2},"end":{"line":54,"column":null}},"5":{"start":{"line":57,"column":18},"end":{"line":57,"column":null}},"6":{"start":{"line":58,"column":18},"end":{"line":58,"column":null}},"7":{"start":{"line":59,"column":2},"end":{"line":65,"column":null}},"8":{"start":{"line":68,"column":20},"end":{"line":68,"column":null}},"9":{"start":{"line":69,"column":20},"end":{"line":69,"column":null}},"10":{"start":{"line":70,"column":2},"end":{"line":76,"column":null}},"11":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"12":{"start":{"line":80,"column":21},"end":{"line":80,"column":null}},"13":{"start":{"line":81,"column":2},"end":{"line":87,"column":null}},"14":{"start":{"line":90,"column":20},"end":{"line":90,"column":null}},"15":{"start":{"line":91,"column":20},"end":{"line":91,"column":null}},"16":{"start":{"line":92,"column":24},"end":{"line":92,"column":null}},"17":{"start":{"line":92,"column":54},"end":{"line":92,"column":72}},"18":{"start":{"line":93,"column":22},"end":{"line":93,"column":null}},"19":{"start":{"line":93,"column":52},"end":{"line":93,"column":70}},"20":{"start":{"line":94,"column":22},"end":{"line":94,"column":null}},"21":{"start":{"line":95,"column":2},"end":{"line":104,"column":null}},"22":{"start":{"line":107,"column":18},"end":{"line":107,"column":null}},"23":{"start":{"line":108,"column":18},"end":{"line":108,"column":null}},"24":{"start":{"line":109,"column":22},"end":{"line":109,"column":null}},"25":{"start":{"line":109,"column":49},"end":{"line":109,"column":64}},"26":{"start":{"line":110,"column":20},"end":{"line":110,"column":null}},"27":{"start":{"line":110,"column":47},"end":{"line":110,"column":62}},"28":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"29":{"start":{"line":112,"column":2},"end":{"line":121,"column":null}},"30":{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},"31":{"start":{"line":125,"column":18},"end":{"line":125,"column":null}},"32":{"start":{"line":126,"column":4},"end":{"line":130,"column":null}},"33":{"start":{"line":134,"column":21},"end":{"line":134,"column":null}},"34":{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},"35":{"start":{"line":136,"column":4},"end":{"line":140,"column":null}},"36":{"start":{"line":142,"column":23},"end":{"line":142,"column":null}},"37":{"start":{"line":143,"column":4},"end":{"line":151,"column":null}},"38":{"start":{"line":155,"column":17},"end":{"line":155,"column":null}},"39":{"start":{"line":156,"column":2},"end":{"line":160,"column":null}},"40":{"start":{"line":167,"column":62},"end":{"line":167,"column":null}},"41":{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},"42":{"start":{"line":169,"column":4},"end":{"line":173,"column":null}},"43":{"start":{"line":175,"column":21},"end":{"line":175,"column":null}},"44":{"start":{"line":176,"column":21},"end":{"line":176,"column":null}},"45":{"start":{"line":177,"column":22},"end":{"line":177,"column":null}},"46":{"start":{"line":178,"column":23},"end":{"line":178,"column":null}},"47":{"start":{"line":179,"column":23},"end":{"line":179,"column":null}},"48":{"start":{"line":180,"column":21},"end":{"line":180,"column":null}},"49":{"start":{"line":181,"column":4},"end":{"line":187,"column":null}},"50":{"start":{"line":190,"column":2},"end":{"line":190,"column":null}}},"fnMap":{"0":{"name":"validateTranslationContent","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":43}},"loc":{"start":{"line":41,"column":92},"end":{"line":191,"column":null}},"line":41},"1":{"name":"(anonymous_1)","decl":{"start":{"line":92,"column":39},"end":{"line":92,"column":47}},"loc":{"start":{"line":92,"column":54},"end":{"line":92,"column":72}},"line":92},"2":{"name":"(anonymous_2)","decl":{"start":{"line":93,"column":37},"end":{"line":93,"column":45}},"loc":{"start":{"line":93,"column":52},"end":{"line":93,"column":70}},"line":93},"3":{"name":"(anonymous_3)","decl":{"start":{"line":109,"column":35},"end":{"line":109,"column":43}},"loc":{"start":{"line":109,"column":49},"end":{"line":109,"column":64}},"line":109},"4":{"name":"(anonymous_4)","decl":{"start":{"line":110,"column":33},"end":{"line":110,"column":41}},"loc":{"start":{"line":110,"column":47},"end":{"line":110,"column":62}},"line":110}},"branchMap":{"0":{"loc":{"start":{"line":51,"column":12},"end":{"line":53,"column":null}},"type":"cond-expr","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":null}},{"start":{"line":53,"column":8},"end":{"line":53,"column":null}}],"line":51},"1":{"loc":{"start":{"line":62,"column":12},"end":{"line":64,"column":null}},"type":"cond-expr","locations":[{"start":{"line":63,"column":8},"end":{"line":63,"column":null}},{"start":{"line":64,"column":8},"end":{"line":64,"column":null}}],"line":62},"2":{"loc":{"start":{"line":73,"column":12},"end":{"line":75,"column":null}},"type":"cond-expr","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":null}},{"start":{"line":75,"column":8},"end":{"line":75,"column":null}}],"line":73},"3":{"loc":{"start":{"line":84,"column":12},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":85,"column":8},"end":{"line":85,"column":null}},{"start":{"line":86,"column":8},"end":{"line":86,"column":null}}],"line":84},"4":{"loc":{"start":{"line":94,"column":22},"end":{"line":94,"column":null}},"type":"binary-expr","locations":[{"start":{"line":94,"column":22},"end":{"line":94,"column":52}},{"start":{"line":94,"column":52},"end":{"line":94,"column":null}}],"line":94},"5":{"loc":{"start":{"line":98,"column":12},"end":{"line":103,"column":null}},"type":"cond-expr","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":null}},{"start":{"line":100,"column":8},"end":{"line":103,"column":null}}],"line":98},"6":{"loc":{"start":{"line":101,"column":10},"end":{"line":101,"column":null}},"type":"cond-expr","locations":[{"start":{"line":101,"column":37},"end":{"line":101,"column":78}},{"start":{"line":101,"column":78},"end":{"line":101,"column":null}}],"line":101},"7":{"loc":{"start":{"line":102,"column":10},"end":{"line":102,"column":null}},"type":"cond-expr","locations":[{"start":{"line":102,"column":35},"end":{"line":102,"column":72}},{"start":{"line":102,"column":72},"end":{"line":102,"column":null}}],"line":102},"8":{"loc":{"start":{"line":111,"column":20},"end":{"line":111,"column":null}},"type":"binary-expr","locations":[{"start":{"line":111,"column":20},"end":{"line":111,"column":48}},{"start":{"line":111,"column":48},"end":{"line":111,"column":null}}],"line":111},"9":{"loc":{"start":{"line":115,"column":12},"end":{"line":120,"column":null}},"type":"cond-expr","locations":[{"start":{"line":116,"column":8},"end":{"line":116,"column":null}},{"start":{"line":117,"column":8},"end":{"line":120,"column":null}}],"line":115},"10":{"loc":{"start":{"line":118,"column":10},"end":{"line":118,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":35},"end":{"line":118,"column":88}},{"start":{"line":118,"column":88},"end":{"line":118,"column":null}}],"line":118},"11":{"loc":{"start":{"line":119,"column":10},"end":{"line":119,"column":null}},"type":"cond-expr","locations":[{"start":{"line":119,"column":33},"end":{"line":119,"column":77}},{"start":{"line":119,"column":77},"end":{"line":119,"column":null}}],"line":119},"12":{"loc":{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":2},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":124},"13":{"loc":{"start":{"line":129,"column":14},"end":{"line":129,"column":null}},"type":"cond-expr","locations":[{"start":{"line":129,"column":22},"end":{"line":129,"column":34}},{"start":{"line":129,"column":34},"end":{"line":129,"column":null}}],"line":129},"14":{"loc":{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":2},"end":{"line":152,"column":null}},{"start":{"line":141,"column":9},"end":{"line":152,"column":null}}],"line":135},"15":{"loc":{"start":{"line":135,"column":6},"end":{"line":135,"column":53}},"type":"binary-expr","locations":[{"start":{"line":135,"column":6},"end":{"line":135,"column":28}},{"start":{"line":135,"column":28},"end":{"line":135,"column":53}}],"line":135},"16":{"loc":{"start":{"line":139,"column":14},"end":{"line":139,"column":null}},"type":"cond-expr","locations":[{"start":{"line":139,"column":27},"end":{"line":139,"column":39}},{"start":{"line":139,"column":39},"end":{"line":139,"column":null}}],"line":139},"17":{"loc":{"start":{"line":146,"column":14},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":147,"column":10},"end":{"line":147,"column":null}},{"start":{"line":148,"column":10},"end":{"line":150,"column":null}}],"line":146},"18":{"loc":{"start":{"line":148,"column":10},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":149,"column":12},"end":{"line":149,"column":null}},{"start":{"line":150,"column":12},"end":{"line":150,"column":null}}],"line":148},"19":{"loc":{"start":{"line":159,"column":12},"end":{"line":159,"column":null}},"type":"cond-expr","locations":[{"start":{"line":159,"column":34},"end":{"line":159,"column":44}},{"start":{"line":159,"column":44},"end":{"line":159,"column":null}}],"line":159},"20":{"loc":{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":2},"end":{"line":188,"column":null}},{"start":{"line":174,"column":9},"end":{"line":188,"column":null}}],"line":168},"21":{"loc":{"start":{"line":180,"column":21},"end":{"line":180,"column":null}},"type":"binary-expr","locations":[{"start":{"line":180,"column":21},"end":{"line":180,"column":47}},{"start":{"line":180,"column":47},"end":{"line":180,"column":null}}],"line":180},"22":{"loc":{"start":{"line":184,"column":14},"end":{"line":186,"column":null}},"type":"cond-expr","locations":[{"start":{"line":185,"column":10},"end":{"line":185,"column":null}},{"start":{"line":186,"column":10},"end":{"line":186,"column":null}}],"line":184}},"s":{"0":11,"1":11,"2":11,"3":11,"4":11,"5":11,"6":11,"7":11,"8":11,"9":11,"10":11,"11":11,"12":11,"13":11,"14":11,"15":11,"16":11,"17":33,"18":11,"19":23,"20":11,"21":11,"22":11,"23":11,"24":11,"25":22,"26":11,"27":15,"28":11,"29":11,"30":11,"31":2,"32":2,"33":11,"34":11,"35":0,"36":11,"37":11,"38":11,"39":11,"40":11,"41":11,"42":2,"43":9,"44":9,"45":9,"46":9,"47":9,"48":9,"49":9,"50":11},"f":{"0":11,"1":33,"2":23,"3":22,"4":15},"b":{"0":[11,0],"1":[11,0],"2":[10,1],"3":[11,0],"4":[11,7],"5":[7,4],"6":[4,0],"7":[0,4],"8":[11,7],"9":[7,4],"10":[4,0],"11":[0,4],"12":[2,9],"13":[1,1],"14":[0,11],"15":[11,11],"16":[0,0],"17":[2,9],"18":[8,1],"19":[11,0],"20":[2,9],"21":[9,8],"22":[8,1]},"meta":{"lastBranch":23,"lastFunction":5,"lastStatement":51,"seen":{"f:41:16:41:43":0,"s:42:65:42:Infinity":0,"s:43:32:43:Infinity":1,"s:46:22:46:Infinity":2,"s:47:22:47:Infinity":3,"s:48:2:54:Infinity":4,"b:52:8:52:Infinity:53:8:53:Infinity":0,"s:57:18:57:Infinity":5,"s:58:18:58:Infinity":6,"s:59:2:65:Infinity":7,"b:63:8:63:Infinity:64:8:64:Infinity":1,"s:68:20:68:Infinity":8,"s:69:20:69:Infinity":9,"s:70:2:76:Infinity":10,"b:74:8:74:Infinity:75:8:75:Infinity":2,"s:79:21:79:Infinity":11,"s:80:21:80:Infinity":12,"s:81:2:87:Infinity":13,"b:85:8:85:Infinity:86:8:86:Infinity":3,"s:90:20:90:Infinity":14,"s:91:20:91:Infinity":15,"s:92:24:92:Infinity":16,"f:92:39:92:47":1,"s:92:54:92:72":17,"s:93:22:93:Infinity":18,"f:93:37:93:45":2,"s:93:52:93:70":19,"s:94:22:94:Infinity":20,"b:94:22:94:52:94:52:94:Infinity":4,"s:95:2:104:Infinity":21,"b:99:8:99:Infinity:100:8:103:Infinity":5,"b:101:37:101:78:101:78:101:Infinity":6,"b:102:35:102:72:102:72:102:Infinity":7,"s:107:18:107:Infinity":22,"s:108:18:108:Infinity":23,"s:109:22:109:Infinity":24,"f:109:35:109:43":3,"s:109:49:109:64":25,"s:110:20:110:Infinity":26,"f:110:33:110:41":4,"s:110:47:110:62":27,"s:111:20:111:Infinity":28,"b:111:20:111:48:111:48:111:Infinity":8,"s:112:2:121:Infinity":29,"b:116:8:116:Infinity:117:8:120:Infinity":9,"b:118:35:118:88:118:88:118:Infinity":10,"b:119:33:119:77:119:77:119:Infinity":11,"b:124:2:131:Infinity:undefined:undefined:undefined:undefined":12,"s:124:2:131:Infinity":30,"s:125:18:125:Infinity":31,"s:126:4:130:Infinity":32,"b:129:22:129:34:129:34:129:Infinity":13,"s:134:21:134:Infinity":33,"b:135:2:152:Infinity:141:9:152:Infinity":14,"s:135:2:152:Infinity":34,"b:135:6:135:28:135:28:135:53":15,"s:136:4:140:Infinity":35,"b:139:27:139:39:139:39:139:Infinity":16,"s:142:23:142:Infinity":36,"s:143:4:151:Infinity":37,"b:147:10:147:Infinity:148:10:150:Infinity":17,"b:149:12:149:Infinity:150:12:150:Infinity":18,"s:155:17:155:Infinity":38,"s:156:2:160:Infinity":39,"b:159:34:159:44:159:44:159:Infinity":19,"s:167:62:167:Infinity":40,"b:168:2:188:Infinity:174:9:188:Infinity":20,"s:168:2:188:Infinity":41,"s:169:4:173:Infinity":42,"s:175:21:175:Infinity":43,"s:176:21:176:Infinity":44,"s:177:22:177:Infinity":45,"s:178:23:178:Infinity":46,"s:179:23:179:Infinity":47,"s:180:21:180:Infinity":48,"b:180:21:180:47:180:47:180:Infinity":21,"s:181:4:187:Infinity":49,"b:185:10:185:Infinity:186:10:186:Infinity":22,"s:190:2:190:Infinity":50}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-static-pages.js":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-static-pages.js","statementMap":{"0":{"start":{"line":104,"column":2},"end":{"line":104,"column":103}},"1":{"start":{"line":127,"column":2},"end":{"line":127,"column":125}},"2":{"start":{"line":148,"column":23},"end":{"line":148,"column":67}},"3":{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},"4":{"start":{"line":151,"column":21},"end":{"line":151,"column":70}},"5":{"start":{"line":152,"column":18},"end":{"line":152,"column":40}},"6":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"7":{"start":{"line":153,"column":60},"end":{"line":153,"column":null}},"8":{"start":{"line":156,"column":20},"end":{"line":156,"column":48}},"9":{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},"10":{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},"11":{"start":{"line":160,"column":6},"end":{"line":160,"column":null}},"12":{"start":{"line":163,"column":17},"end":{"line":165,"column":60}},"13":{"start":{"line":165,"column":21},"end":{"line":165,"column":59}},"14":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"15":{"start":{"line":166,"column":27},"end":{"line":166,"column":null}},"16":{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},"17":{"start":{"line":168,"column":6},"end":{"line":171,"column":null}},"18":{"start":{"line":175,"column":2},"end":{"line":179,"column":null}},"19":{"start":{"line":202,"column":23},"end":{"line":202,"column":67}},"20":{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},"21":{"start":{"line":205,"column":21},"end":{"line":205,"column":70}},"22":{"start":{"line":206,"column":16},"end":{"line":206,"column":45}},"23":{"start":{"line":207,"column":18},"end":{"line":207,"column":31}},"24":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"25":{"start":{"line":208,"column":59},"end":{"line":208,"column":null}},"26":{"start":{"line":211,"column":16},"end":{"line":211,"column":50}},"27":{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},"28":{"start":{"line":213,"column":15},"end":{"line":213,"column":63}},"29":{"start":{"line":214,"column":17},"end":{"line":214,"column":64}},"30":{"start":{"line":214,"column":53},"end":{"line":214,"column":63}},"31":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"32":{"start":{"line":215,"column":27},"end":{"line":215,"column":null}},"33":{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},"34":{"start":{"line":217,"column":6},"end":{"line":220,"column":null}},"35":{"start":{"line":224,"column":2},"end":{"line":224,"column":null}},"36":{"start":{"line":236,"column":16},"end":{"line":236,"column":18}},"37":{"start":{"line":237,"column":2},"end":{"line":264,"column":null}},"38":{"start":{"line":238,"column":16},"end":{"line":238,"column":48}},"39":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"40":{"start":{"line":239,"column":29},"end":{"line":239,"column":null}},"41":{"start":{"line":240,"column":17},"end":{"line":240,"column":33}},"42":{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},"43":{"start":{"line":242,"column":6},"end":{"line":242,"column":null}},"44":{"start":{"line":243,"column":6},"end":{"line":243,"column":null}},"45":{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},"46":{"start":{"line":246,"column":22},"end":{"line":246,"column":66}},"47":{"start":{"line":247,"column":6},"end":{"line":251,"column":null}},"48":{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},"49":{"start":{"line":249,"column":10},"end":{"line":249,"column":null}},"50":{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},"51":{"start":{"line":253,"column":8},"end":{"line":261,"column":null}},"52":{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},"53":{"start":{"line":254,"column":32},"end":{"line":254,"column":null}},"54":{"start":{"line":255,"column":10},"end":{"line":260,"column":null}},"55":{"start":{"line":265,"column":2},"end":{"line":265,"column":null}},"56":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"57":{"start":{"line":280,"column":38},"end":{"line":280,"column":null}},"58":{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},"59":{"start":{"line":281,"column":36},"end":{"line":281,"column":null}},"60":{"start":{"line":282,"column":2},"end":{"line":282,"column":null}},"61":{"start":{"line":296,"column":44},"end":{"line":296,"column":51}},"62":{"start":{"line":298,"column":2},"end":{"line":394,"column":null}},"63":{"start":{"line":307,"column":24},"end":{"line":307,"column":89}},"64":{"start":{"line":308,"column":29},"end":{"line":308,"column":57}},"65":{"start":{"line":311,"column":33},"end":{"line":311,"column":42}},"66":{"start":{"line":312,"column":30},"end":{"line":317,"column":9}},"67":{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},"68":{"start":{"line":314,"column":12},"end":{"line":314,"column":null}},"69":{"start":{"line":316,"column":10},"end":{"line":316,"column":null}},"70":{"start":{"line":319,"column":27},"end":{"line":319,"column":28}},"71":{"start":{"line":320,"column":29},"end":{"line":320,"column":30}},"72":{"start":{"line":321,"column":35},"end":{"line":321,"column":36}},"73":{"start":{"line":322,"column":27},"end":{"line":322,"column":29}},"74":{"start":{"line":324,"column":8},"end":{"line":381,"column":null}},"75":{"start":{"line":325,"column":24},"end":{"line":325,"column":58}},"76":{"start":{"line":326,"column":24},"end":{"line":326,"column":25}},"77":{"start":{"line":327,"column":26},"end":{"line":327,"column":27}},"78":{"start":{"line":328,"column":32},"end":{"line":328,"column":33}},"79":{"start":{"line":330,"column":10},"end":{"line":375,"column":null}},"80":{"start":{"line":331,"column":24},"end":{"line":331,"column":59}},"81":{"start":{"line":332,"column":28},"end":{"line":332,"column":51}},"82":{"start":{"line":333,"column":12},"end":{"line":333,"column":null}},"83":{"start":{"line":335,"column":25},"end":{"line":335,"column":57}},"84":{"start":{"line":336,"column":29},"end":{"line":336,"column":34}},"85":{"start":{"line":337,"column":35},"end":{"line":337,"column":40}},"86":{"start":{"line":341,"column":22},"end":{"line":351,"column":13}},"87":{"start":{"line":344,"column":16},"end":{"line":344,"column":null}},"88":{"start":{"line":345,"column":32},"end":{"line":345,"column":65}},"89":{"start":{"line":346,"column":16},"end":{"line":349,"column":null}},"90":{"start":{"line":353,"column":12},"end":{"line":369,"column":null}},"91":{"start":{"line":354,"column":31},"end":{"line":354,"column":55}},"92":{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},"93":{"start":{"line":356,"column":16},"end":{"line":356,"column":null}},"94":{"start":{"line":358,"column":14},"end":{"line":358,"column":null}},"95":{"start":{"line":359,"column":33},"end":{"line":363,"column":25}},"96":{"start":{"line":360,"column":16},"end":{"line":363,"column":25}},"97":{"start":{"line":364,"column":34},"end":{"line":364,"column":52}},"98":{"start":{"line":365,"column":33},"end":{"line":365,"column":50}},"99":{"start":{"line":366,"column":32},"end":{"line":366,"column":68}},"100":{"start":{"line":367,"column":31},"end":{"line":367,"column":65}},"101":{"start":{"line":368,"column":14},"end":{"line":368,"column":null}},"102":{"start":{"line":371,"column":12},"end":{"line":371,"column":null}},"103":{"start":{"line":372,"column":12},"end":{"line":372,"column":null}},"104":{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},"105":{"start":{"line":373,"column":28},"end":{"line":373,"column":null}},"106":{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},"107":{"start":{"line":374,"column":34},"end":{"line":374,"column":null}},"108":{"start":{"line":377,"column":10},"end":{"line":377,"column":null}},"109":{"start":{"line":378,"column":10},"end":{"line":378,"column":null}},"110":{"start":{"line":379,"column":10},"end":{"line":379,"column":null}},"111":{"start":{"line":380,"column":10},"end":{"line":380,"column":null}},"112":{"start":{"line":383,"column":24},"end":{"line":385,"column":21}},"113":{"start":{"line":384,"column":22},"end":{"line":384,"column":81}},"114":{"start":{"line":386,"column":8},"end":{"line":391,"column":null}}},"fnMap":{"0":{"name":"readStylesAssetName","decl":{"start":{"line":147,"column":9},"end":{"line":147,"column":28}},"loc":{"start":{"line":147,"column":38},"end":{"line":180,"column":null}},"line":147},"1":{"name":"(anonymous_1)","decl":{"start":{"line":165,"column":14},"end":{"line":165,"column":15}},"loc":{"start":{"line":165,"column":21},"end":{"line":165,"column":59}},"line":165},"2":{"name":"readModuleAssetName","decl":{"start":{"line":201,"column":9},"end":{"line":201,"column":28}},"loc":{"start":{"line":201,"column":49},"end":{"line":225,"column":null}},"line":201},"3":{"name":"(anonymous_3)","decl":{"start":{"line":214,"column":46},"end":{"line":214,"column":47}},"loc":{"start":{"line":214,"column":53},"end":{"line":214,"column":63}},"line":214},"4":{"name":"resolvePageFiles","decl":{"start":{"line":235,"column":9},"end":{"line":235,"column":25}},"loc":{"start":{"line":235,"column":44},"end":{"line":266,"column":null}},"line":235},"5":{"name":"rewrittenHref","decl":{"start":{"line":279,"column":9},"end":{"line":279,"column":22}},"loc":{"start":{"line":279,"column":51},"end":{"line":283,"column":null}},"line":279},"6":{"name":"staticPagesPlugin","decl":{"start":{"line":295,"column":24},"end":{"line":295,"column":41}},"loc":{"start":{"line":295,"column":51},"end":{"line":395,"column":null}},"line":295},"7":{"name":"(anonymous_7)","decl":{"start":{"line":306,"column":6},"end":{"line":306,"column":13}},"loc":{"start":{"line":306,"column":16},"end":{"line":392,"column":7}},"line":306},"8":{"name":"(anonymous_8)","decl":{"start":{"line":312,"column":30},"end":{"line":312,"column":31}},"loc":{"start":{"line":312,"column":45},"end":{"line":317,"column":9}},"line":312},"9":{"name":"(anonymous_9)","decl":{"start":{"line":343,"column":14},"end":{"line":343,"column":15}},"loc":{"start":{"line":343,"column":48},"end":{"line":350,"column":15}},"line":343},"10":{"name":"(anonymous_10)","decl":{"start":{"line":353,"column":48},"end":{"line":353,"column":49}},"loc":{"start":{"line":353,"column":85},"end":{"line":369,"column":13}},"line":353},"11":{"name":"(anonymous_11)","decl":{"start":{"line":359,"column":33},"end":{"line":359,"column":34}},"loc":{"start":{"line":360,"column":16},"end":{"line":363,"column":25}},"line":360},"12":{"name":"(anonymous_12)","decl":{"start":{"line":384,"column":15},"end":{"line":384,"column":16}},"loc":{"start":{"line":384,"column":22},"end":{"line":384,"column":81}},"line":384}},"branchMap":{"0":{"loc":{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},"type":"if","locations":[{"start":{"line":149,"column":2},"end":{"line":154,"column":null}},{"start":{},"end":{}}],"line":149},"1":{"loc":{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},"type":"if","locations":[{"start":{"line":153,"column":4},"end":{"line":153,"column":null}},{"start":{},"end":{}}],"line":153},"2":{"loc":{"start":{"line":153,"column":8},"end":{"line":153,"column":58}},"type":"binary-expr","locations":[{"start":{"line":153,"column":8},"end":{"line":153,"column":13}},{"start":{"line":153,"column":17},"end":{"line":153,"column":27}},{"start":{"line":153,"column":31},"end":{"line":153,"column":58}}],"line":153},"3":{"loc":{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},"type":"if","locations":[{"start":{"line":157,"column":2},"end":{"line":173,"column":null}},{"start":{},"end":{}}],"line":157},"4":{"loc":{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},"type":"if","locations":[{"start":{"line":159,"column":4},"end":{"line":161,"column":null}},{"start":{},"end":{}}],"line":159},"5":{"loc":{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},"type":"if","locations":[{"start":{"line":166,"column":4},"end":{"line":166,"column":null}},{"start":{},"end":{}}],"line":166},"6":{"loc":{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},"type":"if","locations":[{"start":{"line":167,"column":4},"end":{"line":172,"column":null}},{"start":{},"end":{}}],"line":167},"7":{"loc":{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},"type":"if","locations":[{"start":{"line":203,"column":2},"end":{"line":209,"column":null}},{"start":{},"end":{}}],"line":203},"8":{"loc":{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},"type":"if","locations":[{"start":{"line":208,"column":4},"end":{"line":208,"column":null}},{"start":{},"end":{}}],"line":208},"9":{"loc":{"start":{"line":208,"column":8},"end":{"line":208,"column":57}},"type":"binary-expr","locations":[{"start":{"line":208,"column":8},"end":{"line":208,"column":13}},{"start":{"line":208,"column":17},"end":{"line":208,"column":27}},{"start":{"line":208,"column":31},"end":{"line":208,"column":57}}],"line":208},"10":{"loc":{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},"type":"if","locations":[{"start":{"line":212,"column":2},"end":{"line":222,"column":null}},{"start":{},"end":{}}],"line":212},"11":{"loc":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"type":"if","locations":[{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},{"start":{},"end":{}}],"line":215},"12":{"loc":{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},"type":"if","locations":[{"start":{"line":216,"column":4},"end":{"line":221,"column":null}},{"start":{},"end":{}}],"line":216},"13":{"loc":{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},"type":"if","locations":[{"start":{"line":239,"column":4},"end":{"line":239,"column":null}},{"start":{},"end":{}}],"line":239},"14":{"loc":{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},"type":"if","locations":[{"start":{"line":241,"column":4},"end":{"line":244,"column":null}},{"start":{},"end":{}}],"line":241},"15":{"loc":{"start":{"line":241,"column":8},"end":{"line":241,"column":46}},"type":"binary-expr","locations":[{"start":{"line":241,"column":8},"end":{"line":241,"column":21}},{"start":{"line":241,"column":25},"end":{"line":241,"column":46}}],"line":241},"16":{"loc":{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},"type":"if","locations":[{"start":{"line":245,"column":4},"end":{"line":263,"column":null}},{"start":{},"end":{}}],"line":245},"17":{"loc":{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":8},"end":{"line":250,"column":null}},{"start":{},"end":{}}],"line":248},"18":{"loc":{"start":{"line":248,"column":12},"end":{"line":248,"column":50}},"type":"binary-expr","locations":[{"start":{"line":248,"column":12},"end":{"line":248,"column":22}},{"start":{"line":248,"column":26},"end":{"line":248,"column":50}}],"line":248},"19":{"loc":{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},"type":"if","locations":[{"start":{"line":252,"column":6},"end":{"line":262,"column":null}},{"start":{},"end":{}}],"line":252},"20":{"loc":{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},"type":"if","locations":[{"start":{"line":254,"column":10},"end":{"line":254,"column":null}},{"start":{},"end":{}}],"line":254},"21":{"loc":{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},"type":"if","locations":[{"start":{"line":280,"column":2},"end":{"line":280,"column":null}},{"start":{},"end":{}}],"line":280},"22":{"loc":{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},"type":"if","locations":[{"start":{"line":281,"column":2},"end":{"line":281,"column":null}},{"start":{},"end":{}}],"line":281},"23":{"loc":{"start":{"line":307,"column":24},"end":{"line":307,"column":89}},"type":"cond-expr","locations":[{"start":{"line":307,"column":50},"end":{"line":307,"column":56}},{"start":{"line":307,"column":59},"end":{"line":307,"column":89}}],"line":307},"24":{"loc":{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},"type":"if","locations":[{"start":{"line":313,"column":10},"end":{"line":315,"column":null}},{"start":{},"end":{}}],"line":313},"25":{"loc":{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},"type":"if","locations":[{"start":{"line":355,"column":14},"end":{"line":357,"column":null}},{"start":{},"end":{}}],"line":355},"26":{"loc":{"start":{"line":366,"column":32},"end":{"line":366,"column":68}},"type":"cond-expr","locations":[{"start":{"line":366,"column":46},"end":{"line":366,"column":63}},{"start":{"line":366,"column":66},"end":{"line":366,"column":68}}],"line":366},"27":{"loc":{"start":{"line":367,"column":31},"end":{"line":367,"column":65}},"type":"cond-expr","locations":[{"start":{"line":367,"column":44},"end":{"line":367,"column":60}},{"start":{"line":367,"column":63},"end":{"line":367,"column":65}}],"line":367},"28":{"loc":{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},"type":"if","locations":[{"start":{"line":373,"column":12},"end":{"line":373,"column":null}},{"start":{},"end":{}}],"line":373},"29":{"loc":{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},"type":"if","locations":[{"start":{"line":374,"column":12},"end":{"line":374,"column":null}},{"start":{},"end":{}}],"line":374}},"s":{"0":1,"1":1,"2":16,"3":16,"4":16,"5":16,"6":16,"7":13,"8":3,"9":3,"10":3,"11":1,"12":2,"13":1,"14":2,"15":1,"16":1,"17":0,"18":1,"19":5,"20":5,"21":5,"22":5,"23":5,"24":5,"25":3,"26":2,"27":2,"28":1,"29":1,"30":1,"31":1,"32":1,"33":0,"34":0,"35":1,"36":15,"37":15,"38":15,"39":15,"40":1,"41":14,"42":14,"43":6,"44":6,"45":8,"46":8,"47":8,"48":16,"49":16,"50":8,"51":1,"52":2,"53":2,"54":0,"55":15,"56":21,"57":16,"58":5,"59":0,"60":5,"61":17,"62":17,"63":16,"64":16,"65":16,"66":16,"67":8,"68":5,"69":8,"70":16,"71":16,"72":16,"73":16,"74":16,"75":15,"76":15,"77":15,"78":15,"79":15,"80":22,"81":22,"82":22,"83":22,"84":22,"85":22,"86":22,"87":21,"88":21,"89":21,"90":22,"91":8,"92":8,"93":1,"94":7,"95":7,"96":14,"97":7,"98":7,"99":7,"100":8,"101":8,"102":22,"103":22,"104":22,"105":21,"106":22,"107":7,"108":15,"109":15,"110":15,"111":15,"112":15,"113":15,"114":15},"f":{"0":16,"1":1,"2":5,"3":1,"4":15,"5":21,"6":17,"7":16,"8":8,"9":21,"10":8,"11":14,"12":15},"b":{"0":[16,0],"1":[13,3],"2":[16,13,13],"3":[3,0],"4":[1,2],"5":[1,1],"6":[0,1],"7":[5,0],"8":[3,2],"9":[5,3,3],"10":[1,1],"11":[1,0],"12":[0,0],"13":[1,14],"14":[6,8],"15":[14,6],"16":[8,0],"17":[16,0],"18":[16,16],"19":[1,7],"20":[2,0],"21":[16,5],"22":[0,5],"23":[0,16],"24":[5,3],"25":[1,7],"26":[7,0],"27":[0,7],"28":[21,1],"29":[7,15]},"meta":{"lastBranch":30,"lastFunction":13,"lastStatement":115,"seen":{"s:104:2:104:103":0,"s:127:2:127:125":1,"f:147:9:147:28":0,"s:148:23:148:67":2,"b:149:2:154:Infinity:undefined:undefined:undefined:undefined":0,"s:149:2:154:Infinity":3,"s:151:21:151:70":4,"s:152:18:152:40":5,"b:153:4:153:Infinity:undefined:undefined:undefined:undefined":1,"s:153:4:153:Infinity":6,"b:153:8:153:13:153:17:153:27:153:31:153:58":2,"s:153:60:153:Infinity":7,"s:156:20:156:48":8,"b:157:2:173:Infinity:undefined:undefined:undefined:undefined":3,"s:157:2:173:Infinity":9,"b:159:4:161:Infinity:undefined:undefined:undefined:undefined":4,"s:159:4:161:Infinity":10,"s:160:6:160:Infinity":11,"s:163:17:165:60":12,"f:165:14:165:15":1,"s:165:21:165:59":13,"b:166:4:166:Infinity:undefined:undefined:undefined:undefined":5,"s:166:4:166:Infinity":14,"s:166:27:166:Infinity":15,"b:167:4:172:Infinity:undefined:undefined:undefined:undefined":6,"s:167:4:172:Infinity":16,"s:168:6:171:Infinity":17,"s:175:2:179:Infinity":18,"f:201:9:201:28":2,"s:202:23:202:67":19,"b:203:2:209:Infinity:undefined:undefined:undefined:undefined":7,"s:203:2:209:Infinity":20,"s:205:21:205:70":21,"s:206:16:206:45":22,"s:207:18:207:31":23,"b:208:4:208:Infinity:undefined:undefined:undefined:undefined":8,"s:208:4:208:Infinity":24,"b:208:8:208:13:208:17:208:27:208:31:208:57":9,"s:208:59:208:Infinity":25,"s:211:16:211:50":26,"b:212:2:222:Infinity:undefined:undefined:undefined:undefined":10,"s:212:2:222:Infinity":27,"s:213:15:213:63":28,"s:214:17:214:64":29,"f:214:46:214:47":3,"s:214:53:214:63":30,"b:215:4:215:Infinity:undefined:undefined:undefined:undefined":11,"s:215:4:215:Infinity":31,"s:215:27:215:Infinity":32,"b:216:4:221:Infinity:undefined:undefined:undefined:undefined":12,"s:216:4:221:Infinity":33,"s:217:6:220:Infinity":34,"s:224:2:224:Infinity":35,"f:235:9:235:25":4,"s:236:16:236:18":36,"s:237:2:264:Infinity":37,"s:238:16:238:48":38,"b:239:4:239:Infinity:undefined:undefined:undefined:undefined":13,"s:239:4:239:Infinity":39,"s:239:29:239:Infinity":40,"s:240:17:240:33":41,"b:241:4:244:Infinity:undefined:undefined:undefined:undefined":14,"s:241:4:244:Infinity":42,"b:241:8:241:21:241:25:241:46":15,"s:242:6:242:Infinity":43,"s:243:6:243:Infinity":44,"b:245:4:263:Infinity:undefined:undefined:undefined:undefined":16,"s:245:4:263:Infinity":45,"s:246:22:246:66":46,"s:247:6:251:Infinity":47,"b:248:8:250:Infinity:undefined:undefined:undefined:undefined":17,"s:248:8:250:Infinity":48,"b:248:12:248:22:248:26:248:50":18,"s:249:10:249:Infinity":49,"b:252:6:262:Infinity:undefined:undefined:undefined:undefined":19,"s:252:6:262:Infinity":50,"s:253:8:261:Infinity":51,"b:254:10:254:Infinity:undefined:undefined:undefined:undefined":20,"s:254:10:254:Infinity":52,"s:254:32:254:Infinity":53,"s:255:10:260:Infinity":54,"s:265:2:265:Infinity":55,"f:279:9:279:22":5,"b:280:2:280:Infinity:undefined:undefined:undefined:undefined":21,"s:280:2:280:Infinity":56,"s:280:38:280:Infinity":57,"b:281:2:281:Infinity:undefined:undefined:undefined:undefined":22,"s:281:2:281:Infinity":58,"s:281:36:281:Infinity":59,"s:282:2:282:Infinity":60,"f:295:24:295:41":6,"s:296:44:296:51":61,"s:298:2:394:Infinity":62,"f:306:6:306:13":7,"s:307:24:307:89":63,"b:307:50:307:56:307:59:307:89":23,"s:308:29:308:57":64,"s:311:33:311:42":65,"s:312:30:317:9":66,"f:312:30:312:31":8,"b:313:10:315:Infinity:undefined:undefined:undefined:undefined":24,"s:313:10:315:Infinity":67,"s:314:12:314:Infinity":68,"s:316:10:316:Infinity":69,"s:319:27:319:28":70,"s:320:29:320:30":71,"s:321:35:321:36":72,"s:322:27:322:29":73,"s:324:8:381:Infinity":74,"s:325:24:325:58":75,"s:326:24:326:25":76,"s:327:26:327:27":77,"s:328:32:328:33":78,"s:330:10:375:Infinity":79,"s:331:24:331:59":80,"s:332:28:332:51":81,"s:333:12:333:Infinity":82,"s:335:25:335:57":83,"s:336:29:336:34":84,"s:337:35:337:40":85,"s:341:22:351:13":86,"f:343:14:343:15":9,"s:344:16:344:Infinity":87,"s:345:32:345:65":88,"s:346:16:349:Infinity":89,"s:353:12:369:Infinity":90,"f:353:48:353:49":10,"s:354:31:354:55":91,"b:355:14:357:Infinity:undefined:undefined:undefined:undefined":25,"s:355:14:357:Infinity":92,"s:356:16:356:Infinity":93,"s:358:14:358:Infinity":94,"s:359:33:363:25":95,"f:359:33:359:34":11,"s:360:16:363:25":96,"s:364:34:364:52":97,"s:365:33:365:50":98,"s:366:32:366:68":99,"b:366:46:366:63:366:66:366:68":26,"s:367:31:367:65":100,"b:367:44:367:60:367:63:367:65":27,"s:368:14:368:Infinity":101,"s:371:12:371:Infinity":102,"s:372:12:372:Infinity":103,"b:373:12:373:Infinity:undefined:undefined:undefined:undefined":28,"s:373:12:373:Infinity":104,"s:373:28:373:Infinity":105,"b:374:12:374:Infinity:undefined:undefined:undefined:undefined":29,"s:374:12:374:Infinity":106,"s:374:34:374:Infinity":107,"s:377:10:377:Infinity":108,"s:378:10:378:Infinity":109,"s:379:10:379:Infinity":110,"s:380:10:380:Infinity":111,"s:383:24:385:21":112,"f:384:15:384:16":12,"s:384:22:384:81":113,"s:386:8:391:Infinity":114}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-sw-build-id.js":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/vite-plugin-sw-build-id.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":66}},"1":{"start":{"line":54,"column":17},"end":{"line":54,"column":39}},"2":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"3":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"4":{"start":{"line":59,"column":2},"end":{"line":69,"column":null}},"5":{"start":{"line":60,"column":16},"end":{"line":63,"column":13}},"6":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"7":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"8":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"9":{"start":{"line":81,"column":43},"end":{"line":81,"column":50}},"10":{"start":{"line":83,"column":2},"end":{"line":125,"column":null}},"11":{"start":{"line":92,"column":24},"end":{"line":92,"column":40}},"12":{"start":{"line":93,"column":24},"end":{"line":95,"column":42}},"13":{"start":{"line":97,"column":24},"end":{"line":97,"column":65}},"14":{"start":{"line":98,"column":25},"end":{"line":98,"column":52}},"15":{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},"16":{"start":{"line":101,"column":10},"end":{"line":103,"column":null}},"17":{"start":{"line":106,"column":20},"end":{"line":106,"column":52}},"18":{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},"19":{"start":{"line":108,"column":10},"end":{"line":112,"column":null}},"20":{"start":{"line":115,"column":20},"end":{"line":115,"column":59}},"21":{"start":{"line":117,"column":8},"end":{"line":117,"column":null}},"22":{"start":{"line":118,"column":8},"end":{"line":118,"column":null}},"23":{"start":{"line":120,"column":8},"end":{"line":122,"column":null}}},"fnMap":{"0":{"name":"resolveBuildId","decl":{"start":{"line":53,"column":9},"end":{"line":53,"column":23}},"loc":{"start":{"line":53,"column":26},"end":{"line":72,"column":null}},"line":53},"1":{"name":"swBuildIdPlugin","decl":{"start":{"line":80,"column":24},"end":{"line":80,"column":39}},"loc":{"start":{"line":80,"column":49},"end":{"line":126,"column":null}},"line":80},"2":{"name":"(anonymous_2)","decl":{"start":{"line":91,"column":6},"end":{"line":91,"column":13}},"loc":{"start":{"line":91,"column":16},"end":{"line":123,"column":7}},"line":91}},"branchMap":{"0":{"loc":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":55},"1":{"loc":{"start":{"line":55,"column":6},"end":{"line":55,"column":43}},"type":"binary-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":12}},{"start":{"line":55,"column":16},"end":{"line":55,"column":43}}],"line":55},"2":{"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"3":{"loc":{"start":{"line":64,"column":8},"end":{"line":64,"column":51}},"type":"binary-expr","locations":[{"start":{"line":64,"column":8},"end":{"line":64,"column":32}},{"start":{"line":64,"column":36},"end":{"line":64,"column":51}}],"line":64},"4":{"loc":{"start":{"line":81,"column":23},"end":{"line":81,"column":38}},"type":"default-arg","locations":[{"start":{"line":81,"column":32},"end":{"line":81,"column":38}}],"line":81},"5":{"loc":{"start":{"line":93,"column":24},"end":{"line":95,"column":42}},"type":"cond-expr","locations":[{"start":{"line":94,"column":12},"end":{"line":94,"column":null}},{"start":{"line":95,"column":12},"end":{"line":95,"column":42}}],"line":93},"6":{"loc":{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":104,"column":null}},{"start":{},"end":{}}],"line":100},"7":{"loc":{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":107,"column":8},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":107}},"s":{"0":1,"1":6,"2":6,"3":5,"4":1,"5":1,"6":1,"7":1,"8":0,"9":7,"10":7,"11":6,"12":6,"13":6,"14":6,"15":6,"16":1,"17":5,"18":5,"19":1,"20":4,"21":4,"22":4,"23":4},"f":{"0":6,"1":7,"2":6},"b":{"0":[5,1],"1":[6,5],"2":[1,0],"3":[1,1],"4":[7],"5":[0,6],"6":[1,5],"7":[1,4]},"meta":{"lastBranch":8,"lastFunction":3,"lastStatement":24,"seen":{"s:1:17:1:66":0,"f:53:9:53:23":0,"s:54:17:54:39":1,"b:55:2:57:Infinity:undefined:undefined:undefined:undefined":0,"s:55:2:57:Infinity":2,"b:55:6:55:12:55:16:55:43":1,"s:56:4:56:Infinity":3,"s:59:2:69:Infinity":4,"s:60:16:63:13":5,"b:64:4:66:Infinity:undefined:undefined:undefined:undefined":2,"s:64:4:66:Infinity":6,"b:64:8:64:32:64:36:64:51":3,"s:65:6:65:Infinity":7,"s:71:2:71:Infinity":8,"f:80:24:80:39":1,"s:81:43:81:50":9,"b:81:32:81:38":4,"s:83:2:125:Infinity":10,"f:91:6:91:13":2,"s:92:24:92:40":11,"s:93:24:95:42":12,"b:94:12:94:Infinity:95:12:95:42":5,"s:97:24:97:65":13,"s:98:25:98:52":14,"b:100:8:104:Infinity:undefined:undefined:undefined:undefined":6,"s:100:8:104:Infinity":15,"s:101:10:103:Infinity":16,"s:106:20:106:52":17,"b:107:8:113:Infinity:undefined:undefined:undefined:undefined":7,"s:107:8:113:Infinity":18,"s:108:10:112:Infinity":19,"s:115:20:115:59":20,"s:117:8:117:Infinity":21,"s:118:8:118:Infinity":22,"s:120:8:122:Infinity":23}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-client.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-client.ts","statementMap":{"0":{"start":{"line":57,"column":25},"end":{"line":57,"column":null}},"1":{"start":{"line":58,"column":24},"end":{"line":58,"column":null}},"2":{"start":{"line":59,"column":28},"end":{"line":59,"column":null}},"3":{"start":{"line":66,"column":26},"end":{"line":71,"column":null}},"4":{"start":{"line":74,"column":33},"end":{"line":76,"column":null}},"5":{"start":{"line":79,"column":29},"end":{"line":86,"column":null}},"6":{"start":{"line":120,"column":29},"end":{"line":323,"column":null}},"7":{"start":{"line":339,"column":4},"end":{"line":339,"column":null}},"8":{"start":{"line":340,"column":4},"end":{"line":340,"column":null}},"9":{"start":{"line":341,"column":4},"end":{"line":341,"column":null}},"10":{"start":{"line":357,"column":24},"end":{"line":357,"column":null}},"11":{"start":{"line":358,"column":16},"end":{"line":358,"column":null}},"12":{"start":{"line":360,"column":17},"end":{"line":360,"column":null}},"13":{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},"14":{"start":{"line":363,"column":6},"end":{"line":363,"column":null}},"15":{"start":{"line":366,"column":4},"end":{"line":383,"column":null}},"16":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"17":{"start":{"line":368,"column":22},"end":{"line":375,"column":8}},"18":{"start":{"line":377,"column":22},"end":{"line":377,"column":null}},"19":{"start":{"line":378,"column":22},"end":{"line":378,"column":null}},"20":{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},"21":{"start":{"line":379,"column":42},"end":{"line":379,"column":null}},"22":{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},"23":{"start":{"line":380,"column":26},"end":{"line":380,"column":null}},"24":{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},"25":{"start":{"line":381,"column":26},"end":{"line":381,"column":null}},"26":{"start":{"line":382,"column":8},"end":{"line":382,"column":null}},"27":{"start":{"line":397,"column":20},"end":{"line":397,"column":null}},"28":{"start":{"line":398,"column":4},"end":{"line":398,"column":null}},"29":{"start":{"line":412,"column":20},"end":{"line":412,"column":null}},"30":{"start":{"line":414,"column":4},"end":{"line":421,"column":null}},"31":{"start":{"line":415,"column":6},"end":{"line":420,"column":null}},"32":{"start":{"line":416,"column":23},"end":{"line":416,"column":null}},"33":{"start":{"line":417,"column":8},"end":{"line":417,"column":null}},"34":{"start":{"line":419,"column":8},"end":{"line":419,"column":null}},"35":{"start":{"line":423,"column":4},"end":{"line":423,"column":null}},"36":{"start":{"line":431,"column":23},"end":{"line":431,"column":null}},"37":{"start":{"line":432,"column":22},"end":{"line":432,"column":null}},"38":{"start":{"line":432,"column":39},"end":{"line":432,"column":59}},"39":{"start":{"line":434,"column":4},"end":{"line":454,"column":null}},"40":{"start":{"line":435,"column":23},"end":{"line":438,"column":null}},"41":{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},"42":{"start":{"line":441,"column":8},"end":{"line":441,"column":null}},"43":{"start":{"line":444,"column":6},"end":{"line":444,"column":null}},"44":{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},"45":{"start":{"line":447,"column":22},"end":{"line":447,"column":null}},"46":{"start":{"line":448,"column":8},"end":{"line":448,"column":null}},"47":{"start":{"line":448,"column":39},"end":{"line":448,"column":65}},"48":{"start":{"line":449,"column":8},"end":{"line":449,"column":null}},"49":{"start":{"line":451,"column":6},"end":{"line":451,"column":null}},"50":{"start":{"line":453,"column":6},"end":{"line":453,"column":null}},"51":{"start":{"line":462,"column":53},"end":{"line":462,"column":null}},"52":{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},"53":{"start":{"line":467,"column":4},"end":{"line":467,"column":null}},"54":{"start":{"line":469,"column":2},"end":{"line":469,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":338,"column":2},"end":{"line":338,"column":14}},"loc":{"start":{"line":338,"column":50},"end":{"line":342,"column":null}},"line":338},"1":{"name":"(anonymous_1)","decl":{"start":{"line":352,"column":8},"end":{"line":352,"column":null}},"loc":{"start":{"line":356,"column":35},"end":{"line":384,"column":null}},"line":356},"2":{"name":"(anonymous_2)","decl":{"start":{"line":367,"column":7},"end":{"line":367,"column":15}},"loc":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"line":367},"3":{"name":"(anonymous_3)","decl":{"start":{"line":368,"column":7},"end":{"line":368,"column":12}},"loc":{"start":{"line":368,"column":22},"end":{"line":375,"column":8}},"line":368},"4":{"name":"(anonymous_4)","decl":{"start":{"line":376,"column":7},"end":{"line":376,"column":13}},"loc":{"start":{"line":376,"column":22},"end":{"line":383,"column":7}},"line":376},"5":{"name":"(anonymous_5)","decl":{"start":{"line":393,"column":8},"end":{"line":393,"column":null}},"loc":{"start":{"line":396,"column":40},"end":{"line":399,"column":null}},"line":396},"6":{"name":"(anonymous_6)","decl":{"start":{"line":408,"column":8},"end":{"line":408,"column":null}},"loc":{"start":{"line":411,"column":53},"end":{"line":424,"column":null}},"line":411},"7":{"name":"(anonymous_7)","decl":{"start":{"line":430,"column":16},"end":{"line":430,"column":31}},"loc":{"start":{"line":430,"column":75},"end":{"line":455,"column":null}},"line":430},"8":{"name":"(anonymous_8)","decl":{"start":{"line":432,"column":22},"end":{"line":432,"column":39}},"loc":{"start":{"line":432,"column":39},"end":{"line":432,"column":59}},"line":432},"9":{"name":"(anonymous_9)","decl":{"start":{"line":448,"column":18},"end":{"line":448,"column":27}},"loc":{"start":{"line":448,"column":39},"end":{"line":448,"column":65}},"line":448},"10":{"name":"getDefaultWorldBankClient","decl":{"start":{"line":465,"column":16},"end":{"line":465,"column":61}},"loc":{"start":{"line":465,"column":61},"end":{"line":470,"column":null}},"line":465}},"branchMap":{"0":{"loc":{"start":{"line":338,"column":14},"end":{"line":338,"column":50}},"type":"default-arg","locations":[{"start":{"line":338,"column":46},"end":{"line":338,"column":50}}],"line":338},"1":{"loc":{"start":{"line":339,"column":19},"end":{"line":339,"column":null}},"type":"binary-expr","locations":[{"start":{"line":339,"column":19},"end":{"line":339,"column":37}},{"start":{"line":339,"column":37},"end":{"line":339,"column":null}}],"line":339},"2":{"loc":{"start":{"line":340,"column":19},"end":{"line":340,"column":null}},"type":"binary-expr","locations":[{"start":{"line":340,"column":19},"end":{"line":340,"column":37}},{"start":{"line":340,"column":37},"end":{"line":340,"column":null}}],"line":340},"3":{"loc":{"start":{"line":341,"column":22},"end":{"line":341,"column":null}},"type":"binary-expr","locations":[{"start":{"line":341,"column":22},"end":{"line":341,"column":43}},{"start":{"line":341,"column":43},"end":{"line":341,"column":null}}],"line":341},"4":{"loc":{"start":{"line":355,"column":4},"end":{"line":355,"column":null}},"type":"default-arg","locations":[{"start":{"line":355,"column":14},"end":{"line":355,"column":null}}],"line":355},"5":{"loc":{"start":{"line":357,"column":24},"end":{"line":357,"column":null}},"type":"cond-expr","locations":[{"start":{"line":357,"column":61},"end":{"line":357,"column":91}},{"start":{"line":357,"column":91},"end":{"line":357,"column":null}}],"line":357},"6":{"loc":{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},"type":"if","locations":[{"start":{"line":362,"column":4},"end":{"line":364,"column":null}},{"start":{},"end":{}}],"line":362},"7":{"loc":{"start":{"line":362,"column":8},"end":{"line":362,"column":76}},"type":"binary-expr","locations":[{"start":{"line":362,"column":8},"end":{"line":362,"column":32}},{"start":{"line":362,"column":32},"end":{"line":362,"column":51}},{"start":{"line":362,"column":51},"end":{"line":362,"column":76}}],"line":362},"8":{"loc":{"start":{"line":367,"column":71},"end":{"line":367,"column":118}},"type":"binary-expr","locations":[{"start":{"line":367,"column":71},"end":{"line":367,"column":94}},{"start":{"line":367,"column":94},"end":{"line":367,"column":118}}],"line":367},"9":{"loc":{"start":{"line":369,"column":19},"end":{"line":369,"column":null}},"type":"binary-expr","locations":[{"start":{"line":369,"column":19},"end":{"line":369,"column":39}},{"start":{"line":369,"column":39},"end":{"line":369,"column":null}}],"line":369},"10":{"loc":{"start":{"line":370,"column":21},"end":{"line":370,"column":null}},"type":"binary-expr","locations":[{"start":{"line":370,"column":21},"end":{"line":370,"column":44}},{"start":{"line":370,"column":44},"end":{"line":370,"column":null}}],"line":370},"11":{"loc":{"start":{"line":371,"column":21},"end":{"line":371,"column":null}},"type":"binary-expr","locations":[{"start":{"line":371,"column":21},"end":{"line":371,"column":43}},{"start":{"line":371,"column":43},"end":{"line":371,"column":null}}],"line":371},"12":{"loc":{"start":{"line":372,"column":23},"end":{"line":372,"column":null}},"type":"binary-expr","locations":[{"start":{"line":372,"column":23},"end":{"line":372,"column":48}},{"start":{"line":372,"column":48},"end":{"line":372,"column":null}}],"line":372},"13":{"loc":{"start":{"line":373,"column":14},"end":{"line":373,"column":null}},"type":"binary-expr","locations":[{"start":{"line":373,"column":14},"end":{"line":373,"column":27}},{"start":{"line":373,"column":27},"end":{"line":373,"column":null}}],"line":373},"14":{"loc":{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},"type":"if","locations":[{"start":{"line":379,"column":8},"end":{"line":379,"column":null}},{"start":{},"end":{}}],"line":379},"15":{"loc":{"start":{"line":379,"column":12},"end":{"line":379,"column":42}},"type":"binary-expr","locations":[{"start":{"line":379,"column":12},"end":{"line":379,"column":28}},{"start":{"line":379,"column":28},"end":{"line":379,"column":42}}],"line":379},"16":{"loc":{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},"type":"if","locations":[{"start":{"line":380,"column":8},"end":{"line":380,"column":null}},{"start":{},"end":{}}],"line":380},"17":{"loc":{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},"type":"if","locations":[{"start":{"line":381,"column":8},"end":{"line":381,"column":null}},{"start":{},"end":{}}],"line":381},"18":{"loc":{"start":{"line":398,"column":11},"end":{"line":398,"column":null}},"type":"cond-expr","locations":[{"start":{"line":398,"column":32},"end":{"line":398,"column":45}},{"start":{"line":398,"column":45},"end":{"line":398,"column":null}}],"line":398},"19":{"loc":{"start":{"line":430,"column":44},"end":{"line":430,"column":75}},"type":"default-arg","locations":[{"start":{"line":430,"column":54},"end":{"line":430,"column":75}}],"line":430},"20":{"loc":{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},"type":"if","locations":[{"start":{"line":440,"column":6},"end":{"line":442,"column":null}},{"start":{},"end":{}}],"line":440},"21":{"loc":{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},"type":"if","locations":[{"start":{"line":446,"column":6},"end":{"line":450,"column":null}},{"start":{},"end":{}}],"line":446},"22":{"loc":{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},"type":"if","locations":[{"start":{"line":466,"column":2},"end":{"line":468,"column":null}},{"start":{},"end":{}}],"line":466}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":57,"8":57,"9":57,"10":96,"11":96,"12":96,"13":93,"14":81,"15":12,"16":12,"17":11,"18":4,"19":4,"20":4,"21":0,"22":4,"23":0,"24":4,"25":0,"26":4,"27":6,"28":5,"29":2,"30":2,"31":4,"32":4,"33":3,"34":1,"35":2,"36":97,"37":97,"38":0,"39":97,"40":97,"41":94,"42":1,"43":93,"44":4,"45":1,"46":1,"47":1,"48":1,"49":3,"50":97,"51":3,"52":3,"53":1,"54":3},"f":{"0":57,"1":96,"2":12,"3":11,"4":4,"5":6,"6":2,"7":97,"8":0,"9":1,"10":3},"b":{"0":[57],"1":[57,56],"2":[57,55],"3":[57,53],"4":[96],"5":[7,89],"6":[81,12],"7":[93,13,12],"8":[12,11],"9":[11,0],"10":[11,1],"11":[11,0],"12":[11,1],"13":[11,0],"14":[0,4],"15":[4,0],"16":[0,4],"17":[0,4],"18":[4,1],"19":[97],"20":[1,93],"21":[1,3],"22":[1,2]},"meta":{"lastBranch":23,"lastFunction":11,"lastStatement":55,"seen":{"s:57:25:57:Infinity":0,"s:58:24:58:Infinity":1,"s:59:28:59:Infinity":2,"s:66:26:71:Infinity":3,"s:74:33:76:Infinity":4,"s:79:29:86:Infinity":5,"s:120:29:323:Infinity":6,"f:338:2:338:14":0,"b:338:46:338:50":0,"s:339:4:339:Infinity":7,"b:339:19:339:37:339:37:339:Infinity":1,"s:340:4:340:Infinity":8,"b:340:19:340:37:340:37:340:Infinity":2,"s:341:4:341:Infinity":9,"b:341:22:341:43:341:43:341:Infinity":3,"f:352:8:352:Infinity":1,"b:355:14:355:Infinity":4,"s:357:24:357:Infinity":10,"b:357:61:357:91:357:91:357:Infinity":5,"s:358:16:358:Infinity":11,"s:360:17:360:Infinity":12,"b:362:4:364:Infinity:undefined:undefined:undefined:undefined":6,"s:362:4:364:Infinity":13,"b:362:8:362:32:362:32:362:51:362:51:362:76":7,"s:363:6:363:Infinity":14,"s:366:4:383:Infinity":15,"f:367:7:367:15":2,"s:367:71:367:118":16,"b:367:71:367:94:367:94:367:118":8,"f:368:7:368:12":3,"s:368:22:375:8":17,"b:369:19:369:39:369:39:369:Infinity":9,"b:370:21:370:44:370:44:370:Infinity":10,"b:371:21:371:43:371:43:371:Infinity":11,"b:372:23:372:48:372:48:372:Infinity":12,"b:373:14:373:27:373:27:373:Infinity":13,"f:376:7:376:13":4,"s:377:22:377:Infinity":18,"s:378:22:378:Infinity":19,"b:379:8:379:Infinity:undefined:undefined:undefined:undefined":14,"s:379:8:379:Infinity":20,"b:379:12:379:28:379:28:379:42":15,"s:379:42:379:Infinity":21,"b:380:8:380:Infinity:undefined:undefined:undefined:undefined":16,"s:380:8:380:Infinity":22,"s:380:26:380:Infinity":23,"b:381:8:381:Infinity:undefined:undefined:undefined:undefined":17,"s:381:8:381:Infinity":24,"s:381:26:381:Infinity":25,"s:382:8:382:Infinity":26,"f:393:8:393:Infinity":5,"s:397:20:397:Infinity":27,"s:398:4:398:Infinity":28,"b:398:32:398:45:398:45:398:Infinity":18,"f:408:8:408:Infinity":6,"s:412:20:412:Infinity":29,"s:414:4:421:Infinity":30,"s:415:6:420:Infinity":31,"s:416:23:416:Infinity":32,"s:417:8:417:Infinity":33,"s:419:8:419:Infinity":34,"s:423:4:423:Infinity":35,"f:430:16:430:31":7,"b:430:54:430:75":19,"s:431:23:431:Infinity":36,"s:432:22:432:Infinity":37,"f:432:22:432:39":8,"s:432:39:432:59":38,"s:434:4:454:Infinity":39,"s:435:23:438:Infinity":40,"b:440:6:442:Infinity:undefined:undefined:undefined:undefined":20,"s:440:6:442:Infinity":41,"s:441:8:441:Infinity":42,"s:444:6:444:Infinity":43,"b:446:6:450:Infinity:undefined:undefined:undefined:undefined":21,"s:446:6:450:Infinity":44,"s:447:22:447:Infinity":45,"s:448:8:448:Infinity":46,"f:448:18:448:27":9,"s:448:39:448:65":47,"s:449:8:449:Infinity":48,"s:451:6:451:Infinity":49,"s:453:6:453:Infinity":50,"s:462:53:462:Infinity":51,"f:465:16:465:61":10,"b:466:2:468:Infinity:undefined:undefined:undefined:undefined":22,"s:466:2:468:Infinity":52,"s:467:4:467:Infinity":53,"s:469:2:469:Infinity":54}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-context.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/scripts/world-bank-context.ts","statementMap":{"0":{"start":{"line":113,"column":2},"end":{"line":118,"column":null}},"1":{"start":{"line":114,"column":20},"end":{"line":114,"column":null}},"2":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"3":{"start":{"line":117,"column":4},"end":{"line":117,"column":null}},"4":{"start":{"line":130,"column":2},"end":{"line":160,"column":null}},"5":{"start":{"line":131,"column":16},"end":{"line":131,"column":null}},"6":{"start":{"line":132,"column":42},"end":{"line":132,"column":null}},"7":{"start":{"line":134,"column":52},"end":{"line":134,"column":null}},"8":{"start":{"line":135,"column":4},"end":{"line":146,"column":null}},"9":{"start":{"line":136,"column":6},"end":{"line":145,"column":null}},"10":{"start":{"line":137,"column":8},"end":{"line":144,"column":null}},"11":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"12":{"start":{"line":150,"column":6},"end":{"line":152,"column":null}},"13":{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},"14":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"15":{"start":{"line":158,"column":4},"end":{"line":158,"column":null}},"16":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"17":{"start":{"line":185,"column":2},"end":{"line":185,"column":null}},"18":{"start":{"line":192,"column":54},"end":{"line":207,"column":null}},"19":{"start":{"line":217,"column":94},"end":{"line":316,"column":null}},"20":{"start":{"line":333,"column":19},"end":{"line":333,"column":null}},"21":{"start":{"line":334,"column":2},"end":{"line":334,"column":null}},"22":{"start":{"line":346,"column":12},"end":{"line":346,"column":null}},"23":{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},"24":{"start":{"line":348,"column":4},"end":{"line":348,"column":null}},"25":{"start":{"line":350,"column":2},"end":{"line":354,"column":null}},"26":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"27":{"start":{"line":352,"column":43},"end":{"line":352,"column":73}},"28":{"start":{"line":353,"column":39},"end":{"line":353,"column":60}},"29":{"start":{"line":366,"column":2},"end":{"line":370,"column":null}},"30":{"start":{"line":366,"column":51},"end":{"line":370,"column":4}},"31":{"start":{"line":386,"column":15},"end":{"line":386,"column":null}},"32":{"start":{"line":387,"column":38},"end":{"line":416,"column":null}},"33":{"start":{"line":418,"column":2},"end":{"line":418,"column":null}},"34":{"start":{"line":418,"column":36},"end":{"line":418,"column":54}}},"fnMap":{"0":{"name":"resolveInventoryPath","decl":{"start":{"line":112,"column":9},"end":{"line":112,"column":40}},"loc":{"start":{"line":112,"column":40},"end":{"line":119,"column":null}},"line":112},"1":{"name":"loadIndicatorsFromInventory","decl":{"start":{"line":129,"column":9},"end":{"line":129,"column":77}},"loc":{"start":{"line":129,"column":77},"end":{"line":161,"column":null}},"line":129},"2":{"name":"getEconomicHeading","decl":{"start":{"line":329,"column":16},"end":{"line":329,"column":null}},"loc":{"start":{"line":332,"column":10},"end":{"line":335,"column":null}},"line":332},"3":{"name":"findRelevantIndicators","decl":{"start":{"line":345,"column":16},"end":{"line":345,"column":39}},"loc":{"start":{"line":345,"column":92},"end":{"line":355,"column":null}},"line":345},"4":{"name":"(anonymous_4)","decl":{"start":{"line":350,"column":31},"end":{"line":350,"column":null}},"loc":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"line":352},"5":{"name":"(anonymous_5)","decl":{"start":{"line":352,"column":28},"end":{"line":352,"column":34}},"loc":{"start":{"line":352,"column":43},"end":{"line":352,"column":73}},"line":352},"6":{"name":"(anonymous_6)","decl":{"start":{"line":353,"column":27},"end":{"line":353,"column":33}},"loc":{"start":{"line":353,"column":39},"end":{"line":353,"column":60}},"line":353},"7":{"name":"getSwedishIndicatorQueries","decl":{"start":{"line":365,"column":16},"end":{"line":365,"column":116}},"loc":{"start":{"line":365,"column":116},"end":{"line":371,"column":null}},"line":365},"8":{"name":"(anonymous_8)","decl":{"start":{"line":366,"column":31},"end":{"line":366,"column":36}},"loc":{"start":{"line":366,"column":51},"end":{"line":370,"column":4}},"line":366},"9":{"name":"hasEconomicContext","decl":{"start":{"line":385,"column":16},"end":{"line":385,"column":35}},"loc":{"start":{"line":385,"column":61},"end":{"line":419,"column":null}},"line":385},"10":{"name":"(anonymous_10)","decl":{"start":{"line":418,"column":18},"end":{"line":418,"column":24}},"loc":{"start":{"line":418,"column":36},"end":{"line":418,"column":54}},"line":418}},"branchMap":{"0":{"loc":{"start":{"line":140,"column":23},"end":{"line":140,"column":null}},"type":"binary-expr","locations":[{"start":{"line":140,"column":23},"end":{"line":140,"column":42}},{"start":{"line":140,"column":42},"end":{"line":140,"column":null}}],"line":140},"1":{"loc":{"start":{"line":141,"column":23},"end":{"line":141,"column":null}},"type":"binary-expr","locations":[{"start":{"line":141,"column":23},"end":{"line":141,"column":42}},{"start":{"line":141,"column":42},"end":{"line":141,"column":null}}],"line":141},"2":{"loc":{"start":{"line":142,"column":22},"end":{"line":142,"column":null}},"type":"binary-expr","locations":[{"start":{"line":142,"column":22},"end":{"line":142,"column":40}},{"start":{"line":142,"column":40},"end":{"line":142,"column":null}}],"line":142},"3":{"loc":{"start":{"line":150,"column":6},"end":{"line":152,"column":null}},"type":"cond-expr","locations":[{"start":{"line":151,"column":10},"end":{"line":151,"column":null}},{"start":{"line":152,"column":10},"end":{"line":152,"column":null}}],"line":150},"4":{"loc":{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":4},"end":{"line":156,"column":null}},{"start":{},"end":{}}],"line":154},"5":{"loc":{"start":{"line":333,"column":19},"end":{"line":333,"column":null}},"type":"binary-expr","locations":[{"start":{"line":333,"column":19},"end":{"line":333,"column":66}},{"start":{"line":333,"column":66},"end":{"line":333,"column":null}}],"line":333},"6":{"loc":{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},"type":"if","locations":[{"start":{"line":347,"column":2},"end":{"line":349,"column":null}},{"start":{},"end":{}}],"line":347},"7":{"loc":{"start":{"line":352,"column":6},"end":{"line":353,"column":null}},"type":"binary-expr","locations":[{"start":{"line":352,"column":6},"end":{"line":352,"column":null}},{"start":{"line":353,"column":6},"end":{"line":353,"column":null}}],"line":352}},"s":{"0":1,"1":1,"2":1,"3":0,"4":1,"5":1,"6":1,"7":1,"8":1,"9":11,"10":79,"11":1,"12":0,"13":0,"14":0,"15":0,"16":0,"17":1,"18":1,"19":1,"20":91,"21":91,"22":185,"23":185,"24":2,"25":183,"26":14457,"27":35648,"28":19290,"29":22,"30":1738,"31":28,"32":28,"33":28,"34":437},"f":{"0":1,"1":1,"2":91,"3":185,"4":14457,"5":35648,"6":19290,"7":22,"8":1738,"9":28,"10":437},"b":{"0":[79,0],"1":[79,0],"2":[79,52],"3":[0,0],"4":[0,0],"5":[91,2],"6":[2,183],"7":[14457,14339]},"meta":{"lastBranch":8,"lastFunction":11,"lastStatement":35,"seen":{"f:112:9:112:40":0,"s:113:2:118:Infinity":0,"s:114:20:114:Infinity":1,"s:115:4:115:Infinity":2,"s:117:4:117:Infinity":3,"f:129:9:129:77":1,"s:130:2:160:Infinity":4,"s:131:16:131:Infinity":5,"s:132:42:132:Infinity":6,"s:134:52:134:Infinity":7,"s:135:4:146:Infinity":8,"s:136:6:145:Infinity":9,"s:137:8:144:Infinity":10,"b:140:23:140:42:140:42:140:Infinity":0,"b:141:23:141:42:141:42:141:Infinity":1,"b:142:22:142:40:142:40:142:Infinity":2,"s:147:4:147:Infinity":11,"s:150:6:152:Infinity":12,"b:151:10:151:Infinity:152:10:152:Infinity":3,"b:154:4:156:Infinity:undefined:undefined:undefined:undefined":4,"s:154:4:156:Infinity":13,"s:155:6:155:Infinity":14,"s:158:4:158:Infinity":15,"s:159:4:159:Infinity":16,"s:185:2:185:Infinity":17,"s:192:54:207:Infinity":18,"s:217:94:316:Infinity":19,"f:329:16:329:Infinity":2,"s:333:19:333:Infinity":20,"b:333:19:333:66:333:66:333:Infinity":5,"s:334:2:334:Infinity":21,"f:345:16:345:39":3,"s:346:12:346:Infinity":22,"b:347:2:349:Infinity:undefined:undefined:undefined:undefined":6,"s:347:2:349:Infinity":23,"s:348:4:348:Infinity":24,"s:350:2:354:Infinity":25,"f:350:31:350:Infinity":4,"s:352:6:353:Infinity":26,"b:352:6:352:Infinity:353:6:353:Infinity":7,"f:352:28:352:34":5,"s:352:43:352:73":27,"f:353:27:353:33":6,"s:353:39:353:60":28,"f:365:16:365:116":7,"s:366:2:370:Infinity":29,"f:366:31:366:36":8,"s:366:51:370:4":30,"f:385:16:385:35":9,"s:386:15:386:Infinity":31,"s:387:38:416:Infinity":32,"s:418:2:418:Infinity":33,"f:418:18:418:24":10,"s:418:36:418:54":34}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-contracts.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-contracts.ts","statementMap":{"0":{"start":{"line":38,"column":53},"end":{"line":479,"column":null}},"1":{"start":{"line":487,"column":2},"end":{"line":487,"column":null}},"2":{"start":{"line":487,"column":35},"end":{"line":487,"column":50}},"3":{"start":{"line":495,"column":45},"end":{"line":495,"column":null}},"4":{"start":{"line":496,"column":2},"end":{"line":499,"column":null}},"5":{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},"6":{"start":{"line":497,"column":27},"end":{"line":497,"column":null}},"7":{"start":{"line":498,"column":4},"end":{"line":498,"column":null}},"8":{"start":{"line":500,"column":2},"end":{"line":500,"column":null}}},"fnMap":{"0":{"name":"getCsvContract","decl":{"start":{"line":486,"column":16},"end":{"line":486,"column":31}},"loc":{"start":{"line":486,"column":65},"end":{"line":488,"column":null}},"line":486},"1":{"name":"(anonymous_1)","decl":{"start":{"line":487,"column":23},"end":{"line":487,"column":29}},"loc":{"start":{"line":487,"column":35},"end":{"line":487,"column":50}},"line":487},"2":{"name":"contractsByDashboard","decl":{"start":{"line":494,"column":16},"end":{"line":494,"column":79}},"loc":{"start":{"line":494,"column":79},"end":{"line":501,"column":null}},"line":494}},"branchMap":{"0":{"loc":{"start":{"line":487,"column":9},"end":{"line":487,"column":null}},"type":"binary-expr","locations":[{"start":{"line":487,"column":9},"end":{"line":487,"column":55}},{"start":{"line":487,"column":55},"end":{"line":487,"column":null}}],"line":487},"1":{"loc":{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},"type":"if","locations":[{"start":{"line":497,"column":4},"end":{"line":497,"column":null}},{"start":{},"end":{}}],"line":497}},"s":{"0":2,"1":4,"2":60,"3":1,"4":1,"5":29,"6":10,"7":29,"8":1},"f":{"0":4,"1":60,"2":1},"b":{"0":[4,2],"1":[10,19]},"meta":{"lastBranch":2,"lastFunction":3,"lastStatement":9,"seen":{"s:38:53:479:Infinity":0,"f:486:16:486:31":0,"s:487:2:487:Infinity":1,"b:487:9:487:55:487:55:487:Infinity":0,"f:487:23:487:29":1,"s:487:35:487:50":2,"f:494:16:494:79":2,"s:495:45:495:Infinity":3,"s:496:2:499:Infinity":4,"b:497:4:497:Infinity:undefined:undefined:undefined:undefined":1,"s:497:4:497:Infinity":5,"s:497:27:497:Infinity":6,"s:498:4:498:Infinity":7,"s:500:2:500:Infinity":8}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-utils.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-utils.ts","statementMap":{"0":{"start":{"line":38,"column":18},"end":{"line":38,"column":null}},"1":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"2":{"start":{"line":39,"column":43},"end":{"line":39,"column":null}},"3":{"start":{"line":41,"column":17},"end":{"line":46,"column":null}},"4":{"start":{"line":45,"column":31},"end":{"line":45,"column":null}},"5":{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},"6":{"start":{"line":49,"column":25},"end":{"line":51,"column":null}},"7":{"start":{"line":50,"column":20},"end":{"line":50,"column":86}},"8":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"9":{"start":{"line":55,"column":2},"end":{"line":57,"column":null}},"10":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"11":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"12":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"13":{"start":{"line":74,"column":13},"end":{"line":74,"column":null}},"14":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"15":{"start":{"line":75,"column":13},"end":{"line":75,"column":null}},"16":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"17":{"start":{"line":77,"column":22},"end":{"line":77,"column":null}},"18":{"start":{"line":78,"column":2},"end":{"line":78,"column":null}},"19":{"start":{"line":105,"column":25},"end":{"line":105,"column":null}},"20":{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},"21":{"start":{"line":107,"column":4},"end":{"line":107,"column":null}},"22":{"start":{"line":110,"column":2},"end":{"line":121,"column":null}},"23":{"start":{"line":111,"column":4},"end":{"line":120,"column":null}},"24":{"start":{"line":112,"column":23},"end":{"line":112,"column":null}},"25":{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},"26":{"start":{"line":113,"column":24},"end":{"line":113,"column":null}},"27":{"start":{"line":114,"column":19},"end":{"line":114,"column":null}},"28":{"start":{"line":115,"column":19},"end":{"line":115,"column":null}},"29":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"30":{"start":{"line":116,"column":27},"end":{"line":116,"column":null}},"31":{"start":{"line":118,"column":22},"end":{"line":118,"column":null}},"32":{"start":{"line":119,"column":6},"end":{"line":119,"column":null}},"33":{"start":{"line":123,"column":2},"end":{"line":123,"column":null}},"34":{"start":{"line":124,"column":2},"end":{"line":124,"column":null}},"35":{"start":{"line":138,"column":2},"end":{"line":139,"column":null}},"36":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}}},"fnMap":{"0":{"name":"parseCSV","decl":{"start":{"line":37,"column":16},"end":{"line":37,"column":25}},"loc":{"start":{"line":37,"column":52},"end":{"line":58,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":4},"end":{"line":45,"column":21}},"loc":{"start":{"line":45,"column":31},"end":{"line":45,"column":null}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":50,"column":7},"end":{"line":50,"column":11}},"loc":{"start":{"line":50,"column":20},"end":{"line":50,"column":86}},"line":50},"3":{"name":"(anonymous_3)","decl":{"start":{"line":55,"column":21},"end":{"line":55,"column":28}},"loc":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"line":56},"4":{"name":"(anonymous_4)","decl":{"start":{"line":56,"column":23},"end":{"line":56,"column":28}},"loc":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"line":56},"5":{"name":"joinURL","decl":{"start":{"line":73,"column":16},"end":{"line":73,"column":24}},"loc":{"start":{"line":73,"column":60},"end":{"line":79,"column":null}},"line":73},"6":{"name":"loadCSV","decl":{"start":{"line":99,"column":22},"end":{"line":99,"column":null}},"loc":{"start":{"line":104,"column":21},"end":{"line":125,"column":null}},"line":104},"7":{"name":"createLoadCSV","decl":{"start":{"line":137,"column":16},"end":{"line":137,"column":30}},"loc":{"start":{"line":137,"column":77},"end":{"line":140,"column":null}},"line":137},"8":{"name":"(anonymous_8)","decl":{"start":{"line":138,"column":2},"end":{"line":138,"column":10}},"loc":{"start":{"line":139,"column":4},"end":{"line":139,"column":null}},"line":139}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":39},"1":{"loc":{"start":{"line":39,"column":6},"end":{"line":39,"column":43}},"type":"binary-expr","locations":[{"start":{"line":39,"column":6},"end":{"line":39,"column":18}},{"start":{"line":39,"column":18},"end":{"line":39,"column":43}}],"line":39},"2":{"loc":{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":50,"column":44},"end":{"line":50,"column":67}},"type":"binary-expr","locations":[{"start":{"line":50,"column":44},"end":{"line":50,"column":57}},{"start":{"line":50,"column":57},"end":{"line":50,"column":67}}],"line":50},"4":{"loc":{"start":{"line":56,"column":37},"end":{"line":56,"column":90}},"type":"binary-expr","locations":[{"start":{"line":56,"column":37},"end":{"line":56,"column":55}},{"start":{"line":56,"column":55},"end":{"line":56,"column":78}},{"start":{"line":56,"column":78},"end":{"line":56,"column":90}}],"line":56},"5":{"loc":{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},"type":"if","locations":[{"start":{"line":74,"column":2},"end":{"line":74,"column":null}},{"start":{},"end":{}}],"line":74},"6":{"loc":{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":75,"column":2},"end":{"line":75,"column":null}},{"start":{},"end":{}}],"line":75},"7":{"loc":{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},"type":"if","locations":[{"start":{"line":106,"column":2},"end":{"line":108,"column":null}},{"start":{},"end":{}}],"line":106},"8":{"loc":{"start":{"line":107,"column":35},"end":{"line":107,"column":60}},"type":"binary-expr","locations":[{"start":{"line":107,"column":35},"end":{"line":107,"column":51}},{"start":{"line":107,"column":51},"end":{"line":107,"column":60}}],"line":107},"9":{"loc":{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":113,"column":6},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":113},"10":{"loc":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"type":"if","locations":[{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},{"start":{},"end":{}}],"line":116},"11":{"loc":{"start":{"line":118,"column":22},"end":{"line":118,"column":null}},"type":"cond-expr","locations":[{"start":{"line":118,"column":43},"end":{"line":118,"column":55}},{"start":{"line":118,"column":55},"end":{"line":118,"column":null}}],"line":118},"12":{"loc":{"start":{"line":137,"column":50},"end":{"line":137,"column":77}},"type":"default-arg","locations":[{"start":{"line":137,"column":64},"end":{"line":137,"column":77}}],"line":137}},"s":{"0":60,"1":60,"2":1,"3":59,"4":279,"5":59,"6":1,"7":1,"8":1,"9":58,"10":167,"11":167,"12":85,"13":1,"14":84,"15":1,"16":83,"17":83,"18":83,"19":38,"20":38,"21":37,"22":38,"23":43,"24":43,"25":42,"26":8,"27":34,"28":34,"29":34,"30":34,"31":1,"32":1,"33":4,"34":4,"35":22,"36":36},"f":{"0":60,"1":279,"2":1,"3":167,"4":167,"5":85,"6":38,"7":22,"8":36},"b":{"0":[1,59],"1":[60,60],"2":[1,58],"3":[1,0],"4":[167,167,167],"5":[1,84],"6":[1,83],"7":[37,1],"8":[37,37],"9":[8,34],"10":[34,0],"11":[1,0],"12":[22]},"meta":{"lastBranch":13,"lastFunction":9,"lastStatement":37,"seen":{"f:37:16:37:25":0,"s:38:18:38:Infinity":0,"b:39:2:39:Infinity:undefined:undefined:undefined:undefined":0,"s:39:2:39:Infinity":1,"b:39:6:39:18:39:18:39:43":1,"s:39:43:39:Infinity":2,"s:41:17:46:Infinity":3,"f:45:4:45:21":1,"s:45:31:45:Infinity":4,"b:48:2:53:Infinity:undefined:undefined:undefined:undefined":2,"s:48:2:53:Infinity":5,"s:49:25:51:Infinity":6,"f:50:7:50:11":2,"s:50:20:50:86":7,"b:50:44:50:57:50:57:50:67":3,"s:52:4:52:Infinity":8,"s:55:2:57:Infinity":9,"f:55:21:55:28":3,"s:56:4:56:Infinity":10,"f:56:23:56:28":4,"s:56:37:56:90":11,"b:56:37:56:55:56:55:56:78:56:78:56:90":4,"f:73:16:73:24":5,"b:74:2:74:Infinity:undefined:undefined:undefined:undefined":5,"s:74:2:74:Infinity":12,"s:74:13:74:Infinity":13,"b:75:2:75:Infinity:undefined:undefined:undefined:undefined":6,"s:75:2:75:Infinity":14,"s:75:13:75:Infinity":15,"s:76:22:76:Infinity":16,"s:77:22:77:Infinity":17,"s:78:2:78:Infinity":18,"f:99:22:99:Infinity":6,"s:105:25:105:Infinity":19,"b:106:2:108:Infinity:undefined:undefined:undefined:undefined":7,"s:106:2:108:Infinity":20,"s:107:4:107:Infinity":21,"b:107:35:107:51:107:51:107:60":8,"s:110:2:121:Infinity":22,"s:111:4:120:Infinity":23,"s:112:23:112:Infinity":24,"b:113:6:113:Infinity:undefined:undefined:undefined:undefined":9,"s:113:6:113:Infinity":25,"s:113:24:113:Infinity":26,"s:114:19:114:Infinity":27,"s:115:19:115:Infinity":28,"b:116:6:116:Infinity:undefined:undefined:undefined:undefined":10,"s:116:6:116:Infinity":29,"s:116:27:116:Infinity":30,"s:118:22:118:Infinity":31,"b:118:43:118:55:118:55:118:Infinity":11,"s:119:6:119:Infinity":32,"s:123:2:123:Infinity":33,"s:124:2:124:Infinity":34,"f:137:16:137:30":7,"b:137:64:137:77":12,"s:138:2:139:Infinity":35,"f:138:2:138:10":8,"s:139:4:139:Infinity":36}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/data-loader.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/data-loader.ts","statementMap":{"0":{"start":{"line":96,"column":55},"end":{"line":96,"column":null}},"1":{"start":{"line":99,"column":74},"end":{"line":99,"column":null}},"2":{"start":{"line":105,"column":56},"end":{"line":105,"column":null}},"3":{"start":{"line":108,"column":56},"end":{"line":108,"column":null}},"4":{"start":{"line":114,"column":4},"end":{"line":114,"column":null}},"5":{"start":{"line":115,"column":4},"end":{"line":115,"column":null}},"6":{"start":{"line":116,"column":4},"end":{"line":116,"column":null}},"7":{"start":{"line":125,"column":4},"end":{"line":125,"column":null}},"8":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"9":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"10":{"start":{"line":145,"column":4},"end":{"line":145,"column":null}},"11":{"start":{"line":150,"column":4},"end":{"line":150,"column":null}},"12":{"start":{"line":155,"column":4},"end":{"line":155,"column":null}},"13":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"14":{"start":{"line":169,"column":4},"end":{"line":169,"column":null}},"15":{"start":{"line":174,"column":4},"end":{"line":174,"column":null}},"16":{"start":{"line":179,"column":4},"end":{"line":179,"column":null}},"17":{"start":{"line":184,"column":4},"end":{"line":184,"column":null}},"18":{"start":{"line":189,"column":4},"end":{"line":189,"column":null}},"19":{"start":{"line":198,"column":6},"end":{"line":209,"column":null}},"20":{"start":{"line":211,"column":4},"end":{"line":222,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":113,"column":2},"end":{"line":113,"column":16}},"loc":{"start":{"line":113,"column":16},"end":{"line":117,"column":null}},"line":113},"1":{"name":"(anonymous_1)","decl":{"start":{"line":124,"column":2},"end":{"line":124,"column":11}},"loc":{"start":{"line":124,"column":38},"end":{"line":126,"column":null}},"line":124},"2":{"name":"(anonymous_2)","decl":{"start":{"line":134,"column":8},"end":{"line":134,"column":16}},"loc":{"start":{"line":134,"column":77},"end":{"line":136,"column":null}},"line":134},"3":{"name":"(anonymous_3)","decl":{"start":{"line":139,"column":8},"end":{"line":139,"column":60}},"loc":{"start":{"line":139,"column":60},"end":{"line":141,"column":null}},"line":139},"4":{"name":"(anonymous_4)","decl":{"start":{"line":144,"column":8},"end":{"line":144,"column":58}},"loc":{"start":{"line":144,"column":58},"end":{"line":146,"column":null}},"line":144},"5":{"name":"(anonymous_5)","decl":{"start":{"line":149,"column":8},"end":{"line":149,"column":58}},"loc":{"start":{"line":149,"column":58},"end":{"line":151,"column":null}},"line":149},"6":{"name":"(anonymous_6)","decl":{"start":{"line":154,"column":8},"end":{"line":154,"column":58}},"loc":{"start":{"line":154,"column":58},"end":{"line":156,"column":null}},"line":154},"7":{"name":"(anonymous_7)","decl":{"start":{"line":159,"column":8},"end":{"line":159,"column":58}},"loc":{"start":{"line":159,"column":58},"end":{"line":161,"column":null}},"line":159},"8":{"name":"(anonymous_8)","decl":{"start":{"line":168,"column":8},"end":{"line":168,"column":54}},"loc":{"start":{"line":168,"column":54},"end":{"line":170,"column":null}},"line":168},"9":{"name":"(anonymous_9)","decl":{"start":{"line":173,"column":8},"end":{"line":173,"column":60}},"loc":{"start":{"line":173,"column":60},"end":{"line":175,"column":null}},"line":173},"10":{"name":"(anonymous_10)","decl":{"start":{"line":178,"column":8},"end":{"line":178,"column":59}},"loc":{"start":{"line":178,"column":59},"end":{"line":180,"column":null}},"line":178},"11":{"name":"(anonymous_11)","decl":{"start":{"line":183,"column":8},"end":{"line":183,"column":67}},"loc":{"start":{"line":183,"column":67},"end":{"line":185,"column":null}},"line":183},"12":{"name":"(anonymous_12)","decl":{"start":{"line":188,"column":8},"end":{"line":188,"column":61}},"loc":{"start":{"line":188,"column":61},"end":{"line":190,"column":null}},"line":188},"13":{"name":"(anonymous_13)","decl":{"start":{"line":196,"column":8},"end":{"line":196,"column":43}},"loc":{"start":{"line":196,"column":43},"end":{"line":223,"column":null}},"line":196}},"branchMap":{},"s":{"0":3,"1":3,"2":3,"3":3,"4":21,"5":21,"6":21,"7":5,"8":2,"9":0,"10":9,"11":1,"12":1,"13":0,"14":2,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1},"f":{"0":21,"1":5,"2":2,"3":0,"4":9,"5":1,"6":1,"7":0,"8":2,"9":1,"10":1,"11":1,"12":1,"13":1},"b":{},"meta":{"lastBranch":0,"lastFunction":14,"lastStatement":21,"seen":{"s:96:55:96:Infinity":0,"s:99:74:99:Infinity":1,"s:105:56:105:Infinity":2,"s:108:56:108:Infinity":3,"f:113:2:113:16":0,"s:114:4:114:Infinity":4,"s:115:4:115:Infinity":5,"s:116:4:116:Infinity":6,"f:124:2:124:11":1,"s:125:4:125:Infinity":7,"f:134:8:134:16":2,"s:135:4:135:Infinity":8,"f:139:8:139:60":3,"s:140:4:140:Infinity":9,"f:144:8:144:58":4,"s:145:4:145:Infinity":10,"f:149:8:149:58":5,"s:150:4:150:Infinity":11,"f:154:8:154:58":6,"s:155:4:155:Infinity":12,"f:159:8:159:58":7,"s:160:4:160:Infinity":13,"f:168:8:168:54":8,"s:169:4:169:Infinity":14,"f:173:8:173:60":9,"s:174:4:174:Infinity":15,"f:178:8:178:59":10,"s:179:4:179:Infinity":16,"f:183:8:183:67":11,"s:184:4:184:Infinity":17,"f:188:8:188:61":12,"s:189:4:189:Infinity":18,"f:196:8:196:43":13,"s:198:6:209:Infinity":19,"s:211:4:222:Infinity":20}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-validator.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/csv-validator.ts","statementMap":{"0":{"start":{"line":36,"column":4},"end":{"line":40,"column":null}},"1":{"start":{"line":41,"column":4},"end":{"line":41,"column":null}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":null}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"5":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"6":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"7":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"8":{"start":{"line":63,"column":17},"end":{"line":63,"column":null}},"9":{"start":{"line":65,"column":18},"end":{"line":65,"column":null}},"10":{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},"11":{"start":{"line":67,"column":4},"end":{"line":72,"column":null}},"12":{"start":{"line":75,"column":21},"end":{"line":75,"column":null}},"13":{"start":{"line":76,"column":20},"end":{"line":76,"column":null}},"14":{"start":{"line":77,"column":18},"end":{"line":77,"column":null}},"15":{"start":{"line":77,"column":57},"end":{"line":77,"column":74}},"16":{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},"17":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"18":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"19":{"start":{"line":93,"column":2},"end":{"line":102,"column":null}},"20":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"21":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}},"22":{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},"23":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"24":{"start":{"line":99,"column":6},"end":{"line":99,"column":null}},"25":{"start":{"line":101,"column":4},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":30,"column":2},"end":{"line":30,"column":null}},"loc":{"start":{"line":35,"column":4},"end":{"line":46,"column":null}},"line":35},"1":{"name":"validateCsvRows","decl":{"start":{"line":57,"column":16},"end":{"line":57,"column":null}},"loc":{"start":{"line":61,"column":16},"end":{"line":82,"column":null}},"line":61},"2":{"name":"(anonymous_2)","decl":{"start":{"line":77,"column":43},"end":{"line":77,"column":51}},"loc":{"start":{"line":77,"column":57},"end":{"line":77,"column":74}},"line":77},"3":{"name":"validateCsvRowsLenient","decl":{"start":{"line":89,"column":16},"end":{"line":89,"column":null}},"loc":{"start":{"line":92,"column":11},"end":{"line":103,"column":null}},"line":92}},"branchMap":{"0":{"loc":{"start":{"line":62,"column":19},"end":{"line":62,"column":null}},"type":"binary-expr","locations":[{"start":{"line":62,"column":19},"end":{"line":62,"column":39}},{"start":{"line":62,"column":39},"end":{"line":62,"column":null}}],"line":62},"1":{"loc":{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":2},"end":{"line":63,"column":null}},{"start":{},"end":{}}],"line":63},"2":{"loc":{"start":{"line":65,"column":18},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":18},"end":{"line":65,"column":38}},{"start":{"line":65,"column":38},"end":{"line":65,"column":null}}],"line":65},"3":{"loc":{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":2},"end":{"line":73,"column":null}},{"start":{},"end":{}}],"line":66},"4":{"loc":{"start":{"line":70,"column":6},"end":{"line":70,"column":null}},"type":"cond-expr","locations":[{"start":{"line":70,"column":16},"end":{"line":70,"column":39}},{"start":{"line":70,"column":39},"end":{"line":70,"column":null}}],"line":70},"5":{"loc":{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":78,"column":2},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":78},"6":{"loc":{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":100,"column":null}},{"start":{},"end":{}}],"line":97}},"s":{"0":7,"1":7,"2":7,"3":7,"4":7,"5":7,"6":11,"7":11,"8":2,"9":9,"10":11,"11":3,"12":6,"13":6,"14":6,"15":25,"16":6,"17":3,"18":3,"19":2,"20":2,"21":2,"22":1,"23":1,"24":1,"25":0},"f":{"0":7,"1":11,"2":25,"3":2},"b":{"0":[11,4],"1":[2,9],"2":[9,4],"3":[3,8],"4":[1,2],"5":[3,3],"6":[1,0]},"meta":{"lastBranch":7,"lastFunction":4,"lastStatement":26,"seen":{"f:30:2:30:Infinity":0,"s:36:4:40:Infinity":0,"s:41:4:41:Infinity":1,"s:42:4:42:Infinity":2,"s:43:4:43:Infinity":3,"s:44:4:44:Infinity":4,"s:45:4:45:Infinity":5,"f:57:16:57:Infinity":1,"s:62:19:62:Infinity":6,"b:62:19:62:39:62:39:62:Infinity":0,"b:63:2:63:Infinity:undefined:undefined:undefined:undefined":1,"s:63:2:63:Infinity":7,"s:63:17:63:Infinity":8,"s:65:18:65:Infinity":9,"b:65:18:65:38:65:38:65:Infinity":2,"b:66:2:73:Infinity:undefined:undefined:undefined:undefined":3,"s:66:2:73:Infinity":10,"s:67:4:72:Infinity":11,"b:70:16:70:39:70:39:70:Infinity":4,"s:75:21:75:Infinity":12,"s:76:20:76:Infinity":13,"s:77:18:77:Infinity":14,"f:77:43:77:51":2,"s:77:57:77:74":15,"b:78:2:80:Infinity:undefined:undefined:undefined:undefined":5,"s:78:2:80:Infinity":16,"s:79:4:79:Infinity":17,"s:81:2:81:Infinity":18,"f:89:16:89:Infinity":3,"s:93:2:102:Infinity":19,"s:94:4:94:Infinity":20,"s:95:4:95:Infinity":21,"b:97:4:100:Infinity:undefined:undefined:undefined:undefined":6,"s:97:4:100:Infinity":22,"s:98:6:98:Infinity":23,"s:99:6:99:Infinity":24,"s:101:4:101:Infinity":25}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/committees.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/committees.ts","statementMap":{"0":{"start":{"line":38,"column":35},"end":{"line":41,"column":null}},"1":{"start":{"line":43,"column":46},"end":{"line":43,"column":null}},"2":{"start":{"line":44,"column":2},"end":{"line":46,"column":null}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"4":{"start":{"line":48,"column":24},"end":{"line":48,"column":null}},"5":{"start":{"line":50,"column":45},"end":{"line":50,"column":null}},"6":{"start":{"line":51,"column":2},"end":{"line":60,"column":null}},"7":{"start":{"line":52,"column":17},"end":{"line":52,"column":null}},"8":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"9":{"start":{"line":53,"column":15},"end":{"line":53,"column":null}},"10":{"start":{"line":54,"column":21},"end":{"line":54,"column":null}},"11":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"12":{"start":{"line":58,"column":6},"end":{"line":58,"column":null}},"13":{"start":{"line":62,"column":39},"end":{"line":94,"column":null}},"14":{"start":{"line":64,"column":19},"end":{"line":64,"column":null}},"15":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"16":{"start":{"line":66,"column":30},"end":{"line":66,"column":null}},"17":{"start":{"line":67,"column":27},"end":{"line":67,"column":null}},"18":{"start":{"line":68,"column":33},"end":{"line":68,"column":null}},"19":{"start":{"line":69,"column":33},"end":{"line":69,"column":null}},"20":{"start":{"line":70,"column":6},"end":{"line":85,"column":null}},"21":{"start":{"line":88,"column":6},"end":{"line":91,"column":null}},"22":{"start":{"line":94,"column":20},"end":{"line":94,"column":63}},"23":{"start":{"line":96,"column":31},"end":{"line":100,"column":null}},"24":{"start":{"line":96,"column":52},"end":{"line":100,"column":4}},"25":{"start":{"line":102,"column":31},"end":{"line":102,"column":null}},"26":{"start":{"line":103,"column":2},"end":{"line":117,"column":null}},"27":{"start":{"line":103,"column":15},"end":{"line":103,"column":18}},"28":{"start":{"line":104,"column":4},"end":{"line":116,"column":null}},"29":{"start":{"line":104,"column":17},"end":{"line":104,"column":24}},"30":{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},"31":{"start":{"line":109,"column":8},"end":{"line":114,"column":null}},"32":{"start":{"line":119,"column":2},"end":{"line":127,"column":null}}},"fnMap":{"0":{"name":"loadCommitteeNetwork","decl":{"start":{"line":37,"column":22},"end":{"line":37,"column":43}},"loc":{"start":{"line":37,"column":88},"end":{"line":128,"column":null}},"line":37},"1":{"name":"(anonymous_1)","decl":{"start":{"line":44,"column":11},"end":{"line":44,"column":19}},"loc":{"start":{"line":44,"column":24},"end":{"line":46,"column":3}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":51,"column":15},"end":{"line":51,"column":23}},"loc":{"start":{"line":51,"column":28},"end":{"line":60,"column":3}},"line":51},"3":{"name":"(anonymous_3)","decl":{"start":{"line":63,"column":5},"end":{"line":63,"column":9}},"loc":{"start":{"line":63,"column":14},"end":{"line":86,"column":5}},"line":63},"4":{"name":"(anonymous_4)","decl":{"start":{"line":87,"column":5},"end":{"line":87,"column":12}},"loc":{"start":{"line":87,"column":17},"end":{"line":93,"column":5}},"line":87},"5":{"name":"(anonymous_5)","decl":{"start":{"line":94,"column":5},"end":{"line":94,"column":11}},"loc":{"start":{"line":94,"column":20},"end":{"line":94,"column":63}},"line":94},"6":{"name":"(anonymous_6)","decl":{"start":{"line":96,"column":42},"end":{"line":96,"column":46}},"loc":{"start":{"line":96,"column":52},"end":{"line":100,"column":4}},"line":96}},"branchMap":{"0":{"loc":{"start":{"line":45,"column":36},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":36},"end":{"line":45,"column":67}},{"start":{"line":45,"column":67},"end":{"line":45,"column":null}}],"line":45},"1":{"loc":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},{"start":{},"end":{}}],"line":53},"2":{"loc":{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":55},"3":{"loc":{"start":{"line":55,"column":8},"end":{"line":57,"column":76}},"type":"binary-expr","locations":[{"start":{"line":55,"column":8},"end":{"line":55,"column":22}},{"start":{"line":55,"column":22},"end":{"line":55,"column":null}},{"start":{"line":56,"column":10},"end":{"line":56,"column":null}},{"start":{"line":57,"column":10},"end":{"line":57,"column":76}}],"line":55},"4":{"loc":{"start":{"line":65,"column":19},"end":{"line":65,"column":null}},"type":"binary-expr","locations":[{"start":{"line":65,"column":19},"end":{"line":65,"column":42}},{"start":{"line":65,"column":42},"end":{"line":65,"column":null}}],"line":65},"5":{"loc":{"start":{"line":66,"column":30},"end":{"line":66,"column":null}},"type":"binary-expr","locations":[{"start":{"line":66,"column":30},"end":{"line":66,"column":62}},{"start":{"line":66,"column":62},"end":{"line":66,"column":null}}],"line":66},"6":{"loc":{"start":{"line":67,"column":27},"end":{"line":67,"column":null}},"type":"binary-expr","locations":[{"start":{"line":67,"column":27},"end":{"line":67,"column":48}},{"start":{"line":67,"column":48},"end":{"line":67,"column":null}}],"line":67},"7":{"loc":{"start":{"line":69,"column":33},"end":{"line":69,"column":null}},"type":"binary-expr","locations":[{"start":{"line":69,"column":33},"end":{"line":69,"column":68}},{"start":{"line":69,"column":68},"end":{"line":69,"column":null}}],"line":69},"8":{"loc":{"start":{"line":73,"column":22},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":22},"end":{"line":73,"column":52}},{"start":{"line":73,"column":52},"end":{"line":73,"column":null}}],"line":73},"9":{"loc":{"start":{"line":74,"column":24},"end":{"line":76,"column":null}},"type":"cond-expr","locations":[{"start":{"line":75,"column":12},"end":{"line":75,"column":null}},{"start":{"line":76,"column":12},"end":{"line":76,"column":null}}],"line":74},"10":{"loc":{"start":{"line":80,"column":10},"end":{"line":82,"column":null}},"type":"cond-expr","locations":[{"start":{"line":81,"column":14},"end":{"line":81,"column":null}},{"start":{"line":82,"column":14},"end":{"line":82,"column":null}}],"line":80},"11":{"loc":{"start":{"line":83,"column":20},"end":{"line":83,"column":46}},"type":"binary-expr","locations":[{"start":{"line":83,"column":20},"end":{"line":83,"column":41}},{"start":{"line":83,"column":41},"end":{"line":83,"column":46}}],"line":83},"12":{"loc":{"start":{"line":89,"column":8},"end":{"line":91,"column":null}},"type":"binary-expr","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":null}},{"start":{"line":90,"column":8},"end":{"line":90,"column":null}},{"start":{"line":91,"column":9},"end":{"line":91,"column":47}},{"start":{"line":91,"column":47},"end":{"line":91,"column":null}}],"line":89},"13":{"loc":{"start":{"line":104,"column":24},"end":{"line":104,"column":68}},"type":"binary-expr","locations":[{"start":{"line":104,"column":24},"end":{"line":104,"column":49}},{"start":{"line":104,"column":49},"end":{"line":104,"column":68}}],"line":104},"14":{"loc":{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":6},"end":{"line":115,"column":null}},{"start":{},"end":{}}],"line":105},"15":{"loc":{"start":{"line":106,"column":8},"end":{"line":107,"column":null}},"type":"binary-expr","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":null}},{"start":{"line":107,"column":8},"end":{"line":107,"column":null}}],"line":106}},"s":{"0":1,"1":1,"2":1,"3":2,"4":1,"5":1,"6":1,"7":4,"8":4,"9":0,"10":4,"11":4,"12":4,"13":1,"14":4,"15":4,"16":4,"17":4,"18":4,"19":4,"20":4,"21":4,"22":1,"23":1,"24":2,"25":1,"26":1,"27":1,"28":2,"29":2,"30":1,"31":1,"32":1},"f":{"0":1,"1":2,"2":4,"3":4,"4":4,"5":1,"6":2},"b":{"0":[2,0],"1":[0,4],"2":[4,0],"3":[4,0,0,0],"4":[4,2],"5":[4,1],"6":[4,2],"7":[4,0],"8":[4,1],"9":[3,1],"10":[3,1],"11":[4,0],"12":[4,3,2,0],"13":[2,1],"14":[1,0],"15":[1,1]},"meta":{"lastBranch":16,"lastFunction":7,"lastStatement":33,"seen":{"f:37:22:37:43":0,"s:38:35:41:Infinity":0,"s:43:46:43:Infinity":1,"s:44:2:46:Infinity":2,"f:44:11:44:19":1,"s:45:4:45:Infinity":3,"b:45:36:45:67:45:67:45:Infinity":0,"s:48:24:48:Infinity":4,"s:50:45:50:Infinity":5,"s:51:2:60:Infinity":6,"f:51:15:51:23":2,"s:52:17:52:Infinity":7,"b:53:4:53:Infinity:undefined:undefined:undefined:undefined":1,"s:53:4:53:Infinity":8,"s:53:15:53:Infinity":9,"s:54:21:54:Infinity":10,"b:55:4:59:Infinity:undefined:undefined:undefined:undefined":2,"s:55:4:59:Infinity":11,"b:55:8:55:22:55:22:55:Infinity:56:10:56:Infinity:57:10:57:76":3,"s:58:6:58:Infinity":12,"s:62:39:94:Infinity":13,"f:63:5:63:9":3,"s:64:19:64:Infinity":14,"s:65:19:65:Infinity":15,"b:65:19:65:42:65:42:65:Infinity":4,"s:66:30:66:Infinity":16,"b:66:30:66:62:66:62:66:Infinity":5,"s:67:27:67:Infinity":17,"b:67:27:67:48:67:48:67:Infinity":6,"s:68:33:68:Infinity":18,"s:69:33:69:Infinity":19,"b:69:33:69:68:69:68:69:Infinity":7,"s:70:6:85:Infinity":20,"b:73:22:73:52:73:52:73:Infinity":8,"b:75:12:75:Infinity:76:12:76:Infinity":9,"b:81:14:81:Infinity:82:14:82:Infinity":10,"b:83:20:83:41:83:41:83:46":11,"f:87:5:87:12":4,"s:88:6:91:Infinity":21,"b:89:8:89:Infinity:90:8:90:Infinity:91:9:91:47:91:47:91:Infinity":12,"f:94:5:94:11":5,"s:94:20:94:63":22,"s:96:31:100:Infinity":23,"f:96:42:96:46":6,"s:96:52:100:4":24,"s:102:31:102:Infinity":25,"s:103:2:117:Infinity":26,"s:103:15:103:18":27,"s:104:4:116:Infinity":28,"s:104:17:104:24":29,"b:104:24:104:49:104:49:104:68":13,"b:105:6:115:Infinity:undefined:undefined:undefined:undefined":14,"s:105:6:115:Infinity":30,"b:106:8:106:Infinity:107:8:107:Infinity":15,"s:109:8:114:Infinity":31,"s:119:2:127:Infinity":32}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/demographics.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/demographics.ts","statementMap":{"0":{"start":{"line":29,"column":39},"end":{"line":32,"column":null}},"1":{"start":{"line":34,"column":39},"end":{"line":40,"column":null}},"2":{"start":{"line":35,"column":17},"end":{"line":35,"column":60}},"3":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"4":{"start":{"line":42,"column":47},"end":{"line":48,"column":null}},"5":{"start":{"line":43,"column":17},"end":{"line":43,"column":60}},"6":{"start":{"line":44,"column":15},"end":{"line":48,"column":6}},"7":{"start":{"line":50,"column":2},"end":{"line":57,"column":null}}},"fnMap":{"0":{"name":"loadDemographics","decl":{"start":{"line":28,"column":22},"end":{"line":28,"column":39}},"loc":{"start":{"line":28,"column":89},"end":{"line":58,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":5},"end":{"line":35,"column":12}},"loc":{"start":{"line":35,"column":17},"end":{"line":35,"column":60}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":9}},"loc":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":43,"column":5},"end":{"line":43,"column":12}},"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":60}},"line":43},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":9}},"loc":{"start":{"line":44,"column":15},"end":{"line":48,"column":6}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":14},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":14},"end":{"line":39,"column":36}},{"start":{"line":39,"column":36},"end":{"line":39,"column":null}}],"line":39},"1":{"loc":{"start":{"line":46,"column":24},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":24},"end":{"line":46,"column":57}},{"start":{"line":46,"column":57},"end":{"line":46,"column":null}}],"line":46},"2":{"loc":{"start":{"line":47,"column":24},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":24},"end":{"line":47,"column":57}},{"start":{"line":47,"column":57},"end":{"line":47,"column":null}}],"line":47}},"s":{"0":2,"1":2,"2":5,"3":3,"4":2,"5":5,"6":3,"7":2},"f":{"0":2,"1":5,"2":3,"3":5,"4":3},"b":{"0":[3,0],"1":[3,0],"2":[3,0]},"meta":{"lastBranch":3,"lastFunction":5,"lastStatement":8,"seen":{"f:28:22:28:39":0,"s:29:39:32:Infinity":0,"s:34:39:40:Infinity":1,"f:35:5:35:12":1,"s:35:17:35:60":2,"f:36:5:36:9":2,"s:36:15:40:6":3,"b:39:14:39:36:39:36:39:Infinity":0,"s:42:47:48:Infinity":4,"f:43:5:43:12":3,"s:43:17:43:60":5,"f:44:5:44:9":4,"s:44:15:48:6":6,"b:46:24:46:57:46:57:46:Infinity":1,"b:47:24:47:57:47:57:47:Infinity":2,"s:50:2:57:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/documents.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/documents.ts","statementMap":{"0":{"start":{"line":29,"column":38},"end":{"line":32,"column":null}},"1":{"start":{"line":34,"column":45},"end":{"line":40,"column":null}},"2":{"start":{"line":35,"column":18},"end":{"line":35,"column":44}},"3":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"4":{"start":{"line":42,"column":47},"end":{"line":51,"column":null}},"5":{"start":{"line":43,"column":18},"end":{"line":43,"column":49}},"6":{"start":{"line":44,"column":15},"end":{"line":51,"column":6}},"7":{"start":{"line":53,"column":2},"end":{"line":60,"column":null}}},"fnMap":{"0":{"name":"loadDocumentActivity","decl":{"start":{"line":28,"column":22},"end":{"line":28,"column":43}},"loc":{"start":{"line":28,"column":97},"end":{"line":61,"column":null}},"line":28},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":5},"end":{"line":35,"column":12}},"loc":{"start":{"line":35,"column":18},"end":{"line":35,"column":44}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":5},"end":{"line":36,"column":9}},"loc":{"start":{"line":36,"column":15},"end":{"line":40,"column":6}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":43,"column":5},"end":{"line":43,"column":12}},"loc":{"start":{"line":43,"column":18},"end":{"line":43,"column":49}},"line":43},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":9}},"loc":{"start":{"line":44,"column":15},"end":{"line":51,"column":6}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":13},"end":{"line":37,"column":null}},"type":"binary-expr","locations":[{"start":{"line":37,"column":13},"end":{"line":37,"column":34}},{"start":{"line":37,"column":34},"end":{"line":37,"column":null}}],"line":37},"1":{"loc":{"start":{"line":38,"column":21},"end":{"line":38,"column":null}},"type":"binary-expr","locations":[{"start":{"line":38,"column":21},"end":{"line":38,"column":51}},{"start":{"line":38,"column":51},"end":{"line":38,"column":null}}],"line":38},"2":{"loc":{"start":{"line":39,"column":17},"end":{"line":39,"column":null}},"type":"binary-expr","locations":[{"start":{"line":39,"column":17},"end":{"line":39,"column":43}},{"start":{"line":39,"column":43},"end":{"line":39,"column":null}}],"line":39},"3":{"loc":{"start":{"line":45,"column":13},"end":{"line":45,"column":null}},"type":"binary-expr","locations":[{"start":{"line":45,"column":13},"end":{"line":45,"column":34}},{"start":{"line":45,"column":34},"end":{"line":45,"column":null}}],"line":45},"4":{"loc":{"start":{"line":46,"column":14},"end":{"line":46,"column":null}},"type":"binary-expr","locations":[{"start":{"line":46,"column":14},"end":{"line":46,"column":36}},{"start":{"line":46,"column":36},"end":{"line":46,"column":null}}],"line":46},"5":{"loc":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":22},"end":{"line":47,"column":53}},{"start":{"line":47,"column":53},"end":{"line":47,"column":null}}],"line":47},"6":{"loc":{"start":{"line":48,"column":26},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":26},"end":{"line":48,"column":61}},{"start":{"line":48,"column":61},"end":{"line":48,"column":null}}],"line":48},"7":{"loc":{"start":{"line":49,"column":26},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":26},"end":{"line":49,"column":61}},{"start":{"line":49,"column":61},"end":{"line":49,"column":null}}],"line":49},"8":{"loc":{"start":{"line":50,"column":21},"end":{"line":50,"column":null}},"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":51}},{"start":{"line":50,"column":51},"end":{"line":50,"column":null}}],"line":50}},"s":{"0":2,"1":2,"2":4,"3":2,"4":2,"5":4,"6":2,"7":2},"f":{"0":2,"1":4,"2":2,"3":4,"4":2},"b":{"0":[2,0],"1":[2,0],"2":[2,0],"3":[2,0],"4":[2,0],"5":[2,0],"6":[2,0],"7":[2,0],"8":[2,0]},"meta":{"lastBranch":9,"lastFunction":5,"lastStatement":8,"seen":{"f:28:22:28:43":0,"s:29:38:32:Infinity":0,"s:34:45:40:Infinity":1,"f:35:5:35:12":1,"s:35:18:35:44":2,"f:36:5:36:9":2,"s:36:15:40:6":3,"b:37:13:37:34:37:34:37:Infinity":0,"b:38:21:38:51:38:51:38:Infinity":1,"b:39:17:39:43:39:43:39:Infinity":2,"s:42:47:51:Infinity":4,"f:43:5:43:12":3,"s:43:18:43:49":5,"f:44:5:44:9":4,"s:44:15:51:6":6,"b:45:13:45:34:45:34:45:Infinity":3,"b:46:14:46:36:46:36:46:Infinity":4,"b:47:22:47:53:47:53:47:Infinity":5,"b:48:26:48:61:48:61:48:Infinity":6,"b:49:26:49:61:49:61:49:Infinity":7,"b:50:21:50:51:50:51:50:Infinity":8,"s:53:2:60:Infinity":7}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/ministries.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/ministries.ts","statementMap":{"0":{"start":{"line":25,"column":15},"end":{"line":25,"column":null}},"1":{"start":{"line":27,"column":38},"end":{"line":37,"column":null}},"2":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"3":{"start":{"line":29,"column":15},"end":{"line":36,"column":6}},"4":{"start":{"line":37,"column":20},"end":{"line":37,"column":61}},"5":{"start":{"line":39,"column":2},"end":{"line":45,"column":null}}},"fnMap":{"0":{"name":"loadMinistryDashboard","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":44}},"loc":{"start":{"line":24,"column":90},"end":{"line":46,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":5},"end":{"line":28,"column":12}},"loc":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"line":28},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":5},"end":{"line":29,"column":9}},"loc":{"start":{"line":29,"column":15},"end":{"line":36,"column":6}},"line":29},"3":{"name":"(anonymous_3)","decl":{"start":{"line":37,"column":5},"end":{"line":37,"column":11}},"loc":{"start":{"line":37,"column":20},"end":{"line":37,"column":61}},"line":37}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":17},"end":{"line":28,"column":72}},"type":"binary-expr","locations":[{"start":{"line":28,"column":17},"end":{"line":28,"column":37}},{"start":{"line":28,"column":37},"end":{"line":28,"column":72}}],"line":28},"1":{"loc":{"start":{"line":31,"column":22},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":22},"end":{"line":31,"column":63}},{"start":{"line":31,"column":63},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":32,"column":26},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":26},"end":{"line":32,"column":61}},{"start":{"line":32,"column":61},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":24},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":24},"end":{"line":33,"column":57}},{"start":{"line":33,"column":57},"end":{"line":33,"column":null}}],"line":33},"4":{"loc":{"start":{"line":34,"column":13},"end":{"line":34,"column":null}},"type":"binary-expr","locations":[{"start":{"line":34,"column":13},"end":{"line":34,"column":34}},{"start":{"line":34,"column":34},"end":{"line":34,"column":null}}],"line":34},"5":{"loc":{"start":{"line":35,"column":16},"end":{"line":35,"column":null}},"type":"binary-expr","locations":[{"start":{"line":35,"column":16},"end":{"line":35,"column":40}},{"start":{"line":35,"column":40},"end":{"line":35,"column":null}}],"line":35}},"s":{"0":2,"1":2,"2":5,"3":3,"4":1,"5":2},"f":{"0":2,"1":5,"2":3,"3":1},"b":{"0":[5,5],"1":[3,0],"2":[3,0],"3":[3,0],"4":[3,0],"5":[3,0]},"meta":{"lastBranch":6,"lastFunction":4,"lastStatement":6,"seen":{"f:24:22:24:44":0,"s:25:15:25:Infinity":0,"s:27:38:37:Infinity":1,"f:28:5:28:12":1,"s:28:17:28:72":2,"b:28:17:28:37:28:37:28:72":0,"f:29:5:29:9":2,"s:29:15:36:6":3,"b:31:22:31:63:31:63:31:Infinity":1,"b:32:26:32:61:32:61:32:Infinity":2,"b:33:24:33:57:33:57:33:Infinity":3,"b:34:13:34:34:34:34:34:Infinity":4,"b:35:16:35:40:35:40:35:Infinity":5,"f:37:5:37:11":3,"s:37:20:37:61":4,"s:39:2:45:Infinity":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/election.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/election.ts","statementMap":{"0":{"start":{"line":19,"column":6},"end":{"line":26,"column":null}},"1":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"2":{"start":{"line":20,"column":59},"end":{"line":20,"column":null}},"3":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"4":{"start":{"line":22,"column":16},"end":{"line":22,"column":null}},"5":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"6":{"start":{"line":23,"column":30},"end":{"line":23,"column":null}},"7":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"8":{"start":{"line":28,"column":6},"end":{"line":36,"column":null}},"9":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"10":{"start":{"line":29,"column":34},"end":{"line":29,"column":null}},"11":{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},"12":{"start":{"line":31,"column":23},"end":{"line":31,"column":null}},"13":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"14":{"start":{"line":32,"column":31},"end":{"line":32,"column":null}},"15":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"16":{"start":{"line":33,"column":32},"end":{"line":33,"column":null}},"17":{"start":{"line":35,"column":2},"end":{"line":35,"column":null}},"18":{"start":{"line":46,"column":39},"end":{"line":49,"column":null}},"19":{"start":{"line":51,"column":18},"end":{"line":76,"column":null}},"20":{"start":{"line":52,"column":17},"end":{"line":52,"column":null}},"21":{"start":{"line":53,"column":25},"end":{"line":53,"column":null}},"22":{"start":{"line":54,"column":27},"end":{"line":54,"column":null}},"23":{"start":{"line":55,"column":19},"end":{"line":55,"column":null}},"24":{"start":{"line":56,"column":22},"end":{"line":56,"column":null}},"25":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"26":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"27":{"start":{"line":62,"column":26},"end":{"line":62,"column":null}},"28":{"start":{"line":63,"column":26},"end":{"line":63,"column":null}},"29":{"start":{"line":65,"column":4},"end":{"line":75,"column":null}},"30":{"start":{"line":78,"column":29},"end":{"line":108,"column":null}},"31":{"start":{"line":79,"column":17},"end":{"line":79,"column":null}},"32":{"start":{"line":80,"column":24},"end":{"line":80,"column":null}},"33":{"start":{"line":81,"column":23},"end":{"line":81,"column":null}},"34":{"start":{"line":82,"column":21},"end":{"line":82,"column":null}},"35":{"start":{"line":83,"column":22},"end":{"line":83,"column":null}},"36":{"start":{"line":84,"column":24},"end":{"line":87,"column":null}},"37":{"start":{"line":86,"column":16},"end":{"line":86,"column":24}},"38":{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},"39":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"40":{"start":{"line":100,"column":4},"end":{"line":107,"column":null}},"41":{"start":{"line":110,"column":2},"end":{"line":121,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":19,"column":6},"end":{"line":19,"column":24}},"loc":{"start":{"line":19,"column":63},"end":{"line":26,"column":null}},"line":19},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":6},"end":{"line":28,"column":19}},"loc":{"start":{"line":28,"column":59},"end":{"line":36,"column":null}},"line":28},"2":{"name":"loadElectionAnalysis","decl":{"start":{"line":45,"column":22},"end":{"line":45,"column":43}},"loc":{"start":{"line":45,"column":88},"end":{"line":122,"column":null}},"line":45},"3":{"name":"(anonymous_3)","decl":{"start":{"line":51,"column":31},"end":{"line":51,"column":39}},"loc":{"start":{"line":51,"column":44},"end":{"line":76,"column":3}},"line":51},"4":{"name":"(anonymous_4)","decl":{"start":{"line":78,"column":42},"end":{"line":78,"column":50}},"loc":{"start":{"line":78,"column":55},"end":{"line":108,"column":3}},"line":78},"5":{"name":"(anonymous_5)","decl":{"start":{"line":86,"column":7},"end":{"line":86,"column":11}},"loc":{"start":{"line":86,"column":16},"end":{"line":86,"column":24}},"line":86}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"type":"if","locations":[{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},{"start":{},"end":{}}],"line":20},"1":{"loc":{"start":{"line":20,"column":6},"end":{"line":20,"column":59}},"type":"binary-expr","locations":[{"start":{"line":20,"column":6},"end":{"line":20,"column":35}},{"start":{"line":20,"column":35},"end":{"line":20,"column":59}}],"line":20},"2":{"loc":{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},"type":"if","locations":[{"start":{"line":21,"column":2},"end":{"line":24,"column":null}},{"start":{},"end":{}}],"line":21},"3":{"loc":{"start":{"line":21,"column":6},"end":{"line":21,"column":56}},"type":"binary-expr","locations":[{"start":{"line":21,"column":6},"end":{"line":21,"column":35}},{"start":{"line":21,"column":35},"end":{"line":21,"column":56}}],"line":21},"4":{"loc":{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23},"5":{"loc":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"type":"if","locations":[{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},{"start":{},"end":{}}],"line":29},"6":{"loc":{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":34,"column":null}},{"start":{},"end":{}}],"line":30},"7":{"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":null}},{"start":{},"end":{}}],"line":32},"8":{"loc":{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":33,"column":4},"end":{"line":33,"column":null}},{"start":{},"end":{}}],"line":33},"9":{"loc":{"start":{"line":52,"column":24},"end":{"line":52,"column":36}},"type":"binary-expr","locations":[{"start":{"line":52,"column":24},"end":{"line":52,"column":34}},{"start":{"line":52,"column":34},"end":{"line":52,"column":36}}],"line":52},"10":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":58},"11":{"loc":{"start":{"line":58,"column":8},"end":{"line":58,"column":128}},"type":"binary-expr","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":17}},{"start":{"line":58,"column":17},"end":{"line":58,"column":47}},{"start":{"line":58,"column":47},"end":{"line":58,"column":79}},{"start":{"line":58,"column":79},"end":{"line":58,"column":103}},{"start":{"line":58,"column":103},"end":{"line":58,"column":128}}],"line":58},"12":{"loc":{"start":{"line":72,"column":8},"end":{"line":74,"column":null}},"type":"cond-expr","locations":[{"start":{"line":73,"column":12},"end":{"line":73,"column":null}},{"start":{"line":74,"column":12},"end":{"line":74,"column":null}}],"line":72},"13":{"loc":{"start":{"line":72,"column":8},"end":{"line":72,"column":null}},"type":"binary-expr","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},{"start":{"line":72,"column":39},"end":{"line":72,"column":null}}],"line":72},"14":{"loc":{"start":{"line":79,"column":24},"end":{"line":79,"column":36}},"type":"binary-expr","locations":[{"start":{"line":79,"column":24},"end":{"line":79,"column":34}},{"start":{"line":79,"column":34},"end":{"line":79,"column":36}}],"line":79},"15":{"loc":{"start":{"line":83,"column":29},"end":{"line":83,"column":46}},"type":"binary-expr","locations":[{"start":{"line":83,"column":29},"end":{"line":83,"column":44}},{"start":{"line":83,"column":44},"end":{"line":83,"column":46}}],"line":83},"16":{"loc":{"start":{"line":84,"column":31},"end":{"line":84,"column":50}},"type":"binary-expr","locations":[{"start":{"line":84,"column":31},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":50}}],"line":84},"17":{"loc":{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":98,"column":null}},{"start":{},"end":{}}],"line":89},"18":{"loc":{"start":{"line":90,"column":6},"end":{"line":95,"column":null}},"type":"binary-expr","locations":[{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},{"start":{"line":93,"column":6},"end":{"line":93,"column":null}},{"start":{"line":94,"column":6},"end":{"line":94,"column":null}},{"start":{"line":95,"column":6},"end":{"line":95,"column":null}}],"line":90}},"s":{"0":4,"1":376,"2":370,"3":6,"4":0,"5":0,"6":0,"7":6,"8":4,"9":30,"10":29,"11":1,"12":1,"13":1,"14":0,"15":1,"16":0,"17":1,"18":10,"19":10,"20":53,"21":53,"22":53,"23":53,"24":53,"25":53,"26":1,"27":52,"28":52,"29":52,"30":10,"31":30,"32":30,"33":30,"34":30,"35":30,"36":30,"37":107,"38":30,"39":3,"40":27,"41":10},"f":{"0":376,"1":30,"2":10,"3":53,"4":30,"5":107},"b":{"0":[370,6],"1":[376,370],"2":[0,6],"3":[6,0],"4":[0,0],"5":[29,1],"6":[1,0],"7":[0,1],"8":[0,1],"9":[53,0],"10":[1,52],"11":[53,53,52,52,52],"12":[50,2],"13":[52,50],"14":[30,0],"15":[30,1],"16":[30,0],"17":[3,27],"18":[30,30,29,29,28,27]},"meta":{"lastBranch":19,"lastFunction":6,"lastStatement":42,"seen":{"s:19:6:26:Infinity":0,"f:19:6:19:24":0,"b:20:2:20:Infinity:undefined:undefined:undefined:undefined":0,"s:20:2:20:Infinity":1,"b:20:6:20:35:20:35:20:59":1,"s:20:59:20:Infinity":2,"b:21:2:24:Infinity:undefined:undefined:undefined:undefined":2,"s:21:2:24:Infinity":3,"b:21:6:21:35:21:35:21:56":3,"s:22:16:22:Infinity":4,"b:23:4:23:Infinity:undefined:undefined:undefined:undefined":4,"s:23:4:23:Infinity":5,"s:23:30:23:Infinity":6,"s:25:2:25:Infinity":7,"s:28:6:36:Infinity":8,"f:28:6:28:19":1,"b:29:2:29:Infinity:undefined:undefined:undefined:undefined":5,"s:29:2:29:Infinity":9,"s:29:34:29:Infinity":10,"b:30:2:34:Infinity:undefined:undefined:undefined:undefined":6,"s:30:2:34:Infinity":11,"s:31:23:31:Infinity":12,"b:32:4:32:Infinity:undefined:undefined:undefined:undefined":7,"s:32:4:32:Infinity":13,"s:32:31:32:Infinity":14,"b:33:4:33:Infinity:undefined:undefined:undefined:undefined":8,"s:33:4:33:Infinity":15,"s:33:32:33:Infinity":16,"s:35:2:35:Infinity":17,"f:45:22:45:43":2,"s:46:39:49:Infinity":18,"s:51:18:76:Infinity":19,"f:51:31:51:39":3,"s:52:17:52:Infinity":20,"b:52:24:52:34:52:34:52:36":9,"s:53:25:53:Infinity":21,"s:54:27:54:Infinity":22,"s:55:19:55:Infinity":23,"s:56:22:56:Infinity":24,"b:58:4:60:Infinity:undefined:undefined:undefined:undefined":10,"s:58:4:60:Infinity":25,"b:58:8:58:17:58:17:58:47:58:47:58:79:58:79:58:103:58:103:58:128":11,"s:59:6:59:Infinity":26,"s:62:26:62:Infinity":27,"s:63:26:63:Infinity":28,"s:65:4:75:Infinity":29,"b:73:12:73:Infinity:74:12:74:Infinity":12,"b:72:8:72:39:72:39:72:Infinity":13,"s:78:29:108:Infinity":30,"f:78:42:78:50":4,"s:79:17:79:Infinity":31,"b:79:24:79:34:79:34:79:36":14,"s:80:24:80:Infinity":32,"s:81:23:81:Infinity":33,"s:82:21:82:Infinity":34,"s:83:22:83:Infinity":35,"b:83:29:83:44:83:44:83:46":15,"s:84:24:87:Infinity":36,"b:84:31:84:48:84:48:84:50":16,"f:86:7:86:11":5,"s:86:16:86:24":37,"b:89:4:98:Infinity:undefined:undefined:undefined:undefined":17,"s:89:4:98:Infinity":38,"b:90:6:90:Infinity:91:6:91:Infinity:92:6:92:Infinity:93:6:93:Infinity:94:6:94:Infinity:95:6:95:Infinity":18,"s:97:6:97:Infinity":39,"s:100:4:107:Infinity":40,"s:110:2:121:Infinity":41}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/overview.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/overview.ts","statementMap":{"0":{"start":{"line":27,"column":77},"end":{"line":33,"column":null}},"1":{"start":{"line":35,"column":20},"end":{"line":35,"column":null}},"2":{"start":{"line":35,"column":43},"end":{"line":35,"column":87}},"3":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"4":{"start":{"line":38,"column":24},"end":{"line":40,"column":null}},"5":{"start":{"line":39,"column":25},"end":{"line":39,"column":42}},"6":{"start":{"line":39,"column":56},"end":{"line":39,"column":83}},"7":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"8":{"start":{"line":43,"column":19},"end":{"line":43,"column":null}},"9":{"start":{"line":43,"column":43},"end":{"line":43,"column":66}},"10":{"start":{"line":44,"column":18},"end":{"line":44,"column":null}},"11":{"start":{"line":44,"column":42},"end":{"line":44,"column":67}},"12":{"start":{"line":45,"column":18},"end":{"line":45,"column":null}},"13":{"start":{"line":45,"column":42},"end":{"line":45,"column":64}},"14":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"15":{"start":{"line":46,"column":47},"end":{"line":46,"column":92}},"16":{"start":{"line":47,"column":16},"end":{"line":47,"column":null}},"17":{"start":{"line":47,"column":43},"end":{"line":47,"column":88}},"18":{"start":{"line":48,"column":16},"end":{"line":48,"column":null}},"19":{"start":{"line":48,"column":43},"end":{"line":48,"column":88}},"20":{"start":{"line":50,"column":25},"end":{"line":52,"column":null}},"21":{"start":{"line":51,"column":36},"end":{"line":51,"column":81}},"22":{"start":{"line":54,"column":31},"end":{"line":56,"column":null}},"23":{"start":{"line":58,"column":22},"end":{"line":58,"column":null}},"24":{"start":{"line":59,"column":25},"end":{"line":59,"column":null}},"25":{"start":{"line":59,"column":48},"end":{"line":59,"column":87}},"26":{"start":{"line":60,"column":24},"end":{"line":62,"column":null}},"27":{"start":{"line":61,"column":49},"end":{"line":61,"column":96}},"28":{"start":{"line":64,"column":2},"end":{"line":101,"column":null}}},"fnMap":{"0":{"name":"loadOverviewDashboard","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":44}},"loc":{"start":{"line":26,"column":90},"end":{"line":102,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":35,"column":33},"end":{"line":35,"column":38}},"loc":{"start":{"line":35,"column":43},"end":{"line":35,"column":87}},"line":35},"2":{"name":"(anonymous_2)","decl":{"start":{"line":39,"column":16},"end":{"line":39,"column":20}},"loc":{"start":{"line":39,"column":25},"end":{"line":39,"column":42}},"line":39},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":44},"end":{"line":39,"column":51}},"loc":{"start":{"line":39,"column":56},"end":{"line":39,"column":83}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":43,"column":31},"end":{"line":43,"column":38}},"loc":{"start":{"line":43,"column":43},"end":{"line":43,"column":66}},"line":43},"5":{"name":"(anonymous_5)","decl":{"start":{"line":44,"column":30},"end":{"line":44,"column":37}},"loc":{"start":{"line":44,"column":42},"end":{"line":44,"column":67}},"line":44},"6":{"name":"(anonymous_6)","decl":{"start":{"line":45,"column":30},"end":{"line":45,"column":37}},"loc":{"start":{"line":45,"column":42},"end":{"line":45,"column":64}},"line":45},"7":{"name":"(anonymous_7)","decl":{"start":{"line":46,"column":28},"end":{"line":46,"column":36}},"loc":{"start":{"line":46,"column":47},"end":{"line":46,"column":92}},"line":46},"8":{"name":"(anonymous_8)","decl":{"start":{"line":47,"column":24},"end":{"line":47,"column":32}},"loc":{"start":{"line":47,"column":43},"end":{"line":47,"column":88}},"line":47},"9":{"name":"(anonymous_9)","decl":{"start":{"line":48,"column":24},"end":{"line":48,"column":32}},"loc":{"start":{"line":48,"column":43},"end":{"line":48,"column":88}},"line":48},"10":{"name":"(anonymous_10)","decl":{"start":{"line":51,"column":17},"end":{"line":51,"column":25}},"loc":{"start":{"line":51,"column":36},"end":{"line":51,"column":81}},"line":51},"11":{"name":"(anonymous_11)","decl":{"start":{"line":59,"column":36},"end":{"line":59,"column":43}},"loc":{"start":{"line":59,"column":48},"end":{"line":59,"column":87}},"line":59},"12":{"name":"(anonymous_12)","decl":{"start":{"line":61,"column":32},"end":{"line":61,"column":40}},"loc":{"start":{"line":61,"column":49},"end":{"line":61,"column":96}},"line":61}},"branchMap":{"0":{"loc":{"start":{"line":36,"column":19},"end":{"line":36,"column":null}},"type":"cond-expr","locations":[{"start":{"line":36,"column":32},"end":{"line":36,"column":68}},{"start":{"line":36,"column":68},"end":{"line":36,"column":null}}],"line":36},"1":{"loc":{"start":{"line":41,"column":23},"end":{"line":41,"column":null}},"type":"binary-expr","locations":[{"start":{"line":41,"column":23},"end":{"line":41,"column":45}},{"start":{"line":41,"column":45},"end":{"line":41,"column":null}}],"line":41},"2":{"loc":{"start":{"line":46,"column":55},"end":{"line":46,"column":92}},"type":"binary-expr","locations":[{"start":{"line":46,"column":55},"end":{"line":46,"column":88}},{"start":{"line":46,"column":88},"end":{"line":46,"column":92}}],"line":46},"3":{"loc":{"start":{"line":47,"column":51},"end":{"line":47,"column":88}},"type":"binary-expr","locations":[{"start":{"line":47,"column":51},"end":{"line":47,"column":84}},{"start":{"line":47,"column":84},"end":{"line":47,"column":88}}],"line":47},"4":{"loc":{"start":{"line":48,"column":51},"end":{"line":48,"column":88}},"type":"binary-expr","locations":[{"start":{"line":48,"column":51},"end":{"line":48,"column":84}},{"start":{"line":48,"column":84},"end":{"line":48,"column":88}}],"line":48},"5":{"loc":{"start":{"line":50,"column":25},"end":{"line":52,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":6},"end":{"line":51,"column":null}},{"start":{"line":52,"column":6},"end":{"line":52,"column":null}}],"line":50},"6":{"loc":{"start":{"line":51,"column":44},"end":{"line":51,"column":81}},"type":"binary-expr","locations":[{"start":{"line":51,"column":44},"end":{"line":51,"column":77}},{"start":{"line":51,"column":77},"end":{"line":51,"column":81}}],"line":51},"7":{"loc":{"start":{"line":54,"column":31},"end":{"line":56,"column":null}},"type":"cond-expr","locations":[{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},{"start":{"line":56,"column":6},"end":{"line":56,"column":null}}],"line":54},"8":{"loc":{"start":{"line":60,"column":24},"end":{"line":62,"column":null}},"type":"cond-expr","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":null}},{"start":{"line":62,"column":6},"end":{"line":62,"column":null}}],"line":60},"9":{"loc":{"start":{"line":61,"column":55},"end":{"line":61,"column":96}},"type":"binary-expr","locations":[{"start":{"line":61,"column":55},"end":{"line":61,"column":92}},{"start":{"line":61,"column":92},"end":{"line":61,"column":96}}],"line":61},"10":{"loc":{"start":{"line":84,"column":23},"end":{"line":84,"column":null}},"type":"binary-expr","locations":[{"start":{"line":84,"column":23},"end":{"line":84,"column":62}},{"start":{"line":84,"column":62},"end":{"line":84,"column":null}}],"line":84},"11":{"loc":{"start":{"line":85,"column":27},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":27},"end":{"line":85,"column":69}},{"start":{"line":85,"column":69},"end":{"line":85,"column":null}}],"line":85},"12":{"loc":{"start":{"line":91,"column":17},"end":{"line":91,"column":null}},"type":"cond-expr","locations":[{"start":{"line":91,"column":39},"end":{"line":91,"column":52}},{"start":{"line":91,"column":52},"end":{"line":91,"column":null}}],"line":91},"13":{"loc":{"start":{"line":93,"column":26},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":47},"end":{"line":93,"column":56}},{"start":{"line":93,"column":56},"end":{"line":93,"column":null}}],"line":93}},"s":{"0":2,"1":2,"2":1,"3":2,"4":2,"5":5,"6":5,"7":2,"8":2,"9":5,"10":2,"11":5,"12":2,"13":5,"14":2,"15":1,"16":2,"17":1,"18":2,"19":3,"20":2,"21":3,"22":2,"23":2,"24":2,"25":4,"26":2,"27":4,"28":2},"f":{"0":2,"1":1,"2":5,"3":5,"4":5,"5":5,"6":5,"7":1,"8":1,"9":3,"10":3,"11":4,"12":4},"b":{"0":[1,1],"1":[2,1],"2":[1,0],"3":[1,0],"4":[3,0],"5":[1,1],"6":[3,0],"7":[1,1],"8":[1,1],"9":[4,0],"10":[2,1],"11":[2,1],"12":[2,0],"13":[0,2]},"meta":{"lastBranch":14,"lastFunction":13,"lastStatement":29,"seen":{"f:26:22:26:44":0,"s:27:77:33:Infinity":0,"s:35:20:35:Infinity":1,"f:35:33:35:38":1,"s:35:43:35:87":2,"s:36:19:36:Infinity":3,"b:36:32:36:68:36:68:36:Infinity":0,"s:38:24:40:Infinity":4,"f:39:16:39:20":2,"s:39:25:39:42":5,"f:39:44:39:51":3,"s:39:56:39:83":6,"s:41:23:41:Infinity":7,"b:41:23:41:45:41:45:41:Infinity":1,"s:43:19:43:Infinity":8,"f:43:31:43:38":4,"s:43:43:43:66":9,"s:44:18:44:Infinity":10,"f:44:30:44:37":5,"s:44:42:44:67":11,"s:45:18:45:Infinity":12,"f:45:30:45:37":6,"s:45:42:45:64":13,"s:46:19:46:Infinity":14,"f:46:28:46:36":7,"s:46:47:46:92":15,"b:46:55:46:88:46:88:46:92":2,"s:47:16:47:Infinity":16,"f:47:24:47:32":8,"s:47:43:47:88":17,"b:47:51:47:84:47:84:47:88":3,"s:48:16:48:Infinity":18,"f:48:24:48:32":9,"s:48:43:48:88":19,"b:48:51:48:84:48:84:48:88":4,"s:50:25:52:Infinity":20,"b:51:6:51:Infinity:52:6:52:Infinity":5,"f:51:17:51:25":10,"s:51:36:51:81":21,"b:51:44:51:77:51:77:51:81":6,"s:54:31:56:Infinity":22,"b:55:6:55:Infinity:56:6:56:Infinity":7,"s:58:22:58:Infinity":23,"s:59:25:59:Infinity":24,"f:59:36:59:43":11,"s:59:48:59:87":25,"s:60:24:62:Infinity":26,"b:61:6:61:Infinity:62:6:62:Infinity":8,"f:61:32:61:40":12,"s:61:49:61:96":27,"b:61:55:61:92:61:92:61:96":9,"s:64:2:101:Infinity":28,"b:84:23:84:62:84:62:84:Infinity":10,"b:85:27:85:69:85:69:85:Infinity":11,"b:91:39:91:52:91:52:91:Infinity":12,"b:93:47:93:56:93:56:93:Infinity":13}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/parties.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/parties.ts","statementMap":{"0":{"start":{"line":27,"column":43},"end":{"line":31,"column":null}},"1":{"start":{"line":33,"column":28},"end":{"line":33,"column":null}},"2":{"start":{"line":33,"column":52},"end":{"line":33,"column":95}},"3":{"start":{"line":35,"column":45},"end":{"line":35,"column":null}},"4":{"start":{"line":36,"column":2},"end":{"line":40,"column":null}},"5":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"6":{"start":{"line":38,"column":6},"end":{"line":38,"column":null}},"7":{"start":{"line":42,"column":49},"end":{"line":42,"column":null}},"8":{"start":{"line":43,"column":2},"end":{"line":55,"column":null}},"9":{"start":{"line":44,"column":17},"end":{"line":44,"column":60}},"10":{"start":{"line":46,"column":20},"end":{"line":46,"column":null}},"11":{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},"12":{"start":{"line":53,"column":8},"end":{"line":53,"column":null}},"13":{"start":{"line":57,"column":42},"end":{"line":59,"column":null}},"14":{"start":{"line":61,"column":32},"end":{"line":90,"column":null}},"15":{"start":{"line":62,"column":18},"end":{"line":62,"column":null}},"16":{"start":{"line":63,"column":14},"end":{"line":63,"column":null}},"17":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"18":{"start":{"line":66,"column":4},"end":{"line":89,"column":null}},"19":{"start":{"line":92,"column":2},"end":{"line":92,"column":null}},"20":{"start":{"line":92,"column":19},"end":{"line":92,"column":72}},"21":{"start":{"line":94,"column":2},"end":{"line":100,"column":null}}},"fnMap":{"0":{"name":"loadPartyPerformance","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":43}},"loc":{"start":{"line":26,"column":88},"end":{"line":101,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":40},"end":{"line":33,"column":47}},"loc":{"start":{"line":33,"column":52},"end":{"line":33,"column":95}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":36,"column":10},"end":{"line":36,"column":18}},"loc":{"start":{"line":36,"column":23},"end":{"line":40,"column":3}},"line":36},"3":{"name":"(anonymous_3)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":12}},"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":60}},"line":44},"4":{"name":"(anonymous_4)","decl":{"start":{"line":45,"column":5},"end":{"line":45,"column":13}},"loc":{"start":{"line":45,"column":18},"end":{"line":55,"column":5}},"line":45},"5":{"name":"(anonymous_5)","decl":{"start":{"line":61,"column":50},"end":{"line":61,"column":54}},"loc":{"start":{"line":61,"column":59},"end":{"line":90,"column":3}},"line":61},"6":{"name":"(anonymous_6)","decl":{"start":{"line":92,"column":10},"end":{"line":92,"column":16}},"loc":{"start":{"line":92,"column":19},"end":{"line":92,"column":72}},"line":92}},"branchMap":{"0":{"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":39,"column":null}},{"start":{},"end":{}}],"line":37},"1":{"loc":{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},"type":"if","locations":[{"start":{"line":47,"column":6},"end":{"line":54,"column":null}},{"start":{},"end":{}}],"line":47},"2":{"loc":{"start":{"line":48,"column":8},"end":{"line":51,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":8},"end":{"line":48,"column":null}},{"start":{"line":49,"column":9},"end":{"line":49,"column":null}},{"start":{"line":50,"column":10},"end":{"line":50,"column":null}},{"start":{"line":51,"column":11},"end":{"line":51,"column":null}}],"line":48},"3":{"loc":{"start":{"line":63,"column":14},"end":{"line":63,"column":null}},"type":"binary-expr","locations":[{"start":{"line":63,"column":14},"end":{"line":63,"column":35}},{"start":{"line":63,"column":35},"end":{"line":63,"column":null}}],"line":63},"4":{"loc":{"start":{"line":64,"column":16},"end":{"line":64,"column":null}},"type":"binary-expr","locations":[{"start":{"line":64,"column":16},"end":{"line":64,"column":41}},{"start":{"line":64,"column":41},"end":{"line":64,"column":null}}],"line":64},"5":{"loc":{"start":{"line":68,"column":18},"end":{"line":68,"column":null}},"type":"binary-expr","locations":[{"start":{"line":68,"column":18},"end":{"line":68,"column":45}},{"start":{"line":68,"column":45},"end":{"line":68,"column":null}}],"line":68},"6":{"loc":{"start":{"line":71,"column":15},"end":{"line":71,"column":null}},"type":"binary-expr","locations":[{"start":{"line":71,"column":15},"end":{"line":71,"column":33}},{"start":{"line":71,"column":33},"end":{"line":71,"column":null}}],"line":71},"7":{"loc":{"start":{"line":73,"column":22},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":73,"column":22},"end":{"line":73,"column":53}},{"start":{"line":73,"column":53},"end":{"line":73,"column":null}}],"line":73},"8":{"loc":{"start":{"line":74,"column":28},"end":{"line":74,"column":null}},"type":"binary-expr","locations":[{"start":{"line":74,"column":28},"end":{"line":74,"column":64}},{"start":{"line":74,"column":64},"end":{"line":74,"column":null}}],"line":74},"9":{"loc":{"start":{"line":75,"column":27},"end":{"line":75,"column":null}},"type":"binary-expr","locations":[{"start":{"line":75,"column":27},"end":{"line":75,"column":61}},{"start":{"line":75,"column":61},"end":{"line":75,"column":null}}],"line":75},"10":{"loc":{"start":{"line":76,"column":22},"end":{"line":76,"column":null}},"type":"binary-expr","locations":[{"start":{"line":76,"column":22},"end":{"line":76,"column":51}},{"start":{"line":76,"column":51},"end":{"line":76,"column":null}}],"line":76},"11":{"loc":{"start":{"line":79,"column":21},"end":{"line":79,"column":null}},"type":"binary-expr","locations":[{"start":{"line":79,"column":21},"end":{"line":79,"column":59}},{"start":{"line":79,"column":59},"end":{"line":79,"column":null}}],"line":79},"12":{"loc":{"start":{"line":80,"column":24},"end":{"line":80,"column":null}},"type":"binary-expr","locations":[{"start":{"line":80,"column":24},"end":{"line":80,"column":63}},{"start":{"line":80,"column":63},"end":{"line":80,"column":null}}],"line":80},"13":{"loc":{"start":{"line":81,"column":24},"end":{"line":81,"column":null}},"type":"binary-expr","locations":[{"start":{"line":81,"column":24},"end":{"line":81,"column":55}},{"start":{"line":81,"column":55},"end":{"line":81,"column":null}}],"line":81},"14":{"loc":{"start":{"line":84,"column":24},"end":{"line":84,"column":66}},"type":"binary-expr","locations":[{"start":{"line":84,"column":24},"end":{"line":84,"column":58}},{"start":{"line":84,"column":58},"end":{"line":84,"column":66}}],"line":84},"15":{"loc":{"start":{"line":85,"column":25},"end":{"line":85,"column":76}},"type":"binary-expr","locations":[{"start":{"line":85,"column":25},"end":{"line":85,"column":68}},{"start":{"line":85,"column":68},"end":{"line":85,"column":76}}],"line":85},"16":{"loc":{"start":{"line":86,"column":27},"end":{"line":86,"column":null}},"type":"binary-expr","locations":[{"start":{"line":86,"column":27},"end":{"line":86,"column":62}},{"start":{"line":86,"column":62},"end":{"line":86,"column":96}},{"start":{"line":86,"column":96},"end":{"line":86,"column":null}}],"line":86},"17":{"loc":{"start":{"line":92,"column":26},"end":{"line":92,"column":51}},"type":"binary-expr","locations":[{"start":{"line":92,"column":26},"end":{"line":92,"column":45}},{"start":{"line":92,"column":45},"end":{"line":92,"column":51}}],"line":92},"18":{"loc":{"start":{"line":92,"column":51},"end":{"line":92,"column":72}},"type":"binary-expr","locations":[{"start":{"line":92,"column":51},"end":{"line":92,"column":70}},{"start":{"line":92,"column":70},"end":{"line":92,"column":72}}],"line":92}},"s":{"0":2,"1":2,"2":4,"3":2,"4":2,"5":3,"6":3,"7":2,"8":2,"9":4,"10":4,"11":4,"12":4,"13":2,"14":2,"15":3,"16":3,"17":3,"18":3,"19":2,"20":1,"21":2},"f":{"0":2,"1":4,"2":3,"3":4,"4":4,"5":3,"6":1},"b":{"0":[3,0],"1":[4,0],"2":[4,1,1,1],"3":[3,0],"4":[3,0],"5":[3,0],"6":[3,0],"7":[3,0],"8":[3,0],"9":[3,0],"10":[3,0],"11":[3,1],"12":[3,1],"13":[3,1],"14":[3,0],"15":[3,0],"16":[3,1,0],"17":[1,0],"18":[1,0]},"meta":{"lastBranch":19,"lastFunction":7,"lastStatement":22,"seen":{"f:26:22:26:43":0,"s:27:43:31:Infinity":0,"s:33:28:33:Infinity":1,"f:33:40:33:47":1,"s:33:52:33:95":2,"s:35:45:35:Infinity":3,"s:36:2:40:Infinity":4,"f:36:10:36:18":2,"b:37:4:39:Infinity:undefined:undefined:undefined:undefined":0,"s:37:4:39:Infinity":5,"s:38:6:38:Infinity":6,"s:42:49:42:Infinity":7,"s:43:2:55:Infinity":8,"f:44:5:44:12":3,"s:44:17:44:60":9,"f:45:5:45:13":4,"s:46:20:46:Infinity":10,"b:47:6:54:Infinity:undefined:undefined:undefined:undefined":1,"s:47:6:54:Infinity":11,"b:48:8:48:Infinity:49:9:49:Infinity:50:10:50:Infinity:51:11:51:Infinity":2,"s:53:8:53:Infinity":12,"s:57:42:59:Infinity":13,"s:61:32:90:Infinity":14,"f:61:50:61:54":5,"s:62:18:62:Infinity":15,"s:63:14:63:Infinity":16,"b:63:14:63:35:63:35:63:Infinity":3,"s:64:16:64:Infinity":17,"b:64:16:64:41:64:41:64:Infinity":4,"s:66:4:89:Infinity":18,"b:68:18:68:45:68:45:68:Infinity":5,"b:71:15:71:33:71:33:71:Infinity":6,"b:73:22:73:53:73:53:73:Infinity":7,"b:74:28:74:64:74:64:74:Infinity":8,"b:75:27:75:61:75:61:75:Infinity":9,"b:76:22:76:51:76:51:76:Infinity":10,"b:79:21:79:59:79:59:79:Infinity":11,"b:80:24:80:63:80:63:80:Infinity":12,"b:81:24:81:55:81:55:81:Infinity":13,"b:84:24:84:58:84:58:84:66":14,"b:85:25:85:68:85:68:85:76":15,"b:86:27:86:62:86:62:86:96:86:96:86:Infinity":16,"s:92:2:92:Infinity":19,"f:92:10:92:16":6,"s:92:19:92:72":20,"b:92:26:92:45:92:45:92:51":17,"b:92:51:92:70:92:70:92:72":18,"s:94:2:100:Infinity":21}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/risk.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/risk.ts","statementMap":{"0":{"start":{"line":25,"column":15},"end":{"line":25,"column":null}},"1":{"start":{"line":27,"column":40},"end":{"line":34,"column":null}},"2":{"start":{"line":28,"column":18},"end":{"line":28,"column":51}},"3":{"start":{"line":29,"column":15},"end":{"line":34,"column":6}},"4":{"start":{"line":36,"column":2},"end":{"line":42,"column":null}}},"fnMap":{"0":{"name":"loadRiskEvolution","decl":{"start":{"line":24,"column":22},"end":{"line":24,"column":40}},"loc":{"start":{"line":24,"column":91},"end":{"line":43,"column":null}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":28,"column":5},"end":{"line":28,"column":12}},"loc":{"start":{"line":28,"column":18},"end":{"line":28,"column":51}},"line":28},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":5},"end":{"line":29,"column":9}},"loc":{"start":{"line":29,"column":15},"end":{"line":34,"column":6}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":15},"end":{"line":30,"column":null}},"type":"binary-expr","locations":[{"start":{"line":30,"column":15},"end":{"line":30,"column":49}},{"start":{"line":30,"column":49},"end":{"line":30,"column":null}}],"line":30},"1":{"loc":{"start":{"line":31,"column":17},"end":{"line":31,"column":null}},"type":"binary-expr","locations":[{"start":{"line":31,"column":17},"end":{"line":31,"column":47}},{"start":{"line":31,"column":47},"end":{"line":31,"column":null}}],"line":31},"2":{"loc":{"start":{"line":32,"column":24},"end":{"line":32,"column":null}},"type":"binary-expr","locations":[{"start":{"line":32,"column":24},"end":{"line":32,"column":57}},{"start":{"line":32,"column":57},"end":{"line":32,"column":null}}],"line":32},"3":{"loc":{"start":{"line":33,"column":21},"end":{"line":33,"column":null}},"type":"binary-expr","locations":[{"start":{"line":33,"column":21},"end":{"line":33,"column":52}},{"start":{"line":33,"column":52},"end":{"line":33,"column":null}}],"line":33}},"s":{"0":2,"1":2,"2":5,"3":3,"4":2},"f":{"0":2,"1":5,"2":3},"b":{"0":[3,0],"1":[3,0],"2":[3,0],"3":[3,0]},"meta":{"lastBranch":4,"lastFunction":3,"lastStatement":5,"seen":{"f:24:22:24:40":0,"s:25:15:25:Infinity":0,"s:27:40:34:Infinity":1,"f:28:5:28:12":1,"s:28:18:28:51":2,"f:29:5:29:9":2,"s:29:15:34:6":3,"b:30:15:30:49:30:49:30:Infinity":0,"b:31:17:31:47:31:47:31:Infinity":1,"b:32:24:32:57:32:57:32:Infinity":2,"b:33:21:33:52:33:52:33:Infinity":3,"s:36:2:42:Infinity":4}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/top10.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/top10.ts","statementMap":{"0":{"start":{"line":27,"column":35},"end":{"line":30,"column":null}},"1":{"start":{"line":32,"column":42},"end":{"line":32,"column":null}},"2":{"start":{"line":33,"column":2},"end":{"line":35,"column":null}},"3":{"start":{"line":34,"column":4},"end":{"line":34,"column":null}},"4":{"start":{"line":37,"column":17},"end":{"line":40,"column":null}},"5":{"start":{"line":38,"column":19},"end":{"line":38,"column":56}},"6":{"start":{"line":39,"column":14},"end":{"line":39,"column":103}},"7":{"start":{"line":42,"column":32},"end":{"line":63,"column":null}},"8":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"9":{"start":{"line":44,"column":4},"end":{"line":62,"column":null}},"10":{"start":{"line":54,"column":45},"end":{"line":54,"column":60}},"11":{"start":{"line":65,"column":2},"end":{"line":72,"column":null}}},"fnMap":{"0":{"name":"loadTop10Influential","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":43}},"loc":{"start":{"line":26,"column":88},"end":{"line":73,"column":null}},"line":26},"1":{"name":"(anonymous_1)","decl":{"start":{"line":33,"column":14},"end":{"line":33,"column":22}},"loc":{"start":{"line":33,"column":27},"end":{"line":35,"column":3}},"line":33},"2":{"name":"(anonymous_2)","decl":{"start":{"line":38,"column":5},"end":{"line":38,"column":12}},"loc":{"start":{"line":38,"column":19},"end":{"line":38,"column":56}},"line":38},"3":{"name":"(anonymous_3)","decl":{"start":{"line":39,"column":5},"end":{"line":39,"column":11}},"loc":{"start":{"line":39,"column":14},"end":{"line":39,"column":103}},"line":39},"4":{"name":"(anonymous_4)","decl":{"start":{"line":42,"column":39},"end":{"line":42,"column":44}},"loc":{"start":{"line":42,"column":56},"end":{"line":63,"column":3}},"line":42},"5":{"name":"(anonymous_5)","decl":{"start":{"line":54,"column":21},"end":{"line":54,"column":31}},"loc":{"start":{"line":54,"column":45},"end":{"line":54,"column":60}},"line":54}},"branchMap":{"0":{"loc":{"start":{"line":39,"column":22},"end":{"line":39,"column":65}},"type":"binary-expr","locations":[{"start":{"line":39,"column":22},"end":{"line":39,"column":58}},{"start":{"line":39,"column":58},"end":{"line":39,"column":65}}],"line":39},"1":{"loc":{"start":{"line":39,"column":65},"end":{"line":39,"column":103}},"type":"binary-expr","locations":[{"start":{"line":39,"column":65},"end":{"line":39,"column":101}},{"start":{"line":39,"column":101},"end":{"line":39,"column":103}}],"line":39},"2":{"loc":{"start":{"line":43,"column":17},"end":{"line":43,"column":null}},"type":"binary-expr","locations":[{"start":{"line":43,"column":17},"end":{"line":43,"column":52}},{"start":{"line":43,"column":52},"end":{"line":43,"column":null}}],"line":43},"3":{"loc":{"start":{"line":47,"column":18},"end":{"line":47,"column":null}},"type":"binary-expr","locations":[{"start":{"line":47,"column":18},"end":{"line":47,"column":46}},{"start":{"line":47,"column":46},"end":{"line":47,"column":null}}],"line":47},"4":{"loc":{"start":{"line":48,"column":17},"end":{"line":48,"column":null}},"type":"binary-expr","locations":[{"start":{"line":48,"column":17},"end":{"line":48,"column":44}},{"start":{"line":48,"column":44},"end":{"line":48,"column":null}}],"line":48},"5":{"loc":{"start":{"line":49,"column":14},"end":{"line":49,"column":null}},"type":"binary-expr","locations":[{"start":{"line":49,"column":14},"end":{"line":49,"column":37}},{"start":{"line":49,"column":37},"end":{"line":49,"column":null}}],"line":49},"6":{"loc":{"start":{"line":50,"column":13},"end":{"line":55,"column":null}},"type":"cond-expr","locations":[{"start":{"line":51,"column":11},"end":{"line":54,"column":null}},{"start":{"line":55,"column":10},"end":{"line":55,"column":null}}],"line":50},"7":{"loc":{"start":{"line":56,"column":23},"end":{"line":56,"column":null}},"type":"binary-expr","locations":[{"start":{"line":56,"column":23},"end":{"line":56,"column":60}},{"start":{"line":56,"column":60},"end":{"line":56,"column":null}}],"line":56},"8":{"loc":{"start":{"line":57,"column":27},"end":{"line":57,"column":null}},"type":"binary-expr","locations":[{"start":{"line":57,"column":27},"end":{"line":57,"column":64}},{"start":{"line":57,"column":64},"end":{"line":57,"column":null}}],"line":57},"9":{"loc":{"start":{"line":58,"column":29},"end":{"line":58,"column":null}},"type":"binary-expr","locations":[{"start":{"line":58,"column":29},"end":{"line":58,"column":68}},{"start":{"line":58,"column":68},"end":{"line":58,"column":null}}],"line":58},"10":{"loc":{"start":{"line":59,"column":18},"end":{"line":59,"column":null}},"type":"binary-expr","locations":[{"start":{"line":59,"column":18},"end":{"line":59,"column":48}},{"start":{"line":59,"column":48},"end":{"line":59,"column":null}}],"line":59},"11":{"loc":{"start":{"line":60,"column":18},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":18},"end":{"line":60,"column":48}},{"start":{"line":60,"column":48},"end":{"line":60,"column":null}}],"line":60}},"s":{"0":2,"1":2,"2":2,"3":3,"4":2,"5":4,"6":1,"7":2,"8":3,"9":3,"10":5,"11":2},"f":{"0":2,"1":3,"2":4,"3":1,"4":3,"5":5},"b":{"0":[1,0],"1":[1,0],"2":[3,0],"3":[3,0],"4":[3,0],"5":[3,0],"6":[3,0],"7":[3,0],"8":[3,0],"9":[3,0],"10":[3,0],"11":[3,0]},"meta":{"lastBranch":12,"lastFunction":6,"lastStatement":12,"seen":{"f:26:22:26:43":0,"s:27:35:30:Infinity":0,"s:32:42:32:Infinity":1,"s:33:2:35:Infinity":2,"f:33:14:33:22":1,"s:34:4:34:Infinity":3,"s:37:17:40:Infinity":4,"f:38:5:38:12":2,"s:38:19:38:56":5,"f:39:5:39:11":3,"s:39:14:39:103":6,"b:39:22:39:58:39:58:39:65":0,"b:39:65:39:101:39:101:39:103":1,"s:42:32:63:Infinity":7,"f:42:39:42:44":4,"s:43:17:43:Infinity":8,"b:43:17:43:52:43:52:43:Infinity":2,"s:44:4:62:Infinity":9,"b:47:18:47:46:47:46:47:Infinity":3,"b:48:17:48:44:48:44:48:Infinity":4,"b:49:14:49:37:49:37:49:Infinity":5,"b:51:11:54:Infinity:55:10:55:Infinity":6,"f:54:21:54:31":5,"s:54:45:54:60":10,"b:56:23:56:60:56:60:56:Infinity":7,"b:57:27:57:64:57:64:57:Infinity":8,"b:58:29:58:68:58:68:58:Infinity":9,"b:59:18:59:48:59:48:59:Infinity":10,"b:60:18:60:48:60:48:60:Infinity":11,"s:65:2:72:Infinity":11}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/voting.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/loaders/voting.ts","statementMap":{"0":{"start":{"line":30,"column":59},"end":{"line":34,"column":null}},"1":{"start":{"line":36,"column":17},"end":{"line":36,"column":null}},"2":{"start":{"line":37,"column":21},"end":{"line":40,"column":null}},"3":{"start":{"line":42,"column":50},"end":{"line":42,"column":null}},"4":{"start":{"line":43,"column":2},"end":{"line":51,"column":null}},"5":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"6":{"start":{"line":46,"column":19},"end":{"line":46,"column":null}},"7":{"start":{"line":47,"column":19},"end":{"line":47,"column":null}},"8":{"start":{"line":48,"column":19},"end":{"line":48,"column":null}},"9":{"start":{"line":49,"column":6},"end":{"line":49,"column":null}},"10":{"start":{"line":50,"column":6},"end":{"line":50,"column":null}},"11":{"start":{"line":53,"column":27},"end":{"line":53,"column":null}},"12":{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},"13":{"start":{"line":57,"column":4},"end":{"line":62,"column":null}},"14":{"start":{"line":58,"column":6},"end":{"line":61,"column":null}},"15":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"16":{"start":{"line":59,"column":23},"end":{"line":59,"column":null}},"17":{"start":{"line":60,"column":8},"end":{"line":60,"column":null}},"18":{"start":{"line":64,"column":50},"end":{"line":64,"column":null}},"19":{"start":{"line":65,"column":4},"end":{"line":77,"column":null}},"20":{"start":{"line":66,"column":19},"end":{"line":66,"column":62}},"21":{"start":{"line":68,"column":22},"end":{"line":68,"column":null}},"22":{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},"23":{"start":{"line":75,"column":10},"end":{"line":75,"column":null}},"24":{"start":{"line":78,"column":4},"end":{"line":85,"column":null}},"25":{"start":{"line":79,"column":18},"end":{"line":79,"column":null}},"26":{"start":{"line":80,"column":6},"end":{"line":84,"column":null}},"27":{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},"28":{"start":{"line":81,"column":23},"end":{"line":81,"column":null}},"29":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"30":{"start":{"line":83,"column":8},"end":{"line":83,"column":null}},"31":{"start":{"line":88,"column":46},"end":{"line":101,"column":null}},"32":{"start":{"line":90,"column":25},"end":{"line":90,"column":null}},"33":{"start":{"line":90,"column":49},"end":{"line":90,"column":66}},"34":{"start":{"line":91,"column":23},"end":{"line":91,"column":null}},"35":{"start":{"line":91,"column":44},"end":{"line":91,"column":67}},"36":{"start":{"line":92,"column":20},"end":{"line":92,"column":null}},"37":{"start":{"line":92,"column":48},"end":{"line":92,"column":91}},"38":{"start":{"line":93,"column":24},"end":{"line":93,"column":null}},"39":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"40":{"start":{"line":95,"column":6},"end":{"line":99,"column":null}},"41":{"start":{"line":101,"column":17},"end":{"line":101,"column":36}},"42":{"start":{"line":103,"column":2},"end":{"line":114,"column":null}}},"fnMap":{"0":{"name":"loadVotingPatterns","decl":{"start":{"line":29,"column":22},"end":{"line":29,"column":41}},"loc":{"start":{"line":29,"column":84},"end":{"line":115,"column":null}},"line":29},"1":{"name":"(anonymous_1)","decl":{"start":{"line":44,"column":5},"end":{"line":44,"column":12}},"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"line":44},"2":{"name":"(anonymous_2)","decl":{"start":{"line":45,"column":5},"end":{"line":45,"column":13}},"loc":{"start":{"line":45,"column":18},"end":{"line":51,"column":5}},"line":45},"3":{"name":"(anonymous_3)","decl":{"start":{"line":57,"column":29},"end":{"line":57,"column":33}},"loc":{"start":{"line":58,"column":6},"end":{"line":61,"column":null}},"line":58},"4":{"name":"(anonymous_4)","decl":{"start":{"line":58,"column":13},"end":{"line":58,"column":17}},"loc":{"start":{"line":58,"column":23},"end":{"line":61,"column":7}},"line":58},"5":{"name":"(anonymous_5)","decl":{"start":{"line":66,"column":7},"end":{"line":66,"column":14}},"loc":{"start":{"line":66,"column":19},"end":{"line":66,"column":62}},"line":66},"6":{"name":"(anonymous_6)","decl":{"start":{"line":67,"column":7},"end":{"line":67,"column":15}},"loc":{"start":{"line":67,"column":20},"end":{"line":77,"column":7}},"line":67},"7":{"name":"(anonymous_7)","decl":{"start":{"line":78,"column":29},"end":{"line":78,"column":33}},"loc":{"start":{"line":78,"column":39},"end":{"line":85,"column":5}},"line":78},"8":{"name":"(anonymous_8)","decl":{"start":{"line":80,"column":20},"end":{"line":80,"column":24}},"loc":{"start":{"line":80,"column":30},"end":{"line":84,"column":7}},"line":80},"9":{"name":"(anonymous_9)","decl":{"start":{"line":89,"column":5},"end":{"line":89,"column":9}},"loc":{"start":{"line":89,"column":18},"end":{"line":100,"column":5}},"line":89},"10":{"name":"(anonymous_10)","decl":{"start":{"line":90,"column":37},"end":{"line":90,"column":44}},"loc":{"start":{"line":90,"column":49},"end":{"line":90,"column":66}},"line":90},"11":{"name":"(anonymous_11)","decl":{"start":{"line":91,"column":34},"end":{"line":91,"column":39}},"loc":{"start":{"line":91,"column":44},"end":{"line":91,"column":67}},"line":91},"12":{"name":"(anonymous_12)","decl":{"start":{"line":92,"column":31},"end":{"line":92,"column":39}},"loc":{"start":{"line":92,"column":48},"end":{"line":92,"column":91}},"line":92},"13":{"name":"(anonymous_13)","decl":{"start":{"line":101,"column":5},"end":{"line":101,"column":12}},"loc":{"start":{"line":101,"column":17},"end":{"line":101,"column":36}},"line":101}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":17},"end":{"line":44,"column":109}},"type":"binary-expr","locations":[{"start":{"line":44,"column":17},"end":{"line":44,"column":65}},{"start":{"line":44,"column":65},"end":{"line":44,"column":109}}],"line":44},"1":{"loc":{"start":{"line":48,"column":32},"end":{"line":48,"column":68}},"type":"binary-expr","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":63}},{"start":{"line":48,"column":63},"end":{"line":48,"column":68}}],"line":48},"2":{"loc":{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},"type":"if","locations":[{"start":{"line":56,"column":2},"end":{"line":86,"column":null}},{"start":{"line":63,"column":9},"end":{"line":86,"column":null}}],"line":56},"3":{"loc":{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":null}},{"start":{},"end":{}}],"line":59},"4":{"loc":{"start":{"line":60,"column":15},"end":{"line":60,"column":null}},"type":"binary-expr","locations":[{"start":{"line":60,"column":15},"end":{"line":60,"column":49}},{"start":{"line":60,"column":49},"end":{"line":60,"column":null}}],"line":60},"5":{"loc":{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":76,"column":null}},{"start":{},"end":{}}],"line":69},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":73,"column":null}},"type":"binary-expr","locations":[{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},{"start":{"line":71,"column":11},"end":{"line":71,"column":null}},{"start":{"line":72,"column":12},"end":{"line":72,"column":null}},{"start":{"line":73,"column":13},"end":{"line":73,"column":null}}],"line":70},"7":{"loc":{"start":{"line":79,"column":18},"end":{"line":79,"column":null}},"type":"cond-expr","locations":[{"start":{"line":79,"column":39},"end":{"line":79,"column":83}},{"start":{"line":79,"column":83},"end":{"line":79,"column":null}}],"line":79},"8":{"loc":{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},"type":"if","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":null}},{"start":{},"end":{}}],"line":81},"9":{"loc":{"start":{"line":82,"column":20},"end":{"line":82,"column":null}},"type":"cond-expr","locations":[{"start":{"line":82,"column":41},"end":{"line":82,"column":85}},{"start":{"line":82,"column":85},"end":{"line":82,"column":null}}],"line":82},"10":{"loc":{"start":{"line":92,"column":54},"end":{"line":92,"column":91}},"type":"binary-expr","locations":[{"start":{"line":92,"column":54},"end":{"line":92,"column":87}},{"start":{"line":92,"column":87},"end":{"line":92,"column":91}}],"line":92},"11":{"loc":{"start":{"line":93,"column":24},"end":{"line":93,"column":null}},"type":"cond-expr","locations":[{"start":{"line":93,"column":36},"end":{"line":93,"column":75}},{"start":{"line":93,"column":75},"end":{"line":93,"column":null}}],"line":93},"12":{"loc":{"start":{"line":94,"column":28},"end":{"line":94,"column":null}},"type":"cond-expr","locations":[{"start":{"line":94,"column":40},"end":{"line":94,"column":90}},{"start":{"line":94,"column":90},"end":{"line":94,"column":null}}],"line":94},"13":{"loc":{"start":{"line":98,"column":15},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":36},"end":{"line":98,"column":51}},{"start":{"line":98,"column":51},"end":{"line":98,"column":null}}],"line":98},"14":{"loc":{"start":{"line":98,"column":51},"end":{"line":98,"column":null}},"type":"cond-expr","locations":[{"start":{"line":98,"column":72},"end":{"line":98,"column":83}},{"start":{"line":98,"column":83},"end":{"line":98,"column":null}}],"line":98},"15":{"loc":{"start":{"line":105,"column":17},"end":{"line":107,"column":null}},"type":"cond-expr","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":null}},{"start":{"line":107,"column":8},"end":{"line":107,"column":null}}],"line":105}},"s":{"0":3,"1":3,"2":3,"3":3,"4":3,"5":3,"6":3,"7":3,"8":3,"9":3,"10":3,"11":3,"12":3,"13":2,"14":16,"15":128,"16":16,"17":112,"18":1,"19":1,"20":2,"21":2,"22":2,"23":2,"24":1,"25":8,"26":8,"27":64,"28":8,"29":56,"30":64,"31":3,"32":24,"33":32,"34":24,"35":2,"36":24,"37":4,"38":24,"39":24,"40":24,"41":24,"42":3},"f":{"0":3,"1":3,"2":3,"3":16,"4":128,"5":2,"6":2,"7":8,"8":64,"9":24,"10":32,"11":2,"12":4,"13":24},"b":{"0":[3,3],"1":[3,0],"2":[2,1],"3":[16,112],"4":[112,106],"5":[2,0],"6":[2,0,0,0],"7":[2,6],"8":[8,56],"9":[14,42],"10":[4,0],"11":[2,22],"12":[2,22],"13":[0,24],"14":[0,24],"15":[2,1]},"meta":{"lastBranch":16,"lastFunction":14,"lastStatement":43,"seen":{"f:29:22:29:41":0,"s:30:59:34:Infinity":0,"s:36:17:36:Infinity":1,"s:37:21:40:Infinity":2,"s:42:50:42:Infinity":3,"s:43:2:51:Infinity":4,"f:44:5:44:12":1,"s:44:17:44:109":5,"b:44:17:44:65:44:65:44:109":0,"f:45:5:45:13":2,"s:46:19:46:Infinity":6,"s:47:19:47:Infinity":7,"s:48:19:48:Infinity":8,"b:48:32:48:63:48:63:48:68":1,"s:49:6:49:Infinity":9,"s:50:6:50:Infinity":10,"s:53:27:53:Infinity":11,"b:56:2:86:Infinity:63:9:86:Infinity":2,"s:56:2:86:Infinity":12,"s:57:4:62:Infinity":13,"f:57:29:57:33":3,"s:58:6:61:Infinity":14,"f:58:13:58:17":4,"b:59:8:59:Infinity:undefined:undefined:undefined:undefined":3,"s:59:8:59:Infinity":15,"s:59:23:59:Infinity":16,"s:60:8:60:Infinity":17,"b:60:15:60:49:60:49:60:Infinity":4,"s:64:50:64:Infinity":18,"s:65:4:77:Infinity":19,"f:66:7:66:14":5,"s:66:19:66:62":20,"f:67:7:67:15":6,"s:68:22:68:Infinity":21,"b:69:8:76:Infinity:undefined:undefined:undefined:undefined":5,"s:69:8:76:Infinity":22,"b:70:10:70:Infinity:71:11:71:Infinity:72:12:72:Infinity:73:13:73:Infinity":6,"s:75:10:75:Infinity":23,"s:78:4:85:Infinity":24,"f:78:29:78:33":7,"s:79:18:79:Infinity":25,"b:79:39:79:83:79:83:79:Infinity":7,"s:80:6:84:Infinity":26,"f:80:20:80:24":8,"b:81:8:81:Infinity:undefined:undefined:undefined:undefined":8,"s:81:8:81:Infinity":27,"s:81:23:81:Infinity":28,"s:82:20:82:Infinity":29,"b:82:41:82:85:82:85:82:Infinity":9,"s:83:8:83:Infinity":30,"s:88:46:101:Infinity":31,"f:89:5:89:9":9,"s:90:25:90:Infinity":32,"f:90:37:90:44":10,"s:90:49:90:66":33,"s:91:23:91:Infinity":34,"f:91:34:91:39":11,"s:91:44:91:67":35,"s:92:20:92:Infinity":36,"f:92:31:92:39":12,"s:92:48:92:91":37,"b:92:54:92:87:92:87:92:91":10,"s:93:24:93:Infinity":38,"b:93:36:93:75:93:75:93:Infinity":11,"s:94:28:94:Infinity":39,"b:94:40:94:90:94:90:94:Infinity":12,"s:95:6:99:Infinity":40,"b:98:36:98:51:98:51:98:Infinity":13,"b:98:72:98:83:98:83:98:Infinity":14,"f:101:5:101:12":13,"s:101:17:101:36":41,"s:103:2:114:Infinity":42,"b:106:8:106:Infinity:107:8:107:Infinity":15}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/lazy-loader.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/lazy-loader.ts","statementMap":{"0":{"start":{"line":35,"column":36},"end":{"line":35,"column":null}},"1":{"start":{"line":48,"column":35},"end":{"line":48,"column":null}},"2":{"start":{"line":51,"column":33},"end":{"line":51,"column":null}},"3":{"start":{"line":70,"column":36},"end":{"line":70,"column":null}},"4":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"5":{"start":{"line":80,"column":19},"end":{"line":80,"column":null}},"6":{"start":{"line":81,"column":16},"end":{"line":81,"column":null}},"7":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"8":{"start":{"line":82,"column":14},"end":{"line":82,"column":null}},"9":{"start":{"line":83,"column":16},"end":{"line":83,"column":null}},"10":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"11":{"start":{"line":84,"column":14},"end":{"line":84,"column":null}},"12":{"start":{"line":85,"column":16},"end":{"line":85,"column":null}},"13":{"start":{"line":86,"column":2},"end":{"line":86,"column":null}},"14":{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},"15":{"start":{"line":118,"column":4},"end":{"line":134,"column":null}},"16":{"start":{"line":119,"column":17},"end":{"line":119,"column":null}},"17":{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},"18":{"start":{"line":121,"column":8},"end":{"line":121,"column":null}},"19":{"start":{"line":122,"column":8},"end":{"line":122,"column":null}},"20":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"21":{"start":{"line":125,"column":6},"end":{"line":133,"column":null}},"22":{"start":{"line":126,"column":20},"end":{"line":126,"column":28}},"23":{"start":{"line":128,"column":10},"end":{"line":128,"column":null}},"24":{"start":{"line":131,"column":10},"end":{"line":131,"column":null}},"25":{"start":{"line":132,"column":10},"end":{"line":132,"column":null}},"26":{"start":{"line":135,"column":4},"end":{"line":135,"column":null}},"27":{"start":{"line":138,"column":18},"end":{"line":138,"column":null}},"28":{"start":{"line":140,"column":19},"end":{"line":164,"column":null}},"29":{"start":{"line":141,"column":4},"end":{"line":163,"column":null}},"30":{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},"31":{"start":{"line":142,"column":33},"end":{"line":142,"column":null}},"32":{"start":{"line":144,"column":17},"end":{"line":144,"column":null}},"33":{"start":{"line":145,"column":6},"end":{"line":145,"column":null}},"34":{"start":{"line":147,"column":23},"end":{"line":147,"column":null}},"35":{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},"36":{"start":{"line":148,"column":21},"end":{"line":148,"column":null}},"37":{"start":{"line":149,"column":6},"end":{"line":149,"column":null}},"38":{"start":{"line":151,"column":6},"end":{"line":151,"column":null}},"39":{"start":{"line":153,"column":6},"end":{"line":162,"column":null}},"40":{"start":{"line":154,"column":20},"end":{"line":154,"column":30}},"41":{"start":{"line":156,"column":10},"end":{"line":156,"column":null}},"42":{"start":{"line":157,"column":10},"end":{"line":157,"column":null}},"43":{"start":{"line":160,"column":10},"end":{"line":160,"column":null}},"44":{"start":{"line":161,"column":10},"end":{"line":161,"column":null}},"45":{"start":{"line":166,"column":2},"end":{"line":174,"column":null}},"46":{"start":{"line":167,"column":15},"end":{"line":167,"column":null}},"47":{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},"48":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"49":{"start":{"line":170,"column":6},"end":{"line":170,"column":null}},"50":{"start":{"line":172,"column":4},"end":{"line":172,"column":null}},"51":{"start":{"line":173,"column":4},"end":{"line":173,"column":null}},"52":{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},"53":{"start":{"line":187,"column":25},"end":{"line":187,"column":null}},"54":{"start":{"line":188,"column":4},"end":{"line":210,"column":null}},"55":{"start":{"line":189,"column":6},"end":{"line":209,"column":null}},"56":{"start":{"line":190,"column":22},"end":{"line":190,"column":null}},"57":{"start":{"line":191,"column":31},"end":{"line":191,"column":null}},"58":{"start":{"line":192,"column":27},"end":{"line":192,"column":null}},"59":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"60":{"start":{"line":193,"column":25},"end":{"line":193,"column":null}},"61":{"start":{"line":195,"column":8},"end":{"line":195,"column":null}},"62":{"start":{"line":196,"column":8},"end":{"line":196,"column":null}},"63":{"start":{"line":198,"column":8},"end":{"line":198,"column":null}},"64":{"start":{"line":199,"column":8},"end":{"line":208,"column":null}},"65":{"start":{"line":200,"column":22},"end":{"line":200,"column":32}},"66":{"start":{"line":202,"column":12},"end":{"line":202,"column":null}},"67":{"start":{"line":203,"column":12},"end":{"line":203,"column":null}},"68":{"start":{"line":206,"column":12},"end":{"line":206,"column":null}},"69":{"start":{"line":207,"column":12},"end":{"line":207,"column":null}},"70":{"start":{"line":213,"column":2},"end":{"line":213,"column":null}}},"fnMap":{"0":{"name":"parseRootMarginPx","decl":{"start":{"line":79,"column":16},"end":{"line":79,"column":34}},"loc":{"start":{"line":79,"column":74},"end":{"line":87,"column":null}},"line":79},"1":{"name":"initLazyDashboards","decl":{"start":{"line":110,"column":16},"end":{"line":110,"column":null}},"loc":{"start":{"line":116,"column":36},"end":{"line":214,"column":null}},"line":116},"2":{"name":"(anonymous_2)","decl":{"start":{"line":126,"column":9},"end":{"line":126,"column":20}},"loc":{"start":{"line":126,"column":20},"end":{"line":126,"column":28}},"line":126},"3":{"name":"(anonymous_3)","decl":{"start":{"line":127,"column":9},"end":{"line":127,"column":20}},"loc":{"start":{"line":127,"column":20},"end":{"line":129,"column":9}},"line":127},"4":{"name":"(anonymous_4)","decl":{"start":{"line":130,"column":9},"end":{"line":130,"column":16}},"loc":{"start":{"line":130,"column":33},"end":{"line":133,"column":9}},"line":130},"5":{"name":"(anonymous_5)","decl":{"start":{"line":140,"column":23},"end":{"line":140,"column":45}},"loc":{"start":{"line":140,"column":86},"end":{"line":164,"column":5}},"line":140},"6":{"name":"(anonymous_6)","decl":{"start":{"line":154,"column":9},"end":{"line":154,"column":20}},"loc":{"start":{"line":154,"column":20},"end":{"line":154,"column":30}},"line":154},"7":{"name":"(anonymous_7)","decl":{"start":{"line":155,"column":9},"end":{"line":155,"column":20}},"loc":{"start":{"line":155,"column":20},"end":{"line":158,"column":9}},"line":155},"8":{"name":"(anonymous_8)","decl":{"start":{"line":159,"column":9},"end":{"line":159,"column":16}},"loc":{"start":{"line":159,"column":33},"end":{"line":162,"column":9}},"line":159},"9":{"name":"(anonymous_9)","decl":{"start":{"line":188,"column":11},"end":{"line":188,"column":39}},"loc":{"start":{"line":188,"column":39},"end":{"line":210,"column":5}},"line":188},"10":{"name":"(anonymous_10)","decl":{"start":{"line":200,"column":11},"end":{"line":200,"column":22}},"loc":{"start":{"line":200,"column":22},"end":{"line":200,"column":32}},"line":200},"11":{"name":"(anonymous_11)","decl":{"start":{"line":201,"column":11},"end":{"line":201,"column":22}},"loc":{"start":{"line":201,"column":22},"end":{"line":204,"column":11}},"line":201},"12":{"name":"(anonymous_12)","decl":{"start":{"line":205,"column":11},"end":{"line":205,"column":18}},"loc":{"start":{"line":205,"column":35},"end":{"line":208,"column":11}},"line":205}},"branchMap":{"0":{"loc":{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":2},"end":{"line":80,"column":null}},{"start":{},"end":{}}],"line":80},"1":{"loc":{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},"type":"if","locations":[{"start":{"line":82,"column":2},"end":{"line":82,"column":null}},{"start":{},"end":{}}],"line":82},"2":{"loc":{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},"type":"if","locations":[{"start":{"line":84,"column":2},"end":{"line":84,"column":null}},{"start":{},"end":{}}],"line":84},"3":{"loc":{"start":{"line":86,"column":9},"end":{"line":86,"column":null}},"type":"cond-expr","locations":[{"start":{"line":86,"column":34},"end":{"line":86,"column":42}},{"start":{"line":86,"column":42},"end":{"line":86,"column":null}}],"line":86},"4":{"loc":{"start":{"line":112,"column":2},"end":{"line":115,"column":null}},"type":"default-arg","locations":[{"start":{"line":112,"column":38},"end":{"line":115,"column":null}}],"line":112},"5":{"loc":{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":2},"end":{"line":136,"column":null}},{"start":{},"end":{}}],"line":117},"6":{"loc":{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":120,"column":6},"end":{"line":123,"column":null}},{"start":{},"end":{}}],"line":120},"7":{"loc":{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},"type":"if","locations":[{"start":{"line":142,"column":6},"end":{"line":142,"column":null}},{"start":{},"end":{}}],"line":142},"8":{"loc":{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},"type":"if","locations":[{"start":{"line":148,"column":6},"end":{"line":148,"column":null}},{"start":{},"end":{}}],"line":148},"9":{"loc":{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},"type":"if","locations":[{"start":{"line":168,"column":4},"end":{"line":171,"column":null}},{"start":{},"end":{}}],"line":168},"10":{"loc":{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},"type":"if","locations":[{"start":{"line":186,"column":2},"end":{"line":211,"column":null}},{"start":{},"end":{}}],"line":186},"11":{"loc":{"start":{"line":186,"column":6},"end":{"line":186,"column":91}},"type":"binary-expr","locations":[{"start":{"line":186,"column":6},"end":{"line":186,"column":39}},{"start":{"line":186,"column":39},"end":{"line":186,"column":91}}],"line":186},"12":{"loc":{"start":{"line":191,"column":31},"end":{"line":191,"column":null}},"type":"binary-expr","locations":[{"start":{"line":191,"column":31},"end":{"line":191,"column":53}},{"start":{"line":191,"column":53},"end":{"line":191,"column":94}},{"start":{"line":191,"column":94},"end":{"line":191,"column":null}}],"line":191},"13":{"loc":{"start":{"line":192,"column":27},"end":{"line":192,"column":null}},"type":"binary-expr","locations":[{"start":{"line":192,"column":27},"end":{"line":192,"column":59}},{"start":{"line":192,"column":59},"end":{"line":192,"column":null}}],"line":192},"14":{"loc":{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},"type":"if","locations":[{"start":{"line":193,"column":8},"end":{"line":193,"column":null}},{"start":{},"end":{}}],"line":193}},"s":{"0":2,"1":2,"2":2,"3":2,"4":24,"5":2,"6":22,"7":22,"8":0,"9":22,"10":22,"11":3,"12":19,"13":19,"14":21,"15":6,"16":6,"17":6,"18":2,"19":2,"20":4,"21":4,"22":4,"23":3,"24":1,"25":1,"26":6,"27":15,"28":15,"29":11,"30":11,"31":1,"32":10,"33":10,"34":10,"35":10,"36":1,"37":9,"38":9,"39":9,"40":9,"41":7,"42":7,"43":2,"44":2,"45":15,"46":28,"47":28,"48":13,"49":13,"50":15,"51":15,"52":15,"53":15,"54":15,"55":15,"56":6,"57":6,"58":6,"59":6,"60":0,"61":6,"62":6,"63":6,"64":6,"65":6,"66":6,"67":6,"68":0,"69":0,"70":15},"f":{"0":24,"1":21,"2":4,"3":3,"4":1,"5":11,"6":9,"7":7,"8":2,"9":15,"10":6,"11":6,"12":0},"b":{"0":[2,22],"1":[0,22],"2":[3,19],"3":[19,0],"4":[21],"5":[6,15],"6":[2,4],"7":[1,10],"8":[1,9],"9":[13,15],"10":[15,0],"11":[15,15],"12":[6,0,0],"13":[6,6],"14":[0,6]},"meta":{"lastBranch":15,"lastFunction":13,"lastStatement":71,"seen":{"s:35:36:35:Infinity":0,"s:48:35:48:Infinity":1,"s:51:33:51:Infinity":2,"s:70:36:70:Infinity":3,"f:79:16:79:34":0,"b:80:2:80:Infinity:undefined:undefined:undefined:undefined":0,"s:80:2:80:Infinity":4,"s:80:19:80:Infinity":5,"s:81:16:81:Infinity":6,"b:82:2:82:Infinity:undefined:undefined:undefined:undefined":1,"s:82:2:82:Infinity":7,"s:82:14:82:Infinity":8,"s:83:16:83:Infinity":9,"b:84:2:84:Infinity:undefined:undefined:undefined:undefined":2,"s:84:2:84:Infinity":10,"s:84:14:84:Infinity":11,"s:85:16:85:Infinity":12,"s:86:2:86:Infinity":13,"b:86:34:86:42:86:42:86:Infinity":3,"f:110:16:110:Infinity":1,"b:112:38:115:Infinity":4,"b:117:2:136:Infinity:undefined:undefined:undefined:undefined":5,"s:117:2:136:Infinity":14,"s:118:4:134:Infinity":15,"s:119:17:119:Infinity":16,"b:120:6:123:Infinity:undefined:undefined:undefined:undefined":6,"s:120:6:123:Infinity":17,"s:121:8:121:Infinity":18,"s:122:8:122:Infinity":19,"s:124:6:124:Infinity":20,"s:125:6:133:Infinity":21,"f:126:9:126:20":2,"s:126:20:126:28":22,"f:127:9:127:20":3,"s:128:10:128:Infinity":23,"f:130:9:130:16":4,"s:131:10:131:Infinity":24,"s:132:10:132:Infinity":25,"s:135:4:135:Infinity":26,"s:138:18:138:Infinity":27,"s:140:19:164:Infinity":28,"f:140:23:140:45":5,"s:141:4:163:Infinity":29,"b:142:6:142:Infinity:undefined:undefined:undefined:undefined":7,"s:142:6:142:Infinity":30,"s:142:33:142:Infinity":31,"s:144:17:144:Infinity":32,"s:145:6:145:Infinity":33,"s:147:23:147:Infinity":34,"b:148:6:148:Infinity:undefined:undefined:undefined:undefined":8,"s:148:6:148:Infinity":35,"s:148:21:148:Infinity":36,"s:149:6:149:Infinity":37,"s:151:6:151:Infinity":38,"s:153:6:162:Infinity":39,"f:154:9:154:20":6,"s:154:20:154:30":40,"f:155:9:155:20":7,"s:156:10:156:Infinity":41,"s:157:10:157:Infinity":42,"f:159:9:159:16":8,"s:160:10:160:Infinity":43,"s:161:10:161:Infinity":44,"s:166:2:174:Infinity":45,"s:167:15:167:Infinity":46,"b:168:4:171:Infinity:undefined:undefined:undefined:undefined":9,"s:168:4:171:Infinity":47,"s:169:6:169:Infinity":48,"s:170:6:170:Infinity":49,"s:172:4:172:Infinity":50,"s:173:4:173:Infinity":51,"b:186:2:211:Infinity:undefined:undefined:undefined:undefined":10,"s:186:2:211:Infinity":52,"b:186:6:186:39:186:39:186:91":11,"s:187:25:187:Infinity":53,"s:188:4:210:Infinity":54,"f:188:11:188:39":9,"s:189:6:209:Infinity":55,"s:190:22:190:Infinity":56,"s:191:31:191:Infinity":57,"b:191:31:191:53:191:53:191:94:191:94:191:Infinity":12,"s:192:27:192:Infinity":58,"b:192:27:192:59:192:59:192:Infinity":13,"b:193:8:193:Infinity:undefined:undefined:undefined:undefined":14,"s:193:8:193:Infinity":59,"s:193:25:193:Infinity":60,"s:195:8:195:Infinity":61,"s:196:8:196:Infinity":62,"s:198:8:198:Infinity":63,"s:199:8:208:Infinity":64,"f:200:11:200:22":10,"s:200:22:200:32":65,"f:201:11:201:22":11,"s:202:12:202:Infinity":66,"s:203:12:203:Infinity":67,"f:205:11:205:18":12,"s:206:12:206:Infinity":68,"s:207:12:207:Infinity":69,"s:213:2:213:Infinity":70}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/visualizations.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/visualizations.ts","statementMap":{"0":{"start":{"line":45,"column":15},"end":{"line":45,"column":null}},"1":{"start":{"line":76,"column":44},"end":{"line":76,"column":null}},"2":{"start":{"line":79,"column":4},"end":{"line":79,"column":null}},"3":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"4":{"start":{"line":85,"column":25},"end":{"line":85,"column":null}},"5":{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},"6":{"start":{"line":88,"column":6},"end":{"line":88,"column":null}},"7":{"start":{"line":89,"column":6},"end":{"line":89,"column":null}},"8":{"start":{"line":92,"column":23},"end":{"line":92,"column":null}},"9":{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},"10":{"start":{"line":94,"column":6},"end":{"line":94,"column":null}},"11":{"start":{"line":96,"column":27},"end":{"line":96,"column":null}},"12":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"13":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"14":{"start":{"line":100,"column":24},"end":{"line":100,"column":null}},"15":{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},"16":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"17":{"start":{"line":104,"column":29},"end":{"line":104,"column":null}},"18":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"19":{"start":{"line":106,"column":6},"end":{"line":106,"column":null}},"20":{"start":{"line":109,"column":26},"end":{"line":109,"column":null}},"21":{"start":{"line":110,"column":28},"end":{"line":110,"column":null}},"22":{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},"23":{"start":{"line":112,"column":6},"end":{"line":112,"column":null}},"24":{"start":{"line":114,"column":25},"end":{"line":114,"column":null}},"25":{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},"26":{"start":{"line":116,"column":6},"end":{"line":116,"column":null}},"27":{"start":{"line":118,"column":25},"end":{"line":118,"column":null}},"28":{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},"29":{"start":{"line":120,"column":6},"end":{"line":120,"column":null}},"30":{"start":{"line":126,"column":26},"end":{"line":126,"column":null}},"31":{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},"32":{"start":{"line":129,"column":6},"end":{"line":129,"column":null}},"33":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"34":{"start":{"line":133,"column":21},"end":{"line":133,"column":null}},"35":{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},"36":{"start":{"line":135,"column":30},"end":{"line":137,"column":null}},"37":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"38":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"39":{"start":{"line":139,"column":8},"end":{"line":139,"column":null}},"40":{"start":{"line":142,"column":6},"end":{"line":195,"column":null}},"41":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"42":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"43":{"start":{"line":198,"column":24},"end":{"line":198,"column":null}},"44":{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},"45":{"start":{"line":200,"column":29},"end":{"line":206,"column":null}},"46":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"47":{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},"48":{"start":{"line":208,"column":8},"end":{"line":208,"column":null}},"49":{"start":{"line":211,"column":6},"end":{"line":264,"column":null}},"50":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"51":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"52":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"53":{"start":{"line":270,"column":22},"end":{"line":270,"column":null}},"54":{"start":{"line":271,"column":22},"end":{"line":271,"column":null}},"55":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"56":{"start":{"line":273,"column":20},"end":{"line":273,"column":null}},"57":{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},"58":{"start":{"line":276,"column":6},"end":{"line":276,"column":null}},"59":{"start":{"line":277,"column":6},"end":{"line":277,"column":null}},"60":{"start":{"line":280,"column":4},"end":{"line":280,"column":null}},"61":{"start":{"line":281,"column":21},"end":{"line":281,"column":null}},"62":{"start":{"line":283,"column":4},"end":{"line":333,"column":null}},"63":{"start":{"line":284,"column":19},"end":{"line":284,"column":null}},"64":{"start":{"line":285,"column":6},"end":{"line":285,"column":null}},"65":{"start":{"line":287,"column":21},"end":{"line":287,"column":null}},"66":{"start":{"line":288,"column":6},"end":{"line":288,"column":null}},"67":{"start":{"line":289,"column":6},"end":{"line":289,"column":null}},"68":{"start":{"line":291,"column":19},"end":{"line":291,"column":null}},"69":{"start":{"line":292,"column":6},"end":{"line":292,"column":null}},"70":{"start":{"line":294,"column":19},"end":{"line":294,"column":null}},"71":{"start":{"line":295,"column":6},"end":{"line":295,"column":null}},"72":{"start":{"line":296,"column":6},"end":{"line":296,"column":null}},"73":{"start":{"line":298,"column":20},"end":{"line":298,"column":null}},"74":{"start":{"line":299,"column":6},"end":{"line":299,"column":null}},"75":{"start":{"line":300,"column":6},"end":{"line":300,"column":null}},"76":{"start":{"line":302,"column":19},"end":{"line":302,"column":null}},"77":{"start":{"line":303,"column":6},"end":{"line":303,"column":null}},"78":{"start":{"line":304,"column":6},"end":{"line":304,"column":null}},"79":{"start":{"line":306,"column":6},"end":{"line":306,"column":null}},"80":{"start":{"line":307,"column":6},"end":{"line":307,"column":null}},"81":{"start":{"line":308,"column":6},"end":{"line":308,"column":null}},"82":{"start":{"line":310,"column":20},"end":{"line":310,"column":null}},"83":{"start":{"line":311,"column":6},"end":{"line":311,"column":null}},"84":{"start":{"line":313,"column":25},"end":{"line":313,"column":null}},"85":{"start":{"line":314,"column":6},"end":{"line":314,"column":null}},"86":{"start":{"line":316,"column":8},"end":{"line":318,"column":null}},"87":{"start":{"line":319,"column":6},"end":{"line":319,"column":null}},"88":{"start":{"line":321,"column":25},"end":{"line":321,"column":null}},"89":{"start":{"line":322,"column":6},"end":{"line":322,"column":null}},"90":{"start":{"line":323,"column":6},"end":{"line":323,"column":null}},"91":{"start":{"line":325,"column":6},"end":{"line":325,"column":null}},"92":{"start":{"line":326,"column":6},"end":{"line":326,"column":null}},"93":{"start":{"line":328,"column":6},"end":{"line":328,"column":null}},"94":{"start":{"line":329,"column":6},"end":{"line":329,"column":null}},"95":{"start":{"line":330,"column":6},"end":{"line":330,"column":null}},"96":{"start":{"line":332,"column":6},"end":{"line":332,"column":null}},"97":{"start":{"line":335,"column":4},"end":{"line":335,"column":null}},"98":{"start":{"line":340,"column":31},"end":{"line":340,"column":null}},"99":{"start":{"line":341,"column":16},"end":{"line":341,"column":null}},"100":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},"101":{"start":{"line":343,"column":46},"end":{"line":343,"column":null}},"102":{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},"103":{"start":{"line":352,"column":6},"end":{"line":352,"column":null}},"104":{"start":{"line":353,"column":6},"end":{"line":353,"column":null}},"105":{"start":{"line":356,"column":19},"end":{"line":356,"column":null}},"106":{"start":{"line":358,"column":4},"end":{"line":389,"column":null}},"107":{"start":{"line":362,"column":76},"end":{"line":367,"column":10}},"108":{"start":{"line":394,"column":27},"end":{"line":394,"column":null}},"109":{"start":{"line":395,"column":22},"end":{"line":395,"column":null}},"110":{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},"111":{"start":{"line":397,"column":20},"end":{"line":397,"column":null}},"112":{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},"113":{"start":{"line":400,"column":6},"end":{"line":400,"column":null}},"114":{"start":{"line":401,"column":6},"end":{"line":401,"column":null}},"115":{"start":{"line":404,"column":4},"end":{"line":404,"column":null}},"116":{"start":{"line":405,"column":21},"end":{"line":405,"column":null}},"117":{"start":{"line":407,"column":4},"end":{"line":472,"column":null}},"118":{"start":{"line":408,"column":19},"end":{"line":408,"column":null}},"119":{"start":{"line":409,"column":6},"end":{"line":409,"column":null}},"120":{"start":{"line":411,"column":21},"end":{"line":411,"column":null}},"121":{"start":{"line":412,"column":6},"end":{"line":412,"column":null}},"122":{"start":{"line":413,"column":6},"end":{"line":413,"column":null}},"123":{"start":{"line":415,"column":20},"end":{"line":415,"column":null}},"124":{"start":{"line":416,"column":6},"end":{"line":416,"column":null}},"125":{"start":{"line":418,"column":12},"end":{"line":433,"column":null}},"126":{"start":{"line":419,"column":21},"end":{"line":419,"column":null}},"127":{"start":{"line":420,"column":8},"end":{"line":420,"column":null}},"128":{"start":{"line":422,"column":26},"end":{"line":422,"column":null}},"129":{"start":{"line":423,"column":8},"end":{"line":423,"column":null}},"130":{"start":{"line":424,"column":8},"end":{"line":424,"column":null}},"131":{"start":{"line":426,"column":26},"end":{"line":426,"column":null}},"132":{"start":{"line":427,"column":8},"end":{"line":427,"column":null}},"133":{"start":{"line":428,"column":8},"end":{"line":428,"column":null}},"134":{"start":{"line":430,"column":8},"end":{"line":430,"column":null}},"135":{"start":{"line":431,"column":8},"end":{"line":431,"column":null}},"136":{"start":{"line":432,"column":8},"end":{"line":432,"column":null}},"137":{"start":{"line":436,"column":8},"end":{"line":436,"column":null}},"138":{"start":{"line":438,"column":8},"end":{"line":440,"column":null}},"139":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"140":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"141":{"start":{"line":446,"column":6},"end":{"line":446,"column":null}},"142":{"start":{"line":447,"column":6},"end":{"line":447,"column":null}},"143":{"start":{"line":448,"column":6},"end":{"line":448,"column":null}},"144":{"start":{"line":449,"column":6},"end":{"line":449,"column":null}},"145":{"start":{"line":451,"column":21},"end":{"line":451,"column":null}},"146":{"start":{"line":452,"column":6},"end":{"line":452,"column":null}},"147":{"start":{"line":454,"column":28},"end":{"line":454,"column":null}},"148":{"start":{"line":455,"column":6},"end":{"line":455,"column":null}},"149":{"start":{"line":456,"column":6},"end":{"line":456,"column":null}},"150":{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},"151":{"start":{"line":459,"column":8},"end":{"line":464,"column":null}},"152":{"start":{"line":460,"column":22},"end":{"line":460,"column":null}},"153":{"start":{"line":461,"column":10},"end":{"line":461,"column":null}},"154":{"start":{"line":462,"column":10},"end":{"line":462,"column":null}},"155":{"start":{"line":463,"column":10},"end":{"line":463,"column":null}},"156":{"start":{"line":467,"column":6},"end":{"line":467,"column":null}},"157":{"start":{"line":468,"column":6},"end":{"line":468,"column":null}},"158":{"start":{"line":469,"column":6},"end":{"line":469,"column":null}},"159":{"start":{"line":471,"column":6},"end":{"line":471,"column":null}},"160":{"start":{"line":474,"column":4},"end":{"line":474,"column":null}},"161":{"start":{"line":476,"column":23},"end":{"line":476,"column":null}},"162":{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},"163":{"start":{"line":478,"column":6},"end":{"line":478,"column":null}},"164":{"start":{"line":480,"column":21},"end":{"line":480,"column":null}},"165":{"start":{"line":482,"column":17},"end":{"line":482,"column":null}},"166":{"start":{"line":483,"column":21},"end":{"line":483,"column":null}},"167":{"start":{"line":484,"column":6},"end":{"line":484,"column":null}},"168":{"start":{"line":485,"column":6},"end":{"line":485,"column":null}},"169":{"start":{"line":486,"column":6},"end":{"line":490,"column":null}},"170":{"start":{"line":492,"column":17},"end":{"line":492,"column":null}},"171":{"start":{"line":493,"column":6},"end":{"line":493,"column":null}},"172":{"start":{"line":495,"column":6},"end":{"line":495,"column":null}},"173":{"start":{"line":496,"column":6},"end":{"line":496,"column":null}},"174":{"start":{"line":497,"column":6},"end":{"line":497,"column":null}},"175":{"start":{"line":503,"column":25},"end":{"line":503,"column":null}},"176":{"start":{"line":504,"column":22},"end":{"line":504,"column":null}},"177":{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},"178":{"start":{"line":506,"column":20},"end":{"line":506,"column":null}},"179":{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},"180":{"start":{"line":509,"column":6},"end":{"line":509,"column":null}},"181":{"start":{"line":510,"column":6},"end":{"line":510,"column":null}},"182":{"start":{"line":513,"column":4},"end":{"line":513,"column":null}},"183":{"start":{"line":514,"column":21},"end":{"line":514,"column":null}},"184":{"start":{"line":516,"column":4},"end":{"line":559,"column":null}},"185":{"start":{"line":517,"column":19},"end":{"line":517,"column":null}},"186":{"start":{"line":518,"column":6},"end":{"line":518,"column":null}},"187":{"start":{"line":520,"column":21},"end":{"line":520,"column":null}},"188":{"start":{"line":521,"column":6},"end":{"line":521,"column":null}},"189":{"start":{"line":522,"column":6},"end":{"line":522,"column":null}},"190":{"start":{"line":524,"column":20},"end":{"line":524,"column":null}},"191":{"start":{"line":525,"column":6},"end":{"line":525,"column":null}},"192":{"start":{"line":527,"column":12},"end":{"line":539,"column":null}},"193":{"start":{"line":528,"column":21},"end":{"line":528,"column":null}},"194":{"start":{"line":529,"column":8},"end":{"line":529,"column":null}},"195":{"start":{"line":530,"column":26},"end":{"line":530,"column":null}},"196":{"start":{"line":531,"column":8},"end":{"line":531,"column":null}},"197":{"start":{"line":532,"column":8},"end":{"line":532,"column":null}},"198":{"start":{"line":533,"column":26},"end":{"line":533,"column":null}},"199":{"start":{"line":534,"column":8},"end":{"line":534,"column":null}},"200":{"start":{"line":535,"column":8},"end":{"line":535,"column":null}},"201":{"start":{"line":536,"column":8},"end":{"line":536,"column":null}},"202":{"start":{"line":537,"column":8},"end":{"line":537,"column":null}},"203":{"start":{"line":538,"column":8},"end":{"line":538,"column":null}},"204":{"start":{"line":541,"column":6},"end":{"line":541,"column":null}},"205":{"start":{"line":542,"column":6},"end":{"line":542,"column":null}},"206":{"start":{"line":543,"column":6},"end":{"line":543,"column":null}},"207":{"start":{"line":545,"column":25},"end":{"line":545,"column":null}},"208":{"start":{"line":546,"column":6},"end":{"line":546,"column":null}},"209":{"start":{"line":547,"column":28},"end":{"line":547,"column":null}},"210":{"start":{"line":548,"column":6},"end":{"line":548,"column":null}},"211":{"start":{"line":549,"column":6},"end":{"line":549,"column":null}},"212":{"start":{"line":550,"column":18},"end":{"line":550,"column":null}},"213":{"start":{"line":551,"column":6},"end":{"line":551,"column":null}},"214":{"start":{"line":552,"column":6},"end":{"line":552,"column":null}},"215":{"start":{"line":553,"column":6},"end":{"line":553,"column":null}},"216":{"start":{"line":555,"column":6},"end":{"line":555,"column":null}},"217":{"start":{"line":556,"column":6},"end":{"line":556,"column":null}},"218":{"start":{"line":557,"column":6},"end":{"line":557,"column":null}},"219":{"start":{"line":558,"column":6},"end":{"line":558,"column":null}},"220":{"start":{"line":561,"column":4},"end":{"line":561,"column":null}},"221":{"start":{"line":566,"column":29},"end":{"line":566,"column":null}},"222":{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},"223":{"start":{"line":573,"column":6},"end":{"line":573,"column":null}},"224":{"start":{"line":574,"column":6},"end":{"line":574,"column":null}},"225":{"start":{"line":577,"column":22},"end":{"line":577,"column":null}},"226":{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},"227":{"start":{"line":579,"column":29},"end":{"line":579,"column":null}},"228":{"start":{"line":580,"column":23},"end":{"line":583,"column":null}},"229":{"start":{"line":581,"column":22},"end":{"line":581,"column":null}},"230":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"231":{"start":{"line":582,"column":8},"end":{"line":582,"column":null}},"232":{"start":{"line":584,"column":25},"end":{"line":587,"column":null}},"233":{"start":{"line":585,"column":22},"end":{"line":585,"column":null}},"234":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"235":{"start":{"line":586,"column":8},"end":{"line":586,"column":null}},"236":{"start":{"line":589,"column":6},"end":{"line":625,"column":null}},"237":{"start":{"line":628,"column":19},"end":{"line":628,"column":null}},"238":{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},"239":{"start":{"line":630,"column":29},"end":{"line":630,"column":null}},"240":{"start":{"line":631,"column":21},"end":{"line":633,"column":null}},"241":{"start":{"line":631,"column":73},"end":{"line":631,"column":90}},"242":{"start":{"line":633,"column":24},"end":{"line":633,"column":42}},"243":{"start":{"line":634,"column":21},"end":{"line":641,"column":null}},"244":{"start":{"line":643,"column":6},"end":{"line":672,"column":null}},"245":{"start":{"line":647,"column":46},"end":{"line":655,"column":12}},"246":{"start":{"line":648,"column":80},"end":{"line":648,"column":95}},"247":{"start":{"line":650,"column":28},"end":{"line":650,"column":null}},"248":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"249":{"start":{"line":651,"column":14},"end":{"line":651,"column":null}},"250":{"start":{"line":678,"column":33},"end":{"line":678,"column":null}},"251":{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},"252":{"start":{"line":685,"column":6},"end":{"line":685,"column":null}},"253":{"start":{"line":686,"column":6},"end":{"line":686,"column":null}},"254":{"start":{"line":689,"column":19},"end":{"line":689,"column":null}},"255":{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},"256":{"start":{"line":691,"column":24},"end":{"line":691,"column":null}},"257":{"start":{"line":692,"column":20},"end":{"line":692,"column":null}},"258":{"start":{"line":692,"column":72},"end":{"line":692,"column":78}},"259":{"start":{"line":693,"column":26},"end":{"line":693,"column":null}},"260":{"start":{"line":695,"column":6},"end":{"line":730,"column":null}},"261":{"start":{"line":700,"column":27},"end":{"line":700,"column":null}},"262":{"start":{"line":701,"column":12},"end":{"line":713,"column":null}},"263":{"start":{"line":704,"column":30},"end":{"line":704,"column":null}},"264":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"265":{"start":{"line":705,"column":16},"end":{"line":705,"column":null}},"266":{"start":{"line":736,"column":30},"end":{"line":736,"column":null}},"267":{"start":{"line":737,"column":22},"end":{"line":737,"column":null}},"268":{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},"269":{"start":{"line":739,"column":20},"end":{"line":739,"column":null}},"270":{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},"271":{"start":{"line":742,"column":6},"end":{"line":742,"column":null}},"272":{"start":{"line":743,"column":6},"end":{"line":743,"column":null}},"273":{"start":{"line":746,"column":4},"end":{"line":746,"column":null}},"274":{"start":{"line":747,"column":21},"end":{"line":747,"column":null}},"275":{"start":{"line":749,"column":71},"end":{"line":749,"column":null}},"276":{"start":{"line":750,"column":4},"end":{"line":754,"column":null}},"277":{"start":{"line":751,"column":21},"end":{"line":751,"column":null}},"278":{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},"279":{"start":{"line":752,"column":33},"end":{"line":752,"column":null}},"280":{"start":{"line":753,"column":6},"end":{"line":753,"column":null}},"281":{"start":{"line":756,"column":4},"end":{"line":786,"column":null}},"282":{"start":{"line":757,"column":26},"end":{"line":757,"column":44}},"283":{"start":{"line":759,"column":21},"end":{"line":759,"column":null}},"284":{"start":{"line":760,"column":8},"end":{"line":760,"column":null}},"285":{"start":{"line":762,"column":23},"end":{"line":762,"column":null}},"286":{"start":{"line":763,"column":8},"end":{"line":763,"column":null}},"287":{"start":{"line":764,"column":8},"end":{"line":764,"column":null}},"288":{"start":{"line":766,"column":22},"end":{"line":766,"column":null}},"289":{"start":{"line":767,"column":8},"end":{"line":767,"column":null}},"290":{"start":{"line":769,"column":8},"end":{"line":781,"column":null}},"291":{"start":{"line":770,"column":23},"end":{"line":770,"column":null}},"292":{"start":{"line":771,"column":10},"end":{"line":771,"column":null}},"293":{"start":{"line":772,"column":24},"end":{"line":772,"column":null}},"294":{"start":{"line":773,"column":10},"end":{"line":773,"column":null}},"295":{"start":{"line":774,"column":10},"end":{"line":774,"column":null}},"296":{"start":{"line":775,"column":24},"end":{"line":775,"column":null}},"297":{"start":{"line":776,"column":10},"end":{"line":776,"column":null}},"298":{"start":{"line":777,"column":10},"end":{"line":777,"column":null}},"299":{"start":{"line":778,"column":10},"end":{"line":778,"column":null}},"300":{"start":{"line":779,"column":10},"end":{"line":779,"column":null}},"301":{"start":{"line":780,"column":10},"end":{"line":780,"column":null}},"302":{"start":{"line":783,"column":8},"end":{"line":783,"column":null}},"303":{"start":{"line":784,"column":8},"end":{"line":784,"column":null}},"304":{"start":{"line":785,"column":8},"end":{"line":785,"column":null}},"305":{"start":{"line":788,"column":4},"end":{"line":788,"column":null}},"306":{"start":{"line":793,"column":4},"end":{"line":797,"column":null}},"307":{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},"308":{"start":{"line":795,"column":8},"end":{"line":795,"column":null}},"309":{"start":{"line":798,"column":4},"end":{"line":798,"column":null}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":78,"column":2},"end":{"line":78,"column":14}},"loc":{"start":{"line":78,"column":34},"end":{"line":81,"column":null}},"line":78},"1":{"name":"(anonymous_1)","decl":{"start":{"line":84,"column":2},"end":{"line":84,"column":27}},"loc":{"start":{"line":84,"column":27},"end":{"line":122,"column":null}},"line":84},"2":{"name":"(anonymous_2)","decl":{"start":{"line":125,"column":2},"end":{"line":125,"column":33}},"loc":{"start":{"line":125,"column":33},"end":{"line":266,"column":null}},"line":125},"3":{"name":"(anonymous_3)","decl":{"start":{"line":135,"column":48},"end":{"line":135,"column":null}},"loc":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"line":136},"4":{"name":"(anonymous_4)","decl":{"start":{"line":145,"column":36},"end":{"line":145,"column":40}},"loc":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"line":145},"5":{"name":"(anonymous_5)","decl":{"start":{"line":149,"column":38},"end":{"line":149,"column":42}},"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"line":150},"6":{"name":"(anonymous_6)","decl":{"start":{"line":200,"column":47},"end":{"line":200,"column":null}},"loc":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"line":202},"7":{"name":"(anonymous_7)","decl":{"start":{"line":214,"column":36},"end":{"line":214,"column":40}},"loc":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"line":214},"8":{"name":"(anonymous_8)","decl":{"start":{"line":218,"column":38},"end":{"line":218,"column":42}},"loc":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"line":219},"9":{"name":"(anonymous_9)","decl":{"start":{"line":232,"column":38},"end":{"line":232,"column":42}},"loc":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"line":233},"10":{"name":"(anonymous_10)","decl":{"start":{"line":269,"column":2},"end":{"line":269,"column":30}},"loc":{"start":{"line":269,"column":30},"end":{"line":336,"column":null}},"line":269},"11":{"name":"(anonymous_11)","decl":{"start":{"line":283,"column":19},"end":{"line":283,"column":28}},"loc":{"start":{"line":283,"column":46},"end":{"line":333,"column":5}},"line":283},"12":{"name":"(anonymous_12)","decl":{"start":{"line":339,"column":2},"end":{"line":339,"column":31}},"loc":{"start":{"line":339,"column":31},"end":{"line":390,"column":null}},"line":339},"13":{"name":"(anonymous_13)","decl":{"start":{"line":362,"column":41},"end":{"line":362,"column":46}},"loc":{"start":{"line":362,"column":76},"end":{"line":367,"column":10}},"line":362},"14":{"name":"(anonymous_14)","decl":{"start":{"line":393,"column":2},"end":{"line":393,"column":33}},"loc":{"start":{"line":393,"column":33},"end":{"line":499,"column":null}},"line":393},"15":{"name":"(anonymous_15)","decl":{"start":{"line":407,"column":26},"end":{"line":407,"column":35}},"loc":{"start":{"line":407,"column":65},"end":{"line":472,"column":5}},"line":407},"16":{"name":"(anonymous_16)","decl":{"start":{"line":418,"column":12},"end":{"line":418,"column":26}},"loc":{"start":{"line":418,"column":84},"end":{"line":433,"column":null}},"line":418},"17":{"name":"(anonymous_17)","decl":{"start":{"line":459,"column":28},"end":{"line":459,"column":37}},"loc":{"start":{"line":459,"column":55},"end":{"line":464,"column":9}},"line":459},"18":{"name":"(anonymous_18)","decl":{"start":{"line":502,"column":2},"end":{"line":502,"column":36}},"loc":{"start":{"line":502,"column":36},"end":{"line":562,"column":null}},"line":502},"19":{"name":"(anonymous_19)","decl":{"start":{"line":516,"column":24},"end":{"line":516,"column":32}},"loc":{"start":{"line":516,"column":37},"end":{"line":559,"column":5}},"line":516},"20":{"name":"(anonymous_20)","decl":{"start":{"line":527,"column":12},"end":{"line":527,"column":26}},"loc":{"start":{"line":527,"column":84},"end":{"line":539,"column":null}},"line":527},"21":{"name":"(anonymous_21)","decl":{"start":{"line":565,"column":2},"end":{"line":565,"column":29}},"loc":{"start":{"line":565,"column":29},"end":{"line":674,"column":null}},"line":565},"22":{"name":"(anonymous_22)","decl":{"start":{"line":580,"column":38},"end":{"line":580,"column":42}},"loc":{"start":{"line":580,"column":47},"end":{"line":583,"column":7}},"line":580},"23":{"name":"(anonymous_23)","decl":{"start":{"line":581,"column":49},"end":{"line":581,"column":54}},"loc":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"line":581},"24":{"name":"(anonymous_24)","decl":{"start":{"line":584,"column":40},"end":{"line":584,"column":44}},"loc":{"start":{"line":584,"column":49},"end":{"line":587,"column":7}},"line":584},"25":{"name":"(anonymous_25)","decl":{"start":{"line":585,"column":49},"end":{"line":585,"column":54}},"loc":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"line":585},"26":{"name":"(anonymous_26)","decl":{"start":{"line":631,"column":64},"end":{"line":631,"column":68}},"loc":{"start":{"line":631,"column":73},"end":{"line":631,"column":90}},"line":631},"27":{"name":"(anonymous_27)","decl":{"start":{"line":633,"column":9},"end":{"line":633,"column":15}},"loc":{"start":{"line":633,"column":24},"end":{"line":633,"column":42}},"line":633},"28":{"name":"(anonymous_28)","decl":{"start":{"line":647,"column":27},"end":{"line":647,"column":32}},"loc":{"start":{"line":647,"column":46},"end":{"line":655,"column":12}},"line":647},"29":{"name":"(anonymous_29)","decl":{"start":{"line":648,"column":66},"end":{"line":648,"column":75}},"loc":{"start":{"line":648,"column":80},"end":{"line":648,"column":95}},"line":648},"30":{"name":"(anonymous_30)","decl":{"start":{"line":649,"column":33},"end":{"line":649,"column":37}},"loc":{"start":{"line":649,"column":42},"end":{"line":652,"column":13}},"line":649},"31":{"name":"(anonymous_31)","decl":{"start":{"line":650,"column":59},"end":{"line":650,"column":64}},"loc":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"line":650},"32":{"name":"(anonymous_32)","decl":{"start":{"line":677,"column":2},"end":{"line":677,"column":33}},"loc":{"start":{"line":677,"column":33},"end":{"line":732,"column":null}},"line":677},"33":{"name":"(anonymous_33)","decl":{"start":{"line":692,"column":63},"end":{"line":692,"column":67}},"loc":{"start":{"line":692,"column":72},"end":{"line":692,"column":78}},"line":692},"34":{"name":"(anonymous_34)","decl":{"start":{"line":699,"column":30},"end":{"line":699,"column":35}},"loc":{"start":{"line":699,"column":47},"end":{"line":714,"column":11}},"line":699},"35":{"name":"(anonymous_35)","decl":{"start":{"line":703,"column":32},"end":{"line":703,"column":36}},"loc":{"start":{"line":703,"column":41},"end":{"line":706,"column":15}},"line":703},"36":{"name":"(anonymous_36)","decl":{"start":{"line":704,"column":61},"end":{"line":704,"column":66}},"loc":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"line":704},"37":{"name":"(anonymous_37)","decl":{"start":{"line":735,"column":2},"end":{"line":735,"column":30}},"loc":{"start":{"line":735,"column":30},"end":{"line":789,"column":null}},"line":735},"38":{"name":"(anonymous_38)","decl":{"start":{"line":750,"column":26},"end":{"line":750,"column":34}},"loc":{"start":{"line":750,"column":39},"end":{"line":754,"column":5}},"line":750},"39":{"name":"(anonymous_39)","decl":{"start":{"line":757,"column":7},"end":{"line":757,"column":13}},"loc":{"start":{"line":757,"column":26},"end":{"line":757,"column":44}},"line":757},"40":{"name":"(anonymous_40)","decl":{"start":{"line":758,"column":7},"end":{"line":758,"column":16}},"loc":{"start":{"line":758,"column":38},"end":{"line":786,"column":7}},"line":758},"41":{"name":"(anonymous_41)","decl":{"start":{"line":769,"column":16},"end":{"line":769,"column":24}},"loc":{"start":{"line":769,"column":29},"end":{"line":781,"column":9}},"line":769},"42":{"name":"(anonymous_42)","decl":{"start":{"line":792,"column":2},"end":{"line":792,"column":18}},"loc":{"start":{"line":792,"column":18},"end":{"line":799,"column":null}},"line":792},"43":{"name":"(anonymous_43)","decl":{"start":{"line":793,"column":31},"end":{"line":793,"column":39}},"loc":{"start":{"line":793,"column":48},"end":{"line":797,"column":5}},"line":793}},"branchMap":{"0":{"loc":{"start":{"line":85,"column":25},"end":{"line":85,"column":null}},"type":"binary-expr","locations":[{"start":{"line":85,"column":25},"end":{"line":85,"column":38}},{"start":{"line":85,"column":38},"end":{"line":85,"column":null}}],"line":85},"1":{"loc":{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},"type":"if","locations":[{"start":{"line":87,"column":4},"end":{"line":90,"column":null}},{"start":{},"end":{}}],"line":87},"2":{"loc":{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},"type":"if","locations":[{"start":{"line":93,"column":4},"end":{"line":95,"column":null}},{"start":{},"end":{}}],"line":93},"3":{"loc":{"start":{"line":93,"column":8},"end":{"line":93,"column":43}},"type":"binary-expr","locations":[{"start":{"line":93,"column":8},"end":{"line":93,"column":22}},{"start":{"line":93,"column":22},"end":{"line":93,"column":43}}],"line":93},"4":{"loc":{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},"type":"if","locations":[{"start":{"line":97,"column":4},"end":{"line":99,"column":null}},{"start":{},"end":{}}],"line":97},"5":{"loc":{"start":{"line":97,"column":8},"end":{"line":97,"column":47}},"type":"binary-expr","locations":[{"start":{"line":97,"column":8},"end":{"line":97,"column":26}},{"start":{"line":97,"column":26},"end":{"line":97,"column":47}}],"line":97},"6":{"loc":{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},"type":"if","locations":[{"start":{"line":101,"column":4},"end":{"line":103,"column":null}},{"start":{},"end":{}}],"line":101},"7":{"loc":{"start":{"line":101,"column":8},"end":{"line":101,"column":44}},"type":"binary-expr","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":23}},{"start":{"line":101,"column":23},"end":{"line":101,"column":44}}],"line":101},"8":{"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},"type":"if","locations":[{"start":{"line":105,"column":4},"end":{"line":107,"column":null}},{"start":{},"end":{}}],"line":105},"9":{"loc":{"start":{"line":105,"column":8},"end":{"line":105,"column":49}},"type":"binary-expr","locations":[{"start":{"line":105,"column":8},"end":{"line":105,"column":28}},{"start":{"line":105,"column":28},"end":{"line":105,"column":49}}],"line":105},"10":{"loc":{"start":{"line":109,"column":26},"end":{"line":109,"column":null}},"type":"binary-expr","locations":[{"start":{"line":109,"column":26},"end":{"line":109,"column":49}},{"start":{"line":109,"column":49},"end":{"line":109,"column":null}}],"line":109},"11":{"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":113,"column":null}},{"start":{},"end":{}}],"line":111},"12":{"loc":{"start":{"line":111,"column":8},"end":{"line":111,"column":42}},"type":"binary-expr","locations":[{"start":{"line":111,"column":8},"end":{"line":111,"column":27}},{"start":{"line":111,"column":27},"end":{"line":111,"column":42}}],"line":111},"13":{"loc":{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":4},"end":{"line":117,"column":null}},{"start":{},"end":{}}],"line":115},"14":{"loc":{"start":{"line":115,"column":8},"end":{"line":115,"column":39}},"type":"binary-expr","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":24}},{"start":{"line":115,"column":24},"end":{"line":115,"column":39}}],"line":115},"15":{"loc":{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":4},"end":{"line":121,"column":null}},{"start":{},"end":{}}],"line":119},"16":{"loc":{"start":{"line":119,"column":8},"end":{"line":119,"column":39}},"type":"binary-expr","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":24}},{"start":{"line":119,"column":24},"end":{"line":119,"column":39}}],"line":119},"17":{"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},"type":"if","locations":[{"start":{"line":128,"column":4},"end":{"line":131,"column":null}},{"start":{},"end":{}}],"line":128},"18":{"loc":{"start":{"line":128,"column":8},"end":{"line":128,"column":57}},"type":"binary-expr","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":22}},{"start":{"line":128,"column":22},"end":{"line":128,"column":57}}],"line":128},"19":{"loc":{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":196,"column":null}},{"start":{},"end":{}}],"line":134},"20":{"loc":{"start":{"line":134,"column":8},"end":{"line":134,"column":50}},"type":"binary-expr","locations":[{"start":{"line":134,"column":8},"end":{"line":134,"column":20}},{"start":{"line":134,"column":20},"end":{"line":134,"column":50}}],"line":134},"21":{"loc":{"start":{"line":136,"column":13},"end":{"line":136,"column":null}},"type":"binary-expr","locations":[{"start":{"line":136,"column":13},"end":{"line":136,"column":18}},{"start":{"line":136,"column":18},"end":{"line":136,"column":31}},{"start":{"line":136,"column":31},"end":{"line":136,"column":null}}],"line":136},"22":{"loc":{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},"type":"if","locations":[{"start":{"line":138,"column":6},"end":{"line":140,"column":null}},{"start":{},"end":{}}],"line":138},"23":{"loc":{"start":{"line":145,"column":45},"end":{"line":145,"column":69}},"type":"binary-expr","locations":[{"start":{"line":145,"column":45},"end":{"line":145,"column":60}},{"start":{"line":145,"column":60},"end":{"line":145,"column":69}}],"line":145},"24":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":null}},"type":"cond-expr","locations":[{"start":{"line":150,"column":72},"end":{"line":150,"column":90}},{"start":{"line":150,"column":90},"end":{"line":150,"column":null}}],"line":150},"25":{"loc":{"start":{"line":150,"column":16},"end":{"line":150,"column":72}},"type":"binary-expr","locations":[{"start":{"line":150,"column":16},"end":{"line":150,"column":21}},{"start":{"line":150,"column":21},"end":{"line":150,"column":34}},{"start":{"line":150,"column":34},"end":{"line":150,"column":72}}],"line":150},"26":{"loc":{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},"type":"if","locations":[{"start":{"line":199,"column":4},"end":{"line":265,"column":null}},{"start":{},"end":{}}],"line":199},"27":{"loc":{"start":{"line":199,"column":8},"end":{"line":199,"column":53}},"type":"binary-expr","locations":[{"start":{"line":199,"column":8},"end":{"line":199,"column":23}},{"start":{"line":199,"column":23},"end":{"line":199,"column":53}}],"line":199},"28":{"loc":{"start":{"line":202,"column":10},"end":{"line":205,"column":null}},"type":"binary-expr","locations":[{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},{"start":{"line":203,"column":10},"end":{"line":203,"column":null}},{"start":{"line":204,"column":10},"end":{"line":204,"column":null}},{"start":{"line":205,"column":10},"end":{"line":205,"column":null}}],"line":202},"29":{"loc":{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},"type":"if","locations":[{"start":{"line":207,"column":6},"end":{"line":209,"column":null}},{"start":{},"end":{}}],"line":207},"30":{"loc":{"start":{"line":214,"column":45},"end":{"line":214,"column":69}},"type":"binary-expr","locations":[{"start":{"line":214,"column":45},"end":{"line":214,"column":60}},{"start":{"line":214,"column":60},"end":{"line":214,"column":69}}],"line":214},"31":{"loc":{"start":{"line":219,"column":16},"end":{"line":221,"column":null}},"type":"cond-expr","locations":[{"start":{"line":220,"column":20},"end":{"line":220,"column":null}},{"start":{"line":221,"column":20},"end":{"line":221,"column":null}}],"line":219},"32":{"loc":{"start":{"line":219,"column":16},"end":{"line":219,"column":null}},"type":"binary-expr","locations":[{"start":{"line":219,"column":16},"end":{"line":219,"column":21}},{"start":{"line":219,"column":21},"end":{"line":219,"column":33}},{"start":{"line":219,"column":33},"end":{"line":219,"column":null}}],"line":219},"33":{"loc":{"start":{"line":233,"column":16},"end":{"line":235,"column":null}},"type":"cond-expr","locations":[{"start":{"line":234,"column":20},"end":{"line":234,"column":null}},{"start":{"line":235,"column":20},"end":{"line":235,"column":null}}],"line":233},"34":{"loc":{"start":{"line":233,"column":16},"end":{"line":233,"column":null}},"type":"binary-expr","locations":[{"start":{"line":233,"column":16},"end":{"line":233,"column":21}},{"start":{"line":233,"column":21},"end":{"line":233,"column":33}},{"start":{"line":233,"column":33},"end":{"line":233,"column":null}}],"line":233},"35":{"loc":{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},"type":"if","locations":[{"start":{"line":273,"column":4},"end":{"line":273,"column":null}},{"start":{},"end":{}}],"line":273},"36":{"loc":{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},"type":"if","locations":[{"start":{"line":275,"column":4},"end":{"line":278,"column":null}},{"start":{},"end":{}}],"line":275},"37":{"loc":{"start":{"line":275,"column":8},"end":{"line":275,"column":50}},"type":"binary-expr","locations":[{"start":{"line":275,"column":8},"end":{"line":275,"column":18}},{"start":{"line":275,"column":18},"end":{"line":275,"column":50}}],"line":275},"38":{"loc":{"start":{"line":316,"column":8},"end":{"line":318,"column":null}},"type":"cond-expr","locations":[{"start":{"line":317,"column":12},"end":{"line":317,"column":null}},{"start":{"line":318,"column":12},"end":{"line":318,"column":null}}],"line":316},"39":{"loc":{"start":{"line":316,"column":8},"end":{"line":316,"column":null}},"type":"binary-expr","locations":[{"start":{"line":316,"column":8},"end":{"line":316,"column":14}},{"start":{"line":316,"column":14},"end":{"line":316,"column":55}},{"start":{"line":316,"column":55},"end":{"line":316,"column":null}}],"line":316},"40":{"loc":{"start":{"line":319,"column":31},"end":{"line":319,"column":null}},"type":"cond-expr","locations":[{"start":{"line":319,"column":57},"end":{"line":319,"column":85}},{"start":{"line":319,"column":85},"end":{"line":319,"column":null}}],"line":319},"41":{"loc":{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},"type":"if","locations":[{"start":{"line":343,"column":4},"end":{"line":343,"column":null}},{"start":{},"end":{}}],"line":343},"42":{"loc":{"start":{"line":343,"column":8},"end":{"line":343,"column":46}},"type":"binary-expr","locations":[{"start":{"line":343,"column":8},"end":{"line":343,"column":16}},{"start":{"line":343,"column":16},"end":{"line":343,"column":46}}],"line":343},"43":{"loc":{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},"type":"if","locations":[{"start":{"line":345,"column":4},"end":{"line":354,"column":null}},{"start":{},"end":{}}],"line":345},"44":{"loc":{"start":{"line":346,"column":6},"end":{"line":350,"column":null}},"type":"binary-expr","locations":[{"start":{"line":346,"column":6},"end":{"line":346,"column":null}},{"start":{"line":347,"column":6},"end":{"line":347,"column":null}},{"start":{"line":348,"column":6},"end":{"line":348,"column":null}},{"start":{"line":349,"column":6},"end":{"line":349,"column":null}},{"start":{"line":350,"column":6},"end":{"line":350,"column":null}}],"line":346},"45":{"loc":{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},"type":"if","locations":[{"start":{"line":397,"column":4},"end":{"line":397,"column":null}},{"start":{},"end":{}}],"line":397},"46":{"loc":{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},"type":"if","locations":[{"start":{"line":399,"column":4},"end":{"line":402,"column":null}},{"start":{},"end":{}}],"line":399},"47":{"loc":{"start":{"line":399,"column":8},"end":{"line":399,"column":62}},"type":"binary-expr","locations":[{"start":{"line":399,"column":8},"end":{"line":399,"column":23}},{"start":{"line":399,"column":23},"end":{"line":399,"column":62}}],"line":399},"48":{"loc":{"start":{"line":436,"column":8},"end":{"line":436,"column":null}},"type":"cond-expr","locations":[{"start":{"line":436,"column":52},"end":{"line":436,"column":76}},{"start":{"line":436,"column":76},"end":{"line":436,"column":null}}],"line":436},"49":{"loc":{"start":{"line":438,"column":8},"end":{"line":440,"column":null}},"type":"cond-expr","locations":[{"start":{"line":439,"column":12},"end":{"line":439,"column":null}},{"start":{"line":440,"column":12},"end":{"line":440,"column":null}}],"line":438},"50":{"loc":{"start":{"line":438,"column":8},"end":{"line":438,"column":null}},"type":"binary-expr","locations":[{"start":{"line":438,"column":8},"end":{"line":438,"column":56}},{"start":{"line":438,"column":56},"end":{"line":438,"column":null}}],"line":438},"51":{"loc":{"start":{"line":442,"column":8},"end":{"line":442,"column":null}},"type":"cond-expr","locations":[{"start":{"line":442,"column":56},"end":{"line":442,"column":84}},{"start":{"line":442,"column":84},"end":{"line":442,"column":null}}],"line":442},"52":{"loc":{"start":{"line":444,"column":8},"end":{"line":444,"column":null}},"type":"cond-expr","locations":[{"start":{"line":444,"column":59},"end":{"line":444,"column":90}},{"start":{"line":444,"column":90},"end":{"line":444,"column":null}}],"line":444},"53":{"loc":{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},"type":"if","locations":[{"start":{"line":458,"column":6},"end":{"line":465,"column":null}},{"start":{},"end":{}}],"line":458},"54":{"loc":{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},"type":"if","locations":[{"start":{"line":477,"column":4},"end":{"line":498,"column":null}},{"start":{},"end":{}}],"line":477},"55":{"loc":{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},"type":"if","locations":[{"start":{"line":506,"column":4},"end":{"line":506,"column":null}},{"start":{},"end":{}}],"line":506},"56":{"loc":{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},"type":"if","locations":[{"start":{"line":508,"column":4},"end":{"line":511,"column":null}},{"start":{},"end":{}}],"line":508},"57":{"loc":{"start":{"line":508,"column":8},"end":{"line":508,"column":94}},"type":"binary-expr","locations":[{"start":{"line":508,"column":8},"end":{"line":508,"column":21}},{"start":{"line":508,"column":21},"end":{"line":508,"column":60}},{"start":{"line":508,"column":60},"end":{"line":508,"column":94}}],"line":508},"58":{"loc":{"start":{"line":552,"column":24},"end":{"line":552,"column":null}},"type":"binary-expr","locations":[{"start":{"line":552,"column":24},"end":{"line":552,"column":43}},{"start":{"line":552,"column":43},"end":{"line":552,"column":null}}],"line":552},"59":{"loc":{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},"type":"if","locations":[{"start":{"line":568,"column":4},"end":{"line":575,"column":null}},{"start":{},"end":{}}],"line":568},"60":{"loc":{"start":{"line":569,"column":6},"end":{"line":571,"column":null}},"type":"binary-expr","locations":[{"start":{"line":569,"column":6},"end":{"line":569,"column":null}},{"start":{"line":570,"column":6},"end":{"line":570,"column":null}},{"start":{"line":571,"column":6},"end":{"line":571,"column":null}}],"line":569},"61":{"loc":{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},"type":"if","locations":[{"start":{"line":578,"column":4},"end":{"line":626,"column":null}},{"start":{},"end":{}}],"line":578},"62":{"loc":{"start":{"line":578,"column":8},"end":{"line":578,"column":92}},"type":"binary-expr","locations":[{"start":{"line":578,"column":8},"end":{"line":578,"column":21}},{"start":{"line":578,"column":21},"end":{"line":578,"column":53}},{"start":{"line":578,"column":53},"end":{"line":578,"column":92}}],"line":578},"63":{"loc":{"start":{"line":581,"column":59},"end":{"line":581,"column":94}},"type":"binary-expr","locations":[{"start":{"line":581,"column":59},"end":{"line":581,"column":76}},{"start":{"line":581,"column":76},"end":{"line":581,"column":94}}],"line":581},"64":{"loc":{"start":{"line":582,"column":15},"end":{"line":582,"column":null}},"type":"cond-expr","locations":[{"start":{"line":582,"column":23},"end":{"line":582,"column":37}},{"start":{"line":582,"column":37},"end":{"line":582,"column":null}}],"line":582},"65":{"loc":{"start":{"line":585,"column":59},"end":{"line":585,"column":97}},"type":"binary-expr","locations":[{"start":{"line":585,"column":59},"end":{"line":585,"column":76}},{"start":{"line":585,"column":76},"end":{"line":585,"column":97}}],"line":585},"66":{"loc":{"start":{"line":586,"column":15},"end":{"line":586,"column":null}},"type":"cond-expr","locations":[{"start":{"line":586,"column":23},"end":{"line":586,"column":37}},{"start":{"line":586,"column":37},"end":{"line":586,"column":null}}],"line":586},"67":{"loc":{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},"type":"if","locations":[{"start":{"line":629,"column":4},"end":{"line":673,"column":null}},{"start":{},"end":{}}],"line":629},"68":{"loc":{"start":{"line":629,"column":8},"end":{"line":629,"column":93}},"type":"binary-expr","locations":[{"start":{"line":629,"column":8},"end":{"line":629,"column":18}},{"start":{"line":629,"column":18},"end":{"line":629,"column":50}},{"start":{"line":629,"column":50},"end":{"line":629,"column":93}}],"line":629},"69":{"loc":{"start":{"line":650,"column":69},"end":{"line":650,"column":113}},"type":"binary-expr","locations":[{"start":{"line":650,"column":69},"end":{"line":650,"column":86}},{"start":{"line":650,"column":86},"end":{"line":650,"column":113}}],"line":650},"70":{"loc":{"start":{"line":651,"column":21},"end":{"line":651,"column":null}},"type":"cond-expr","locations":[{"start":{"line":651,"column":29},"end":{"line":651,"column":53}},{"start":{"line":651,"column":53},"end":{"line":651,"column":null}}],"line":651},"71":{"loc":{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},"type":"if","locations":[{"start":{"line":680,"column":4},"end":{"line":687,"column":null}},{"start":{},"end":{}}],"line":680},"72":{"loc":{"start":{"line":681,"column":6},"end":{"line":683,"column":null}},"type":"binary-expr","locations":[{"start":{"line":681,"column":6},"end":{"line":681,"column":null}},{"start":{"line":682,"column":6},"end":{"line":682,"column":null}},{"start":{"line":683,"column":6},"end":{"line":683,"column":null}}],"line":681},"73":{"loc":{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},"type":"if","locations":[{"start":{"line":690,"column":4},"end":{"line":731,"column":null}},{"start":{},"end":{}}],"line":690},"74":{"loc":{"start":{"line":690,"column":8},"end":{"line":690,"column":93}},"type":"binary-expr","locations":[{"start":{"line":690,"column":8},"end":{"line":690,"column":18}},{"start":{"line":690,"column":18},"end":{"line":690,"column":50}},{"start":{"line":690,"column":50},"end":{"line":690,"column":93}}],"line":690},"75":{"loc":{"start":{"line":702,"column":21},"end":{"line":702,"column":null}},"type":"cond-expr","locations":[{"start":{"line":702,"column":38},"end":{"line":702,"column":50}},{"start":{"line":702,"column":50},"end":{"line":702,"column":null}}],"line":702},"76":{"loc":{"start":{"line":702,"column":50},"end":{"line":702,"column":null}},"type":"cond-expr","locations":[{"start":{"line":702,"column":67},"end":{"line":702,"column":89}},{"start":{"line":702,"column":89},"end":{"line":702,"column":null}}],"line":702},"77":{"loc":{"start":{"line":704,"column":71},"end":{"line":704,"column":110}},"type":"binary-expr","locations":[{"start":{"line":704,"column":71},"end":{"line":704,"column":87}},{"start":{"line":704,"column":87},"end":{"line":704,"column":110}}],"line":704},"78":{"loc":{"start":{"line":705,"column":23},"end":{"line":705,"column":null}},"type":"cond-expr","locations":[{"start":{"line":705,"column":31},"end":{"line":705,"column":48}},{"start":{"line":705,"column":48},"end":{"line":705,"column":null}}],"line":705},"79":{"loc":{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},"type":"if","locations":[{"start":{"line":739,"column":4},"end":{"line":739,"column":null}},{"start":{},"end":{}}],"line":739},"80":{"loc":{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},"type":"if","locations":[{"start":{"line":741,"column":4},"end":{"line":744,"column":null}},{"start":{},"end":{}}],"line":741},"81":{"loc":{"start":{"line":741,"column":8},"end":{"line":741,"column":103}},"type":"binary-expr","locations":[{"start":{"line":741,"column":8},"end":{"line":741,"column":26}},{"start":{"line":741,"column":26},"end":{"line":741,"column":67}},{"start":{"line":741,"column":67},"end":{"line":741,"column":103}}],"line":741},"82":{"loc":{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},"type":"if","locations":[{"start":{"line":752,"column":6},"end":{"line":752,"column":null}},{"start":{},"end":{}}],"line":752},"83":{"loc":{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},"type":"if","locations":[{"start":{"line":794,"column":6},"end":{"line":796,"column":null}},{"start":{},"end":{}}],"line":794},"84":{"loc":{"start":{"line":794,"column":10},"end":{"line":794,"column":56}},"type":"binary-expr","locations":[{"start":{"line":794,"column":10},"end":{"line":794,"column":19}},{"start":{"line":794,"column":19},"end":{"line":794,"column":56}}],"line":794}},"s":{"0":32,"1":32,"2":32,"3":32,"4":4,"5":4,"6":1,"7":1,"8":3,"9":3,"10":3,"11":3,"12":3,"13":2,"14":3,"15":3,"16":2,"17":3,"18":3,"19":2,"20":3,"21":4,"22":4,"23":2,"24":3,"25":3,"26":2,"27":3,"28":3,"29":2,"30":6,"31":6,"32":1,"33":1,"34":5,"35":5,"36":4,"37":25,"38":4,"39":1,"40":4,"41":32,"42":32,"43":5,"44":5,"45":4,"46":25,"47":4,"48":1,"49":4,"50":32,"51":32,"52":32,"53":5,"54":5,"55":5,"56":1,"57":4,"58":1,"59":1,"60":3,"61":3,"62":3,"63":9,"64":9,"65":9,"66":9,"67":9,"68":9,"69":9,"70":9,"71":9,"72":9,"73":9,"74":9,"75":9,"76":9,"77":9,"78":9,"79":9,"80":9,"81":9,"82":9,"83":9,"84":9,"85":9,"86":9,"87":9,"88":9,"89":9,"90":9,"91":9,"92":9,"93":9,"94":9,"95":9,"96":9,"97":3,"98":4,"99":4,"100":4,"101":1,"102":3,"103":1,"104":1,"105":2,"106":2,"107":6,"108":5,"109":5,"110":5,"111":1,"112":4,"113":1,"114":1,"115":3,"116":3,"117":3,"118":3,"119":3,"120":3,"121":3,"122":3,"123":3,"124":3,"125":3,"126":12,"127":12,"128":12,"129":12,"130":12,"131":12,"132":12,"133":12,"134":12,"135":12,"136":12,"137":3,"138":3,"139":3,"140":3,"141":3,"142":3,"143":3,"144":3,"145":3,"146":3,"147":3,"148":3,"149":3,"150":3,"151":3,"152":6,"153":6,"154":6,"155":6,"156":3,"157":3,"158":3,"159":3,"160":3,"161":3,"162":3,"163":2,"164":2,"165":2,"166":2,"167":2,"168":2,"169":2,"170":2,"171":2,"172":2,"173":2,"174":2,"175":4,"176":4,"177":4,"178":0,"179":4,"180":1,"181":1,"182":3,"183":3,"184":3,"185":3,"186":3,"187":3,"188":3,"189":3,"190":3,"191":3,"192":3,"193":9,"194":9,"195":9,"196":9,"197":9,"198":9,"199":9,"200":9,"201":9,"202":9,"203":9,"204":3,"205":3,"206":3,"207":3,"208":3,"209":3,"210":3,"211":3,"212":3,"213":3,"214":3,"215":3,"216":3,"217":3,"218":3,"219":3,"220":3,"221":4,"222":4,"223":1,"224":1,"225":3,"226":3,"227":2,"228":2,"229":16,"230":56,"231":16,"232":2,"233":16,"234":60,"235":16,"236":2,"237":3,"238":3,"239":2,"240":2,"241":6,"242":2,"243":2,"244":2,"245":4,"246":4,"247":32,"248":90,"249":32,"250":3,"251":3,"252":1,"253":1,"254":2,"255":2,"256":2,"257":2,"258":8,"259":2,"260":2,"261":6,"262":6,"263":12,"264":36,"265":12,"266":4,"267":4,"268":4,"269":1,"270":3,"271":1,"272":1,"273":2,"274":2,"275":2,"276":2,"277":6,"278":6,"279":4,"280":6,"281":2,"282":2,"283":4,"284":4,"285":4,"286":4,"287":4,"288":4,"289":4,"290":4,"291":6,"292":6,"293":6,"294":6,"295":6,"296":6,"297":6,"298":6,"299":6,"300":6,"301":6,"302":4,"303":4,"304":4,"305":2,"306":4,"307":8,"308":8,"309":4},"f":{"0":32,"1":4,"2":6,"3":25,"4":32,"5":32,"6":25,"7":32,"8":32,"9":32,"10":5,"11":9,"12":4,"13":6,"14":5,"15":3,"16":12,"17":6,"18":4,"19":3,"20":9,"21":4,"22":16,"23":56,"24":16,"25":60,"26":6,"27":2,"28":4,"29":4,"30":32,"31":90,"32":3,"33":8,"34":6,"35":12,"36":36,"37":4,"38":6,"39":2,"40":4,"41":6,"42":4,"43":8},"b":{"0":[4,0],"1":[1,3],"2":[3,0],"3":[3,3],"4":[2,1],"5":[3,2],"6":[2,1],"7":[3,2],"8":[2,1],"9":[3,2],"10":[3,2],"11":[2,2],"12":[4,3],"13":[2,1],"14":[3,2],"15":[2,1],"16":[3,2],"17":[1,5],"18":[6,5],"19":[4,1],"20":[5,5],"21":[25,25,25],"22":[1,3],"23":[32,1],"24":[31,1],"25":[32,32,32],"26":[4,1],"27":[5,5],"28":[25,25,25,24],"29":[1,3],"30":[32,1],"31":[31,1],"32":[32,32,32],"33":[31,1],"34":[32,32,32],"35":[1,4],"36":[1,3],"37":[4,3],"38":[8,1],"39":[9,9,9],"40":[8,1],"41":[1,3],"42":[4,3],"43":[1,2],"44":[3,3,2,2,2],"45":[1,4],"46":[1,3],"47":[4,3],"48":[2,1],"49":[2,1],"50":[3,3],"51":[3,0],"52":[3,0],"53":[3,0],"54":[2,1],"55":[0,4],"56":[1,3],"57":[4,4,4],"58":[3,1],"59":[1,3],"60":[4,3,3],"61":[2,1],"62":[3,2,2],"63":[56,4],"64":[4,12],"65":[60,8],"66":[4,12],"67":[2,1],"68":[3,2,2],"69":[90,10],"70":[6,26],"71":[1,2],"72":[3,2,2],"73":[2,0],"74":[2,2,2],"75":[2,4],"76":[2,2],"77":[36,18],"78":[8,4],"79":[1,3],"80":[1,2],"81":[3,3,3],"82":[4,2],"83":[8,0],"84":[8,8]},"meta":{"lastBranch":85,"lastFunction":44,"lastStatement":310,"seen":{"s:45:15:45:Infinity":0,"s:76:44:76:Infinity":1,"f:78:2:78:14":0,"s:79:4:79:Infinity":2,"s:80:4:80:Infinity":3,"f:84:2:84:27":1,"s:85:25:85:Infinity":4,"b:85:25:85:38:85:38:85:Infinity":0,"b:87:4:90:Infinity:undefined:undefined:undefined:undefined":1,"s:87:4:90:Infinity":5,"s:88:6:88:Infinity":6,"s:89:6:89:Infinity":7,"s:92:23:92:Infinity":8,"b:93:4:95:Infinity:undefined:undefined:undefined:undefined":2,"s:93:4:95:Infinity":9,"b:93:8:93:22:93:22:93:43":3,"s:94:6:94:Infinity":10,"s:96:27:96:Infinity":11,"b:97:4:99:Infinity:undefined:undefined:undefined:undefined":4,"s:97:4:99:Infinity":12,"b:97:8:97:26:97:26:97:47":5,"s:98:6:98:Infinity":13,"s:100:24:100:Infinity":14,"b:101:4:103:Infinity:undefined:undefined:undefined:undefined":6,"s:101:4:103:Infinity":15,"b:101:8:101:23:101:23:101:44":7,"s:102:6:102:Infinity":16,"s:104:29:104:Infinity":17,"b:105:4:107:Infinity:undefined:undefined:undefined:undefined":8,"s:105:4:107:Infinity":18,"b:105:8:105:28:105:28:105:49":9,"s:106:6:106:Infinity":19,"s:109:26:109:Infinity":20,"b:109:26:109:49:109:49:109:Infinity":10,"s:110:28:110:Infinity":21,"b:111:4:113:Infinity:undefined:undefined:undefined:undefined":11,"s:111:4:113:Infinity":22,"b:111:8:111:27:111:27:111:42":12,"s:112:6:112:Infinity":23,"s:114:25:114:Infinity":24,"b:115:4:117:Infinity:undefined:undefined:undefined:undefined":13,"s:115:4:117:Infinity":25,"b:115:8:115:24:115:24:115:39":14,"s:116:6:116:Infinity":26,"s:118:25:118:Infinity":27,"b:119:4:121:Infinity:undefined:undefined:undefined:undefined":15,"s:119:4:121:Infinity":28,"b:119:8:119:24:119:24:119:39":16,"s:120:6:120:Infinity":29,"f:125:2:125:33":2,"s:126:26:126:Infinity":30,"b:128:4:131:Infinity:undefined:undefined:undefined:undefined":17,"s:128:4:131:Infinity":31,"b:128:8:128:22:128:22:128:57":18,"s:129:6:129:Infinity":32,"s:130:6:130:Infinity":33,"s:133:21:133:Infinity":34,"b:134:4:196:Infinity:undefined:undefined:undefined:undefined":19,"s:134:4:196:Infinity":35,"b:134:8:134:20:134:20:134:50":20,"s:135:30:137:Infinity":36,"f:135:48:135:Infinity":3,"s:136:13:136:Infinity":37,"b:136:13:136:18:136:18:136:31:136:31:136:Infinity":21,"b:138:6:140:Infinity:undefined:undefined:undefined:undefined":22,"s:138:6:140:Infinity":38,"s:139:8:139:Infinity":39,"s:142:6:195:Infinity":40,"f:145:36:145:40":4,"s:145:45:145:69":41,"b:145:45:145:60:145:60:145:69":23,"f:149:38:149:42":5,"s:150:16:150:Infinity":42,"b:150:72:150:90:150:90:150:Infinity":24,"b:150:16:150:21:150:21:150:34:150:34:150:72":25,"s:198:24:198:Infinity":43,"b:199:4:265:Infinity:undefined:undefined:undefined:undefined":26,"s:199:4:265:Infinity":44,"b:199:8:199:23:199:23:199:53":27,"s:200:29:206:Infinity":45,"f:200:47:200:Infinity":6,"s:202:10:205:Infinity":46,"b:202:10:202:Infinity:203:10:203:Infinity:204:10:204:Infinity:205:10:205:Infinity":28,"b:207:6:209:Infinity:undefined:undefined:undefined:undefined":29,"s:207:6:209:Infinity":47,"s:208:8:208:Infinity":48,"s:211:6:264:Infinity":49,"f:214:36:214:40":7,"s:214:45:214:69":50,"b:214:45:214:60:214:60:214:69":30,"f:218:38:218:42":8,"s:219:16:221:Infinity":51,"b:220:20:220:Infinity:221:20:221:Infinity":31,"b:219:16:219:21:219:21:219:33:219:33:219:Infinity":32,"f:232:38:232:42":9,"s:233:16:235:Infinity":52,"b:234:20:234:Infinity:235:20:235:Infinity":33,"b:233:16:233:21:233:21:233:33:233:33:233:Infinity":34,"f:269:2:269:30":10,"s:270:22:270:Infinity":53,"s:271:22:271:Infinity":54,"b:273:4:273:Infinity:undefined:undefined:undefined:undefined":35,"s:273:4:273:Infinity":55,"s:273:20:273:Infinity":56,"b:275:4:278:Infinity:undefined:undefined:undefined:undefined":36,"s:275:4:278:Infinity":57,"b:275:8:275:18:275:18:275:50":37,"s:276:6:276:Infinity":58,"s:277:6:277:Infinity":59,"s:280:4:280:Infinity":60,"s:281:21:281:Infinity":61,"s:283:4:333:Infinity":62,"f:283:19:283:28":11,"s:284:19:284:Infinity":63,"s:285:6:285:Infinity":64,"s:287:21:287:Infinity":65,"s:288:6:288:Infinity":66,"s:289:6:289:Infinity":67,"s:291:19:291:Infinity":68,"s:292:6:292:Infinity":69,"s:294:19:294:Infinity":70,"s:295:6:295:Infinity":71,"s:296:6:296:Infinity":72,"s:298:20:298:Infinity":73,"s:299:6:299:Infinity":74,"s:300:6:300:Infinity":75,"s:302:19:302:Infinity":76,"s:303:6:303:Infinity":77,"s:304:6:304:Infinity":78,"s:306:6:306:Infinity":79,"s:307:6:307:Infinity":80,"s:308:6:308:Infinity":81,"s:310:20:310:Infinity":82,"s:311:6:311:Infinity":83,"s:313:25:313:Infinity":84,"s:314:6:314:Infinity":85,"s:316:8:318:Infinity":86,"b:317:12:317:Infinity:318:12:318:Infinity":38,"b:316:8:316:14:316:14:316:55:316:55:316:Infinity":39,"s:319:6:319:Infinity":87,"b:319:57:319:85:319:85:319:Infinity":40,"s:321:25:321:Infinity":88,"s:322:6:322:Infinity":89,"s:323:6:323:Infinity":90,"s:325:6:325:Infinity":91,"s:326:6:326:Infinity":92,"s:328:6:328:Infinity":93,"s:329:6:329:Infinity":94,"s:330:6:330:Infinity":95,"s:332:6:332:Infinity":96,"s:335:4:335:Infinity":97,"f:339:2:339:31":12,"s:340:31:340:Infinity":98,"s:341:16:341:Infinity":99,"b:343:4:343:Infinity:undefined:undefined:undefined:undefined":41,"s:343:4:343:Infinity":100,"b:343:8:343:16:343:16:343:46":42,"s:343:46:343:Infinity":101,"b:345:4:354:Infinity:undefined:undefined:undefined:undefined":43,"s:345:4:354:Infinity":102,"b:346:6:346:Infinity:347:6:347:Infinity:348:6:348:Infinity:349:6:349:Infinity:350:6:350:Infinity":44,"s:352:6:352:Infinity":103,"s:353:6:353:Infinity":104,"s:356:19:356:Infinity":105,"s:358:4:389:Infinity":106,"f:362:41:362:46":13,"s:362:76:367:10":107,"f:393:2:393:33":14,"s:394:27:394:Infinity":108,"s:395:22:395:Infinity":109,"b:397:4:397:Infinity:undefined:undefined:undefined:undefined":45,"s:397:4:397:Infinity":110,"s:397:20:397:Infinity":111,"b:399:4:402:Infinity:undefined:undefined:undefined:undefined":46,"s:399:4:402:Infinity":112,"b:399:8:399:23:399:23:399:62":47,"s:400:6:400:Infinity":113,"s:401:6:401:Infinity":114,"s:404:4:404:Infinity":115,"s:405:21:405:Infinity":116,"s:407:4:472:Infinity":117,"f:407:26:407:35":15,"s:408:19:408:Infinity":118,"s:409:6:409:Infinity":119,"s:411:21:411:Infinity":120,"s:412:6:412:Infinity":121,"s:413:6:413:Infinity":122,"s:415:20:415:Infinity":123,"s:416:6:416:Infinity":124,"s:418:12:433:Infinity":125,"f:418:12:418:26":16,"s:419:21:419:Infinity":126,"s:420:8:420:Infinity":127,"s:422:26:422:Infinity":128,"s:423:8:423:Infinity":129,"s:424:8:424:Infinity":130,"s:426:26:426:Infinity":131,"s:427:8:427:Infinity":132,"s:428:8:428:Infinity":133,"s:430:8:430:Infinity":134,"s:431:8:431:Infinity":135,"s:432:8:432:Infinity":136,"s:436:8:436:Infinity":137,"b:436:52:436:76:436:76:436:Infinity":48,"s:438:8:440:Infinity":138,"b:439:12:439:Infinity:440:12:440:Infinity":49,"b:438:8:438:56:438:56:438:Infinity":50,"s:442:8:442:Infinity":139,"b:442:56:442:84:442:84:442:Infinity":51,"s:444:8:444:Infinity":140,"b:444:59:444:90:444:90:444:Infinity":52,"s:446:6:446:Infinity":141,"s:447:6:447:Infinity":142,"s:448:6:448:Infinity":143,"s:449:6:449:Infinity":144,"s:451:21:451:Infinity":145,"s:452:6:452:Infinity":146,"s:454:28:454:Infinity":147,"s:455:6:455:Infinity":148,"s:456:6:456:Infinity":149,"b:458:6:465:Infinity:undefined:undefined:undefined:undefined":53,"s:458:6:465:Infinity":150,"s:459:8:464:Infinity":151,"f:459:28:459:37":17,"s:460:22:460:Infinity":152,"s:461:10:461:Infinity":153,"s:462:10:462:Infinity":154,"s:463:10:463:Infinity":155,"s:467:6:467:Infinity":156,"s:468:6:468:Infinity":157,"s:469:6:469:Infinity":158,"s:471:6:471:Infinity":159,"s:474:4:474:Infinity":160,"s:476:23:476:Infinity":161,"b:477:4:498:Infinity:undefined:undefined:undefined:undefined":54,"s:477:4:498:Infinity":162,"s:478:6:478:Infinity":163,"s:480:21:480:Infinity":164,"s:482:17:482:Infinity":165,"s:483:21:483:Infinity":166,"s:484:6:484:Infinity":167,"s:485:6:485:Infinity":168,"s:486:6:490:Infinity":169,"s:492:17:492:Infinity":170,"s:493:6:493:Infinity":171,"s:495:6:495:Infinity":172,"s:496:6:496:Infinity":173,"s:497:6:497:Infinity":174,"f:502:2:502:36":18,"s:503:25:503:Infinity":175,"s:504:22:504:Infinity":176,"b:506:4:506:Infinity:undefined:undefined:undefined:undefined":55,"s:506:4:506:Infinity":177,"s:506:20:506:Infinity":178,"b:508:4:511:Infinity:undefined:undefined:undefined:undefined":56,"s:508:4:511:Infinity":179,"b:508:8:508:21:508:21:508:60:508:60:508:94":57,"s:509:6:509:Infinity":180,"s:510:6:510:Infinity":181,"s:513:4:513:Infinity":182,"s:514:21:514:Infinity":183,"s:516:4:559:Infinity":184,"f:516:24:516:32":19,"s:517:19:517:Infinity":185,"s:518:6:518:Infinity":186,"s:520:21:520:Infinity":187,"s:521:6:521:Infinity":188,"s:522:6:522:Infinity":189,"s:524:20:524:Infinity":190,"s:525:6:525:Infinity":191,"s:527:12:539:Infinity":192,"f:527:12:527:26":20,"s:528:21:528:Infinity":193,"s:529:8:529:Infinity":194,"s:530:26:530:Infinity":195,"s:531:8:531:Infinity":196,"s:532:8:532:Infinity":197,"s:533:26:533:Infinity":198,"s:534:8:534:Infinity":199,"s:535:8:535:Infinity":200,"s:536:8:536:Infinity":201,"s:537:8:537:Infinity":202,"s:538:8:538:Infinity":203,"s:541:6:541:Infinity":204,"s:542:6:542:Infinity":205,"s:543:6:543:Infinity":206,"s:545:25:545:Infinity":207,"s:546:6:546:Infinity":208,"s:547:28:547:Infinity":209,"s:548:6:548:Infinity":210,"s:549:6:549:Infinity":211,"s:550:18:550:Infinity":212,"s:551:6:551:Infinity":213,"s:552:6:552:Infinity":214,"b:552:24:552:43:552:43:552:Infinity":58,"s:553:6:553:Infinity":215,"s:555:6:555:Infinity":216,"s:556:6:556:Infinity":217,"s:557:6:557:Infinity":218,"s:558:6:558:Infinity":219,"s:561:4:561:Infinity":220,"f:565:2:565:29":21,"s:566:29:566:Infinity":221,"b:568:4:575:Infinity:undefined:undefined:undefined:undefined":59,"s:568:4:575:Infinity":222,"b:569:6:569:Infinity:570:6:570:Infinity:571:6:571:Infinity":60,"s:573:6:573:Infinity":223,"s:574:6:574:Infinity":224,"s:577:22:577:Infinity":225,"b:578:4:626:Infinity:undefined:undefined:undefined:undefined":61,"s:578:4:626:Infinity":226,"b:578:8:578:21:578:21:578:53:578:53:578:92":62,"s:579:29:579:Infinity":227,"s:580:23:583:Infinity":228,"f:580:38:580:42":22,"s:581:22:581:Infinity":229,"f:581:49:581:54":23,"s:581:59:581:94":230,"b:581:59:581:76:581:76:581:94":63,"s:582:8:582:Infinity":231,"b:582:23:582:37:582:37:582:Infinity":64,"s:584:25:587:Infinity":232,"f:584:40:584:44":24,"s:585:22:585:Infinity":233,"f:585:49:585:54":25,"s:585:59:585:97":234,"b:585:59:585:76:585:76:585:97":65,"s:586:8:586:Infinity":235,"b:586:23:586:37:586:37:586:Infinity":66,"s:589:6:625:Infinity":236,"s:628:19:628:Infinity":237,"b:629:4:673:Infinity:undefined:undefined:undefined:undefined":67,"s:629:4:673:Infinity":238,"b:629:8:629:18:629:18:629:50:629:50:629:93":68,"s:630:29:630:Infinity":239,"s:631:21:633:Infinity":240,"f:631:64:631:68":26,"s:631:73:631:90":241,"f:633:9:633:15":27,"s:633:24:633:42":242,"s:634:21:641:Infinity":243,"s:643:6:672:Infinity":244,"f:647:27:647:32":28,"s:647:46:655:12":245,"f:648:66:648:75":29,"s:648:80:648:95":246,"f:649:33:649:37":30,"s:650:28:650:Infinity":247,"f:650:59:650:64":31,"s:650:69:650:113":248,"b:650:69:650:86:650:86:650:113":69,"s:651:14:651:Infinity":249,"b:651:29:651:53:651:53:651:Infinity":70,"f:677:2:677:33":32,"s:678:33:678:Infinity":250,"b:680:4:687:Infinity:undefined:undefined:undefined:undefined":71,"s:680:4:687:Infinity":251,"b:681:6:681:Infinity:682:6:682:Infinity:683:6:683:Infinity":72,"s:685:6:685:Infinity":252,"s:686:6:686:Infinity":253,"s:689:19:689:Infinity":254,"b:690:4:731:Infinity:undefined:undefined:undefined:undefined":73,"s:690:4:731:Infinity":255,"b:690:8:690:18:690:18:690:50:690:50:690:93":74,"s:691:24:691:Infinity":256,"s:692:20:692:Infinity":257,"f:692:63:692:67":33,"s:692:72:692:78":258,"s:693:26:693:Infinity":259,"s:695:6:730:Infinity":260,"f:699:30:699:35":34,"s:700:27:700:Infinity":261,"s:701:12:713:Infinity":262,"b:702:38:702:50:702:50:702:Infinity":75,"b:702:67:702:89:702:89:702:Infinity":76,"f:703:32:703:36":35,"s:704:30:704:Infinity":263,"f:704:61:704:66":36,"s:704:71:704:110":264,"b:704:71:704:87:704:87:704:110":77,"s:705:16:705:Infinity":265,"b:705:31:705:48:705:48:705:Infinity":78,"f:735:2:735:30":37,"s:736:30:736:Infinity":266,"s:737:22:737:Infinity":267,"b:739:4:739:Infinity:undefined:undefined:undefined:undefined":79,"s:739:4:739:Infinity":268,"s:739:20:739:Infinity":269,"b:741:4:744:Infinity:undefined:undefined:undefined:undefined":80,"s:741:4:744:Infinity":270,"b:741:8:741:26:741:26:741:67:741:67:741:103":81,"s:742:6:742:Infinity":271,"s:743:6:743:Infinity":272,"s:746:4:746:Infinity":273,"s:747:21:747:Infinity":274,"s:749:71:749:Infinity":275,"s:750:4:754:Infinity":276,"f:750:26:750:34":38,"s:751:21:751:Infinity":277,"b:752:6:752:Infinity:undefined:undefined:undefined:undefined":82,"s:752:6:752:Infinity":278,"s:752:33:752:Infinity":279,"s:753:6:753:Infinity":280,"s:756:4:786:Infinity":281,"f:757:7:757:13":39,"s:757:26:757:44":282,"f:758:7:758:16":40,"s:759:21:759:Infinity":283,"s:760:8:760:Infinity":284,"s:762:23:762:Infinity":285,"s:763:8:763:Infinity":286,"s:764:8:764:Infinity":287,"s:766:22:766:Infinity":288,"s:767:8:767:Infinity":289,"s:769:8:781:Infinity":290,"f:769:16:769:24":41,"s:770:23:770:Infinity":291,"s:771:10:771:Infinity":292,"s:772:24:772:Infinity":293,"s:773:10:773:Infinity":294,"s:774:10:774:Infinity":295,"s:775:24:775:Infinity":296,"s:776:10:776:Infinity":297,"s:777:10:777:Infinity":298,"s:778:10:778:Infinity":299,"s:779:10:779:Infinity":300,"s:780:10:780:Infinity":301,"s:783:8:783:Infinity":302,"s:784:8:784:Infinity":303,"s:785:8:785:Infinity":304,"s:788:4:788:Infinity":305,"f:792:2:792:18":42,"s:793:4:797:Infinity":306,"f:793:31:793:39":43,"b:794:6:796:Infinity:undefined:undefined:undefined:undefined":83,"s:794:6:796:Infinity":307,"b:794:10:794:19:794:19:794:56":84,"s:795:8:795:Infinity":308,"s:798:4:798:Infinity":309}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/sources.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/cia/sources.ts","statementMap":{"0":{"start":{"line":21,"column":50},"end":{"line":23,"column":null}},"1":{"start":{"line":26,"column":69},"end":{"line":45,"column":null}},"2":{"start":{"line":51,"column":51},"end":{"line":51,"column":null}},"3":{"start":{"line":60,"column":38},"end":{"line":165,"column":null}},"4":{"start":{"line":168,"column":51},"end":{"line":172,"column":null}},"5":{"start":{"line":170,"column":58},"end":{"line":170,"column":92}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":170,"column":36},"end":{"line":170,"column":41}},"loc":{"start":{"line":170,"column":58},"end":{"line":170,"column":92}},"line":170}},"branchMap":{},"s":{"0":5,"1":5,"2":5,"3":5,"4":5,"5":130},"f":{"0":130},"b":{},"meta":{"lastBranch":0,"lastFunction":1,"lastStatement":6,"seen":{"s:21:50:23:Infinity":0,"s:26:69:45:Infinity":1,"s:51:51:51:Infinity":2,"s:60:38:165:Infinity":3,"s:168:51:172:Infinity":4,"f:170:36:170:41":0,"s:170:58:170:92":5}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/error-boundary.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/error-boundary.ts","statementMap":{"0":{"start":{"line":53,"column":23},"end":{"line":53,"column":null}},"1":{"start":{"line":54,"column":17},"end":{"line":54,"column":null}},"2":{"start":{"line":55,"column":23},"end":{"line":55,"column":null}},"3":{"start":{"line":57,"column":18},"end":{"line":106,"column":null}},"4":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"5":{"start":{"line":59,"column":6},"end":{"line":59,"column":null}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":null}},"7":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":null}},"9":{"start":{"line":67,"column":4},"end":{"line":67,"column":null}},"10":{"start":{"line":69,"column":27},"end":{"line":69,"column":null}},"11":{"start":{"line":70,"column":4},"end":{"line":70,"column":null}},"12":{"start":{"line":71,"column":4},"end":{"line":71,"column":null}},"13":{"start":{"line":72,"column":4},"end":{"line":72,"column":null}},"14":{"start":{"line":74,"column":32},"end":{"line":74,"column":null}},"15":{"start":{"line":75,"column":28},"end":{"line":75,"column":null}},"16":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"17":{"start":{"line":77,"column":6},"end":{"line":77,"column":null}},"18":{"start":{"line":80,"column":4},"end":{"line":80,"column":null}},"19":{"start":{"line":81,"column":4},"end":{"line":81,"column":null}},"20":{"start":{"line":82,"column":4},"end":{"line":82,"column":null}},"21":{"start":{"line":83,"column":4},"end":{"line":83,"column":null}},"22":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"23":{"start":{"line":85,"column":4},"end":{"line":85,"column":null}},"24":{"start":{"line":86,"column":4},"end":{"line":86,"column":null}},"25":{"start":{"line":87,"column":4},"end":{"line":87,"column":null}},"26":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"27":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"28":{"start":{"line":91,"column":4},"end":{"line":91,"column":null}},"29":{"start":{"line":92,"column":4},"end":{"line":92,"column":null}},"30":{"start":{"line":94,"column":4},"end":{"line":105,"column":null}},"31":{"start":{"line":95,"column":6},"end":{"line":95,"column":null}},"32":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"33":{"start":{"line":98,"column":6},"end":{"line":98,"column":null}},"34":{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},"35":{"start":{"line":101,"column":8},"end":{"line":101,"column":null}},"36":{"start":{"line":103,"column":6},"end":{"line":103,"column":null}},"37":{"start":{"line":104,"column":6},"end":{"line":104,"column":null}},"38":{"start":{"line":108,"column":2},"end":{"line":108,"column":null}}},"fnMap":{"0":{"name":"renderWithFallback","decl":{"start":{"line":47,"column":22},"end":{"line":47,"column":null}},"loc":{"start":{"line":52,"column":17},"end":{"line":109,"column":null}},"line":52},"1":{"name":"(anonymous_1)","decl":{"start":{"line":57,"column":18},"end":{"line":57,"column":45}},"loc":{"start":{"line":57,"column":45},"end":{"line":106,"column":null}},"line":57}},"branchMap":{"0":{"loc":{"start":{"line":50,"column":2},"end":{"line":50,"column":null}},"type":"default-arg","locations":[{"start":{"line":50,"column":20},"end":{"line":50,"column":null}}],"line":50},"1":{"loc":{"start":{"line":51,"column":2},"end":{"line":51,"column":null}},"type":"default-arg","locations":[{"start":{"line":51,"column":39},"end":{"line":51,"column":null}}],"line":51},"2":{"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":60,"column":null}},{"start":{},"end":{}}],"line":58},"3":{"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":66,"column":null}},{"start":{},"end":{}}],"line":64},"4":{"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":78,"column":null}},{"start":{},"end":{}}],"line":76},"5":{"loc":{"start":{"line":76,"column":8},"end":{"line":76,"column":64}},"type":"binary-expr","locations":[{"start":{"line":76,"column":8},"end":{"line":76,"column":34}},{"start":{"line":76,"column":34},"end":{"line":76,"column":64}}],"line":76},"6":{"loc":{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":6},"end":{"line":102,"column":null}},{"start":{},"end":{}}],"line":100}},"s":{"0":14,"1":14,"2":14,"3":14,"4":18,"5":1,"6":17,"7":17,"8":3,"9":17,"10":17,"11":17,"12":17,"13":17,"14":17,"15":17,"16":17,"17":17,"18":17,"19":17,"20":17,"21":17,"22":17,"23":17,"24":17,"25":17,"26":17,"27":17,"28":17,"29":17,"30":17,"31":17,"32":9,"33":9,"34":17,"35":4,"36":17,"37":17,"38":14},"f":{"0":14,"1":18},"b":{"0":[14],"1":[14],"2":[1,17],"3":[3,14],"4":[17,0],"5":[17,0],"6":[4,13]},"meta":{"lastBranch":7,"lastFunction":2,"lastStatement":39,"seen":{"f:47:22:47:Infinity":0,"b:50:20:50:Infinity":0,"b:51:39:51:Infinity":1,"s:53:23:53:Infinity":0,"s:54:17:54:Infinity":1,"s:55:23:55:Infinity":2,"s:57:18:106:Infinity":3,"f:57:18:57:45":1,"b:58:4:60:Infinity:undefined:undefined:undefined:undefined":2,"s:58:4:60:Infinity":4,"s:59:6:59:Infinity":5,"s:62:4:62:Infinity":6,"b:64:4:66:Infinity:undefined:undefined:undefined:undefined":3,"s:64:4:66:Infinity":7,"s:65:6:65:Infinity":8,"s:67:4:67:Infinity":9,"s:69:27:69:Infinity":10,"s:70:4:70:Infinity":11,"s:71:4:71:Infinity":12,"s:72:4:72:Infinity":13,"s:74:32:74:Infinity":14,"s:75:28:75:Infinity":15,"b:76:4:78:Infinity:undefined:undefined:undefined:undefined":4,"s:76:4:78:Infinity":16,"b:76:8:76:34:76:34:76:64":5,"s:77:6:77:Infinity":17,"s:80:4:80:Infinity":18,"s:81:4:81:Infinity":19,"s:82:4:82:Infinity":20,"s:83:4:83:Infinity":21,"s:84:4:84:Infinity":22,"s:85:4:85:Infinity":23,"s:86:4:86:Infinity":24,"s:87:4:87:Infinity":25,"s:88:4:88:Infinity":26,"s:89:4:89:Infinity":27,"s:91:4:91:Infinity":28,"s:92:4:92:Infinity":29,"s:94:4:105:Infinity":30,"s:95:6:95:Infinity":31,"s:97:6:97:Infinity":32,"s:98:6:98:Infinity":33,"b:100:6:102:Infinity:undefined:undefined:undefined:undefined":6,"s:100:6:102:Infinity":34,"s:101:8:101:Infinity":35,"s:103:6:103:Infinity":36,"s:104:6:104:Infinity":37,"s:108:2:108:Infinity":38}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/fallback-ui.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/fallback-ui.ts","statementMap":{"0":{"start":{"line":29,"column":2},"end":{"line":29,"column":null}},"1":{"start":{"line":31,"column":15},"end":{"line":31,"column":null}},"2":{"start":{"line":32,"column":2},"end":{"line":32,"column":null}},"3":{"start":{"line":33,"column":2},"end":{"line":33,"column":null}},"4":{"start":{"line":34,"column":2},"end":{"line":34,"column":null}},"5":{"start":{"line":36,"column":15},"end":{"line":36,"column":null}},"6":{"start":{"line":37,"column":2},"end":{"line":37,"column":null}},"7":{"start":{"line":38,"column":2},"end":{"line":38,"column":null}},"8":{"start":{"line":39,"column":2},"end":{"line":39,"column":null}},"9":{"start":{"line":41,"column":15},"end":{"line":41,"column":null}},"10":{"start":{"line":42,"column":2},"end":{"line":42,"column":null}},"11":{"start":{"line":43,"column":2},"end":{"line":43,"column":null}},"12":{"start":{"line":45,"column":2},"end":{"line":45,"column":null}},"13":{"start":{"line":46,"column":2},"end":{"line":46,"column":null}},"14":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"15":{"start":{"line":49,"column":16},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"21":{"start":{"line":57,"column":2},"end":{"line":57,"column":null}},"22":{"start":{"line":65,"column":2},"end":{"line":65,"column":null}},"23":{"start":{"line":67,"column":18},"end":{"line":67,"column":null}},"24":{"start":{"line":68,"column":2},"end":{"line":68,"column":null}},"25":{"start":{"line":69,"column":2},"end":{"line":69,"column":null}},"26":{"start":{"line":70,"column":2},"end":{"line":70,"column":null}},"27":{"start":{"line":71,"column":2},"end":{"line":71,"column":null}},"28":{"start":{"line":73,"column":2},"end":{"line":77,"column":null}},"29":{"start":{"line":73,"column":15},"end":{"line":73,"column":18}},"30":{"start":{"line":74,"column":16},"end":{"line":74,"column":null}},"31":{"start":{"line":75,"column":4},"end":{"line":75,"column":null}},"32":{"start":{"line":76,"column":4},"end":{"line":76,"column":null}},"33":{"start":{"line":79,"column":2},"end":{"line":79,"column":null}}},"fnMap":{"0":{"name":"renderErrorFallback","decl":{"start":{"line":23,"column":16},"end":{"line":23,"column":null}},"loc":{"start":{"line":28,"column":8},"end":{"line":58,"column":null}},"line":28},"1":{"name":"renderLoadingFallback","decl":{"start":{"line":64,"column":16},"end":{"line":64,"column":38}},"loc":{"start":{"line":64,"column":95},"end":{"line":80,"column":null}},"line":64}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":2},"end":{"line":25,"column":null}},"type":"default-arg","locations":[{"start":{"line":25,"column":12},"end":{"line":25,"column":null}}],"line":25},"1":{"loc":{"start":{"line":27,"column":2},"end":{"line":27,"column":null}},"type":"default-arg","locations":[{"start":{"line":27,"column":15},"end":{"line":27,"column":null}}],"line":27},"2":{"loc":{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},"type":"if","locations":[{"start":{"line":48,"column":2},"end":{"line":55,"column":null}},{"start":{},"end":{}}],"line":48},"3":{"loc":{"start":{"line":64,"column":62},"end":{"line":64,"column":95}},"type":"default-arg","locations":[{"start":{"line":64,"column":77},"end":{"line":64,"column":95}}],"line":64}},"s":{"0":19,"1":19,"2":19,"3":19,"4":19,"5":19,"6":19,"7":19,"8":19,"9":19,"10":19,"11":19,"12":19,"13":19,"14":19,"15":13,"16":13,"17":13,"18":13,"19":13,"20":13,"21":19,"22":23,"23":23,"24":23,"25":23,"26":23,"27":23,"28":23,"29":23,"30":69,"31":69,"32":69,"33":23},"f":{"0":19,"1":23},"b":{"0":[19],"1":[19],"2":[13,6],"3":[23]},"meta":{"lastBranch":4,"lastFunction":2,"lastStatement":34,"seen":{"f:23:16:23:Infinity":0,"b:25:12:25:Infinity":0,"b:27:15:27:Infinity":1,"s:29:2:29:Infinity":0,"s:31:15:31:Infinity":1,"s:32:2:32:Infinity":2,"s:33:2:33:Infinity":3,"s:34:2:34:Infinity":4,"s:36:15:36:Infinity":5,"s:37:2:37:Infinity":6,"s:38:2:38:Infinity":7,"s:39:2:39:Infinity":8,"s:41:15:41:Infinity":9,"s:42:2:42:Infinity":10,"s:43:2:43:Infinity":11,"s:45:2:45:Infinity":12,"s:46:2:46:Infinity":13,"b:48:2:55:Infinity:undefined:undefined:undefined:undefined":2,"s:48:2:55:Infinity":14,"s:49:16:49:Infinity":15,"s:50:4:50:Infinity":16,"s:51:4:51:Infinity":17,"s:52:4:52:Infinity":18,"s:53:4:53:Infinity":19,"s:54:4:54:Infinity":20,"s:57:2:57:Infinity":21,"f:64:16:64:38":1,"b:64:77:64:95":3,"s:65:2:65:Infinity":22,"s:67:18:67:Infinity":23,"s:68:2:68:Infinity":24,"s:69:2:69:Infinity":25,"s:70:2:70:Infinity":26,"s:71:2:71:Infinity":27,"s:73:2:77:Infinity":28,"s:73:15:73:18":29,"s:74:16:74:Infinity":30,"s:75:4:75:Infinity":31,"s:76:4:76:Infinity":32,"s:79:2:79:Infinity":33}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/global-libs.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/global-libs.ts","statementMap":{"0":{"start":{"line":49,"column":23},"end":{"line":49,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":4},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:49:23:49:Infinity":0}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/safe-storage.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/safe-storage.ts","statementMap":{"0":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"1":{"start":{"line":23,"column":36},"end":{"line":23,"column":null}},"2":{"start":{"line":24,"column":2},"end":{"line":28,"column":null}},"3":{"start":{"line":50,"column":2},"end":{"line":58,"column":null}},"4":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"5":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"6":{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},"7":{"start":{"line":55,"column":6},"end":{"line":55,"column":null}},"8":{"start":{"line":56,"column":6},"end":{"line":56,"column":null}},"9":{"start":{"line":60,"column":59},"end":{"line":60,"column":null}},"10":{"start":{"line":61,"column":2},"end":{"line":79,"column":null}},"11":{"start":{"line":62,"column":4},"end":{"line":76,"column":null}},"12":{"start":{"line":62,"column":17},"end":{"line":62,"column":20}},"13":{"start":{"line":63,"column":16},"end":{"line":63,"column":null}},"14":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"15":{"start":{"line":64,"column":60},"end":{"line":64,"column":null}},"16":{"start":{"line":65,"column":15},"end":{"line":65,"column":null}},"17":{"start":{"line":66,"column":6},"end":{"line":74,"column":null}},"18":{"start":{"line":67,"column":20},"end":{"line":67,"column":null}},"19":{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},"20":{"start":{"line":69,"column":25},"end":{"line":69,"column":null}},"21":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"22":{"start":{"line":70,"column":52},"end":{"line":70,"column":null}},"23":{"start":{"line":75,"column":6},"end":{"line":75,"column":null}},"24":{"start":{"line":78,"column":4},"end":{"line":78,"column":null}},"25":{"start":{"line":81,"column":2},"end":{"line":81,"column":null}},"26":{"start":{"line":81,"column":28},"end":{"line":81,"column":53}},"27":{"start":{"line":82,"column":22},"end":{"line":82,"column":null}},"28":{"start":{"line":83,"column":2},"end":{"line":85,"column":null}},"29":{"start":{"line":84,"column":4},"end":{"line":84,"column":null}},"30":{"start":{"line":84,"column":10},"end":{"line":84,"column":46}},"31":{"start":{"line":87,"column":2},"end":{"line":96,"column":null}},"32":{"start":{"line":88,"column":4},"end":{"line":88,"column":null}},"33":{"start":{"line":89,"column":4},"end":{"line":89,"column":null}},"34":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"35":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"36":{"start":{"line":94,"column":4},"end":{"line":94,"column":null}},"37":{"start":{"line":95,"column":4},"end":{"line":95,"column":null}}},"fnMap":{"0":{"name":"isQuotaError","decl":{"start":{"line":22,"column":9},"end":{"line":22,"column":22}},"loc":{"start":{"line":22,"column":43},"end":{"line":30,"column":null}},"line":22},"1":{"name":"safeSetItem","decl":{"start":{"line":45,"column":16},"end":{"line":45,"column":null}},"loc":{"start":{"line":49,"column":11},"end":{"line":97,"column":null}},"line":49},"2":{"name":"(anonymous_2)","decl":{"start":{"line":81,"column":13},"end":{"line":81,"column":19}},"loc":{"start":{"line":81,"column":28},"end":{"line":81,"column":53}},"line":81}},"branchMap":{"0":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":23,"column":null}},{"start":{},"end":{}}],"line":23},"1":{"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":null}},"type":"binary-expr","locations":[{"start":{"line":25,"column":4},"end":{"line":25,"column":null}},{"start":{"line":26,"column":4},"end":{"line":26,"column":null}},{"start":{"line":27,"column":4},"end":{"line":27,"column":null}},{"start":{"line":28,"column":4},"end":{"line":28,"column":null}}],"line":25},"2":{"loc":{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":57,"column":null}},{"start":{},"end":{}}],"line":54},"3":{"loc":{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},"type":"if","locations":[{"start":{"line":64,"column":6},"end":{"line":64,"column":null}},{"start":{},"end":{}}],"line":64},"4":{"loc":{"start":{"line":64,"column":10},"end":{"line":64,"column":60}},"type":"binary-expr","locations":[{"start":{"line":64,"column":10},"end":{"line":64,"column":16}},{"start":{"line":64,"column":16},"end":{"line":64,"column":49}},{"start":{"line":64,"column":49},"end":{"line":64,"column":60}}],"line":64},"5":{"loc":{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":71,"column":null}},{"start":{},"end":{}}],"line":68},"6":{"loc":{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},"type":"if","locations":[{"start":{"line":70,"column":10},"end":{"line":70,"column":null}},{"start":{},"end":{}}],"line":70},"7":{"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":4},"end":{"line":93,"column":null}},{"start":{},"end":{}}],"line":91}},"s":{"0":6,"1":0,"2":6,"3":6,"4":6,"5":6,"6":5,"7":2,"8":2,"9":3,"10":3,"11":3,"12":3,"13":9,"14":9,"15":3,"16":6,"17":6,"18":6,"19":6,"20":6,"21":6,"22":6,"23":6,"24":0,"25":3,"26":3,"27":3,"28":3,"29":4,"30":4,"31":3,"32":3,"33":3,"34":1,"35":1,"36":0,"37":0},"f":{"0":6,"1":6,"2":3},"b":{"0":[0,6],"1":[6,2,2,2],"2":[2,3],"3":[3,6],"4":[9,9,6],"5":[6,0],"6":[6,0],"7":[1,0]},"meta":{"lastBranch":8,"lastFunction":3,"lastStatement":38,"seen":{"f:22:9:22:22":0,"b:23:2:23:Infinity:undefined:undefined:undefined:undefined":0,"s:23:2:23:Infinity":0,"s:23:36:23:Infinity":1,"s:24:2:28:Infinity":2,"b:25:4:25:Infinity:26:4:26:Infinity:27:4:27:Infinity:28:4:28:Infinity":1,"f:45:16:45:Infinity":1,"s:50:2:58:Infinity":3,"s:51:4:51:Infinity":4,"s:52:4:52:Infinity":5,"b:54:4:57:Infinity:undefined:undefined:undefined:undefined":2,"s:54:4:57:Infinity":6,"s:55:6:55:Infinity":7,"s:56:6:56:Infinity":8,"s:60:59:60:Infinity":9,"s:61:2:79:Infinity":10,"s:62:4:76:Infinity":11,"s:62:17:62:20":12,"s:63:16:63:Infinity":13,"b:64:6:64:Infinity:undefined:undefined:undefined:undefined":3,"s:64:6:64:Infinity":14,"b:64:10:64:16:64:16:64:49:64:49:64:60":4,"s:64:60:64:Infinity":15,"s:65:15:65:Infinity":16,"s:66:6:74:Infinity":17,"s:67:20:67:Infinity":18,"b:68:8:71:Infinity:undefined:undefined:undefined:undefined":5,"s:68:8:71:Infinity":19,"s:69:25:69:Infinity":20,"b:70:10:70:Infinity:undefined:undefined:undefined:undefined":6,"s:70:10:70:Infinity":21,"s:70:52:70:Infinity":22,"s:75:6:75:Infinity":23,"s:78:4:78:Infinity":24,"s:81:2:81:Infinity":25,"f:81:13:81:19":2,"s:81:28:81:53":26,"s:82:22:82:Infinity":27,"s:83:2:85:Infinity":28,"s:84:4:84:Infinity":29,"s:84:10:84:46":30,"s:87:2:96:Infinity":31,"s:88:4:88:Infinity":32,"s:89:4:89:Infinity":33,"b:91:4:93:Infinity:undefined:undefined:undefined:undefined":7,"s:91:4:93:Infinity":34,"s:92:6:92:Infinity":35,"s:94:4:94:Infinity":36,"s:95:4:95:Infinity":37}}},"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/register-globals-bootstrap.ts":{"path":"/home/runner/work/riksdagsmonitor/riksdagsmonitor/src/browser/shared/register-globals-bootstrap.ts","statementMap":{"0":{"start":{"line":29,"column":0},"end":{"line":29,"column":null}}},"fnMap":{},"branchMap":{},"s":{"0":0},"f":{},"b":{},"meta":{"lastBranch":0,"lastFunction":0,"lastStatement":1,"seen":{"s:29:0:29:Infinity":0}}}}} \ No newline at end of file diff --git a/tests/news-workflow-pass2-budget-contract.test.ts b/tests/news-workflow-pass2-budget-contract.test.ts index 11f5ab4a99c..61b44241d03 100644 --- a/tests/news-workflow-pass2-budget-contract.test.ts +++ b/tests/news-workflow-pass2-budget-contract.test.ts @@ -14,21 +14,21 @@ describe('agentic news workflow pass-2 and budget contracts', () => { expect(src).toContain("cron: '30 15 * * 1-5'"); }); - it('content-generating news workflows use the claude-opus-4.8 reasoning model', () => { + it('content-generating news workflows use the claude-opus-5 reasoning model', () => { const election = read('.github/workflows/news-election-cycle.md'); const yearAhead = read('.github/workflows/news-year-ahead.md'); - expect(election).toContain('model: claude-opus-4.8'); - expect(yearAhead).toContain('model: claude-opus-4.8'); + expect(election).toContain('model: claude-opus-5'); + expect(yearAhead).toContain('model: claude-opus-5'); expect(election).not.toContain('model: claude-sonnet-4.6'); expect(yearAhead).not.toContain('model: claude-sonnet-4.6'); }); it('the translation workflow stays on the claude-sonnet-4.6 throughput model', () => { // Translations are high-volume, low-reasoning fan-out work; only the - // analysis/article-generating workflows use the claude-opus-4.8 model. + // analysis/article-generating workflows use the claude-opus-5 model. const translate = read('.github/workflows/news-translate.md'); expect(translate).toContain('model: claude-sonnet-4.6'); - expect(translate).not.toContain('model: claude-opus-4.8'); + expect(translate).not.toContain('model: claude-opus-5'); }); it('analysis gate requires explicit full pass-2 declaration and canonical rerun schema fields', () => {